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.
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
Sodin ransomware exploits Windows vulnerability and processor architecture