RansomExx: The malware that attacks Linux OS
RansomExx is the new malware used by criminals to attack both Windows and Linux environments. With companies using a mixed environment of Windows and Linux servers, criminals felt the need to expand their ransomware operations to Linux systems as these systems are becoming an important piece inside enterprise networks. This article delivers specific details on RansomExx and how this piece of malware works, and provides some lines of how to prevent ransomware attacks in general.
According to a publication from Kaspersky, it’s been shown that the Exx ransomware (also known as Defrat777) has now been updated by criminals to damage Linux servers. RansomExx has being spotlighted due to in-the-wild attacks against the Brazilian government networks and previous attacks against the Texas Department of Transportation (TxDOT), Konica Minolta, IPG Photonics and Tyler Technologies.
This ransomware is a 64-bit ELF binary compiled with the GCC. As presented in the PortEx graph below, no obfuscation techniques and packed sections were detected during the malware static analysis.
Figure 1: RansomExx — PortEx graphic (no packed sessions detected).
A curious finding observed during the malware analysis is that the malware has hardcoded some debug strings and files used by ransomware operators during its development.
Figure 2: Debug information found during the malware static analysis.
Digging into the ransomware details
This ransomware (written in C) is composed of several core functions, including:
|main()||Entry point function of the ransomware.|
|GeneratePreData()||Used to generate cryptographic keys via mbedtls library.|
|EnumFiles()||Get the full path of the files that will be damaged.|
|list_dir()||Used to list all the target machine directories.|
|encrypt_worker()||The function that creates a single thread by file during the encryption process. It executes the functions: CryptOneFile() and CryptOneBlock().|
|CryptOneFile()||Access the target file to damage and prepares the encryption process.|
|CryptOneBlock()||Encrypts the file by blocks.|
|ReadMeStoreForDir()||Creates the ransom note in each accessed folder.|
As observed in the pseudo-code below, this call is responsible for calling the function GeneratePreData() that generates a 256-bit key and uses it to encrypt all the files belonging to the victim that it can reach using the AES block cipher in ECB mode.
The AES key is encrypted by a public RSA-4096 key embedded in the ransomware body and appended to each encrypted file. The path to encrypt is passed via the argv array inside a while() flow. Next, the function EnumFiles(), is used to list the files inside the folder and starts the encryption process.
Figure 3: RansomEx workflow diagram and pseudo-code — main() function.
This function uses the open-source lib mbedtls responsible for generating the AES encryption key that will be used to encrypt the target files. It gets the current system timestamp to generate random seeds (line 31 and 32 in Figure 4), and finally, the call mbedtls_ctr_drbg_random (line 44) to create a 256-bits AES cryptographic key.
Figure 4: Pseudo-code of GeneratePreData() function — RansomExx.
An important piece to highlight is the pthread_mutex_lock e pthread_mutex_unlock function, a mutex used by ransomware to control the encryption flow.
As previously mentioned, each damaged file has stored inside it a single AES-256 key that is initially encrypted through the use of a hardcoded 4086 RSA public key. The result is a ciphertext (the AES key), then stored inside the damaged file. Only criminals can recover the symmetric decrypted AES key by decrypting it with the private RSA key.
Figure 5: RSA key hardcoded inside the malware.
EnumFiles(), list_dir() and encrypt_worker() functions
EnumFiles() function is responsible for creating several threads that invoke the encrypt_worker() — Figure 7 line 19 — a call that will encrypt the target files. That function is called inside the routine init_workers() — see line 9 in Figure 6.
Figure 6: RansomExx EnumFiles() pseudo-code function.
Figure 7: RansomExx – init_workers() pseudo-code.
In detail, EnumFiles() function also invokes the call list_dir() — Figure 6, line 14 — that will execute the “ReadMeStoreForDir()” routine to drop the ransomware note “!NEWS_FOR_EIGSI!.txt” inside each folder.
Figure 8: RansomExx — list_dir() pseudo-code and the ransomware note drop flow.
This function is called inside the list_dir() call (Figure 8, line 14) and uses another popular function called fwrite() to create and populate (write) the ransomware note in each accessed folder during the encryption process.
Figure 9: RansomExx — ransomware dropped using fwrite call.
CryptOneFile() and CryptOneBlock() functions
Finally, these functions are called and are responsible to perform the data encryption flow.
The first one is invoked — in Figure 7, line 19 — inside the init_workers() function as mentioned above.
Figure 10: Part of the encrypt_work_function() call where the function responsible for encrypting the target files is invoked — CryptOneFile() — line 33.
In detail, the AES key is generated by other concurrent thread that is accessed as described in GeneratePreData() function using the calls mbedtls_aes_init and mbedtls_aes_setkey_enc.
Next, the target file is encrypted by blocks through the execution of the CryptOneBlock functions via the AES-ECB cipher mode.
The extension of the encrypted files is replaced by “.31gs1” in the analyzed sample — the file extension hardcoded inside the ransomware.
Figure 11: File extension used by RansomExx.
Executing the malware in a test environment, it’s possible to observe that empty files are not opened and renamed (in fact, they are junk) and everything else is damaged. During the process, the ransom note is dropped inside the target folders.
Figure 12: Execution of the RansomExx ransomware in a Linux machine.
Similarities with Windows builds of RansomEXX
Comparing the Windows and Linux versions of this ransomware, it is also possible to find obvious similarities in the code despite the changes made by the compilers during the process of building the malicious binaries.
Figure 13: Code similarities between Windows and Linux builds.
Some organizations have been impacted around the world by this recent threat. One of the last organizations was the Superior Court of Justice (aka STJ) of Brazil:
“A Domain Admin account was exploited which allowed the hacker to have access to our servers, to enter into administration groups of the virtual environment and, finally, encrypt a good part of our virtual machines,” as one of the IT technicians told O Bastidor.
Figure 14: Ransomware note of the STJ attack.
According to the ransomware authors, if the victim pays the ransom, he will receive a Linux and Windows executable with the corresponding RSA-4096 private key to recover the damaged files.
Criminals compromise victims’ networks and exfiltrate confidential documents while moving laterally in the infrastructure. Due to the wipe of Linux users in the last years, those systems token an important role inside corporate networks. In this way, the development of malware for attacking Unix-based machines is seen by criminals as an adaptative need.
In a later stage, when the Domain Controller is compromised, criminals spread the ransomware throughout the infrastructure to end the infection chain and deploy the RansomExx Windows and Linux builds to encrypt all devices registered in the Active Directory and other valuable assets available on the network.
Monitoring the use of endpoint security solutions, updated antivirus and the increasing use of canary files are some mechanisms that could prevent the dissemination of these kinds of threats through an entirely corporative network.