Sodin ransomware exploits Windows vulnerability and processor architecture

When Sodin (also known as Sodinokibi and REvil) appeared in the first half of 2019, it immediately caught our attention for distributing itself through an Oracle Weblogic vulnerability and carrying out attacks on MSP providers. In a detailed analysis, we discovered that it also exploits the CVE-2018-8453 vulnerability to elevate privileges in Windows (rare among ransomware), and uses legitimate processor functions to circumvent security solutions.

According to our statistics, most victims were located in the Asia-Pacific region: Taiwan, Hong Kong, and South Korea.

Geographic spread of Sodin ransomware, April – June 2019

Technical description

Vulnerability exploitation

To escalate privileges, Trojan-Ransom.Win32.Sodin uses a vulnerability in win32k.sys; attempts to exploit it were first detected by our proactive technologies (Automatic Exploit Prevention, AEP) in August last year. The vulnerability was assigned the number CVE-2018-8453. After the exploit is executed, the Trojan acquires the highest level of privileges.

Information about the process token after exploit execution

Exploit snippet for checking the window class

Depending on the processor architecture, one of two shellcode options contained in the Trojan body is run:

Procedure for selecting the appropriate shellcode option

Since the binary being analyzed is a 32-bit executable file, we are interested in how it manages to execute 64-bit code in its address space. The screenshot shows a shellcode snippet for executing 64-bit processor instructions:

Shellcode consisting of 32-bit and 64-bit instructions

In a 64-bit OS, the segment selector for 32-bit user mode code is 0x23, while the 64-bit segment selector is 0x33. This is confirmed by looking at the Global Descriptor Table (GDT) in the kernel debugger:

Part of the GDT in OS Windows 10 x64

The selector 0x23 points to the fourth segment descriptor (0x23 >> 3), and the selector 0x33 to the sixth (the null descriptor is not used). The Nl flag indicates that the segment uses 32-bit addressing, while the Lo flag specifies 64-bit. It is important that the base addresses of these segments are equal. At the time of shellcode execution, the selector 0x23 is located in the segment register cs, since the code is executed in a 32-bit address space. With this in mind, let’s take a look at the listing of the very start of the shellcode:

Saving the full address 0x23:0xC

After executing the command for RVA addresses 6 and 7, the long return address is stored at the top of the stack in the format selector:offset, and takes the form 0x23:0x0C. In the stack at offset 0x11, a DWORD is placed whose low-order word contains the selector 0x33 and whose high-order word encodes the instruction retf, the opcode of which is equal to 0xCB.

Saving the full address 0x33:0x1B to 64-bit code

Switching to 64-bit mode

The next instruction call (at the address RVA 0x16) performs a near intrasegment jump to this retf instruction (RVA 0x14), having sent the short return address (offset 0x1b) to the stack. As such, at the time of execution of the retf instruction, the top of the stack contains the address in the format selector:offset, where the selector equals 0x33 and the offset is 0x1b. After executing the retf command, the processor proceeds to execute the code at this address, but now in 64-bit mode.

64-bit shellcode

The return to 32-bit mode is performed at the very end of the shellcode.

Returning to 32-bit mode

The retf command makes a far intrasegment jump to the address 0x23:0x0C (it was placed in the instruction stack at the very start of the shellcode, at the RVA address 6-7). This technique of executing 64-bit code in a 32-bit process address space is called Heaven’s Gate, and was first described around ten years ago.

Trojan configuration

Stored in encrypted form in the body of each Sodin sample is a configuration block containing the settings and data required for the Trojan to work.

Decrypted Trojan configuration block

The Sodin configuration has the following fields:

Field Purpose
pk distributor public key
pid probably distributor id
sub probably campaign id
dbg debug build
fast fast encryption mode (maximum 0x100000 bytes)
wipe deletion of certain files and overwriting of their content with random bytes
wfld names of directories in which the Trojan deletes files
wht names of directories and files, and list of extensions not to be encrypted
prc names of processes to be terminated
dmn server addresses for sending statistics
net sending infection statistics
nbody ransom note template
nname ransom note file name template
exp use of exploit for privilege escalation
img text for desktop wallpaper

Cryptographic scheme

Sodin uses a hybrid scheme to encrypt victim files. The file contents are encrypted with the Salsa20 symmetric stream algorithm, and the keys for it with an elliptic curve asymmetric algorithm. Let’s take a closer look at the scheme.

Since some data is stored in the registry, this article uses the names given by the ransomware itself. For entities not in the registry, we use invented names.

Data saved by the Trojan in the registry

Key generation

The Sodin configuration block contains the pk field, which is saved in the registry under the name sub_key – this is the 32-byte public key of the Trojan distributor. The key is a point on the Curve25519 elliptic curve.

When launched, the Trojan generates a new pair of elliptic curve session keys; the public key of this pair is saved in the registry under the name pk_key, while the private key is encrypted using the ECIES algorithm with the sub_key key and stored in the registry under the name sk_key. The ECIES implementation in this case includes the Curve25519 elliptic curve, the SHA3-256 cryptographic hash, and the AES-256 block cipher in CFB mode. Other ECIES implementations have been encountered in Trojans before, for example, in SynAck targeted ransomware.

Curiously, the same private session key is also encrypted with another public key hardcoded into the body of the Trojan, regardless of the configuration. We will call it the public skeleton key. The encryption result is stored in the registry under the name 0_key. It turns out that someone who knows the private key corresponding to the public skeleton key is able to decrypt the victim’s files, even without the private key for sub_key. It seems like the Trojan developers built a loophole into the algorithm allowing them to decrypt files behind the distributors’ back.

Snippet of the procedure that generates key data and stores some of it in the registry

File encryption

During encryption of each file, a new pair of elliptic curve asymmetric keys is generated, which we will call file_pub and file_priv. Next, SHA3-256(ECDH(file_priv, pk_key)) is calculated, and the result is used as the symmetric key for encrypting file contents with the Salsa20 algorithm. The following information is also saved in the encrypted file:

Data stored in each encrypted file

In addition to the fields discussed above, there is also a nonce (random initialization 8 bytes for the Salsa20 cipher), file_pub_crc32 (checksum for file_pub), flag_fast (if set, only part of the data in the file is encrypted), zero_encr_by_salsa (null dword encrypted by the same Salsa20 key as the file contents – seemingly to check the correctness of the decryption).

The encrypted files receive a new arbitrary extension (the same for each infection case), the ransom note is saved next to them, and the malware-generated wallpaper is set on the desktop.

Cybercriminals demands

Fragment of the desktop wallpaper created by the ransomware

Network communication

If the corresponding flag is set in the configuration block, the Trojan sends information about the infected machine to its servers. The transmitted data is also encrypted with the ECIES algorithm using yet another hardcoded public key.

Part of the Sodin configuration responsible for network communication

Field Purpose
ver Trojan version
pid probably distributor id
sub probably campaign id
pk distributor public key
uid infection id
sk sk_key value (see description above)
unm infected system username
net machine name
grp machine domain/workgroup
lng system language
bro whether language or layout is from the list (below)
os OS version
bit architecture
dsk information about system drives
ext extension of encrypted files

During the execution process, the Trojan checks the system language and available keyboard layouts:

If matches are detected in the list, the malware process terminates short of sending statistics.

MITRE ATT&CK techniques

 

More information about Kaspersky cybersecurity services can be found here: https://www.kaspersky.com/enterprise-security/cybersecurity-services

 

IOC

1ce1ca85bff4517a1ef7e8f9a7c22b16

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *