BOOK THIS SPACE FOR AD
ARTICLE ADThis malware analysis was originally posted in my soon to be closed Japanese blog in 2015 and to avoid the research info disappearing I re-posted it as an English translation over here.
During AVTOKYO-2015 at "Swimming in the Sea of ELF" Workshop (thanks to attendees & tessy). During the workshop a new Linux ransomware has been distributed in the internet, as I explained in the workshop why we sometimes need to reverse binaries in UNIX shell, I used that samples as a demonstration on how to do analysis and sharing the know-how to the audience and then posted my finding in the kernelmode also.
I analyzed this case by just only using one tool of old radare2 version (thanks to pancake), radare2 which is always explained in most of my workshops is useful for that. If you would, I made many screenshots during analysis so you can practice radare2 (in secure environment) to reverse this old malware threat using my analysis notes as comparison.
Table of contents
(1)Background of the infection
(2)What kind of source code was used?
(3)How does it work to encrypt?
(4)Reversing the decryption function
(5)Why did they use PolarSSL code?
(6)Pivoted from OpenSSL
(7)Conclusion
《 1. Background of the infection 》
The infected sites showed errors similar to this one↓(the site had a wordpress file upload plugins vulnerability)
The search keyword is "README_FOR_DECRYPT.txt" and the result came up when you dork it.
If you check the "README_FOR_DECRYPT.txt" contents from an infected site, it looked like this:
(※Click to enlarge)
《 2. What kind of source code was used? 》
The intrusion investigation has concluded that the site had been suffered an infection of ransomware aiming Linux servers called 「Linux/Encoder.1」 a ransomware ELF binary file from the exploited vulnerability. It has two version: x86-64 and x86-32 of binaries that has been used by the adversaries in their C2 during the campaign.
Back in 2015 when Linux Ransomware is not so many, it was so excited to check it out. But, to be very honest, I was really disappointed when I reversed it because the content was too simple, and I wondered if it was made by an amateur programmer.
This is the list of the source code set to build the above binaries↓
↑As you can see, it's all written in C, and system-calls related to C file to be used in functions used throughout the malware are all listed up there, so I think it's easy to understand the purpose and it is good to be a sample for RE beginners to practice. Obviously the starting point and main code of the ransomware is that 「main.c」file.
NOTE: Note: You can quickly search this list of source code usingyour text editor if you want (smile).
《 3. How does it work to encrypt? 》
As one result of the analysis, as always spotted in all ransomware, there are "OK" and "Prohibited" rules for files/dirs encrypted by malware↓
0x002F1FC /root/.ssh (exclusion) 0x002F207 /usr/bin (exclusion) 0x002F210 /etc/ssh (exclusion) 0x002F219 /home 0x002F21F /root 0x002F225 /var/lib/mysql 0x002F234 /var/www 0x002F23D /etc/nginx 0x002F248 /etc/apache2 0x002F255 /var/logAs you can see it encrypted MySQL libraries (smile), I hope this adversary know what they are doing.
I will guide you on how this can be reversed as following notes (Using x86-32 ELF samples):
Note-1: This is the function that has been used to encrypt the desired (inclusion) targets↓
Note-2: And this is the part where exclusion has been performed to some unwanted targets↓
Please note the reason why they don't want to encrypt "/root/.ssh"
These are the scan-able server's file extentions to be aimed for encryption↓
During file scanning it also greps w/regex the files that contain the following keywords↓
0x002F351 public_html 0x002F35D webapp 0x002F364 backupThere are other functions in this ransomware that you can check out yourself during the practise ;-) which I may ask you during my workshop.
《 4. Reversing the decryption function 》
If we see the result after infection, it seems that the extension ".encrypted" had been added to encrypted files. What actually happened is, in contrast, a huge flaw in how this ransomware works, in which the real files were just deleted with "unlink" and new files were created with a new extension; you can confirm that in the source code at the encryption part and also during the forensics.
If you know how Linux filesystem works you'll understand why I called it as a "huge flaw" ;-)
There are two decrypter functions, which are: decrypt_all() and decrypt_file() functions.
If we reverse decrypt_all(), the part of the code will look like this↓
[ xrefs: 0x004014f1 0x00401502 0x00401523 0x004014a5 0x004014b6 0x0040098e 0x00400ad3 ]
↑Several points can be observed↓
1. This ransomware crypter binary required arguments to run the function. Without arguments in won't work.
Like this command line is needed ⇒ ./ransombinary [crypt|decrypt] [key]
In the x86-32 sample, the argument switch function looks like this:↓
2. From studying the reversed code, you know that you can decrypt the entire Linux server from the "/" (root) directory.
3. decrypt_all() is actually an interface needed to decrypt all crypted files, by ultimately executing decrypt_file().
decrypt_file() function can be seen at the address below. It goes like this↓
[ addr: 0x00400617 xref: 0x00400a4f xcall: setChmod() ]
Noted that "Decrypting file: %s" string can be used as a hint (smile)
This is interesting, right? See the way it is coded.. even though it's ransomware, a malware, it uses stdio.h rather than using a system call, with the arguments used for execution, and the structured programming. Typically a work of an accomplice programmer hired by the bad actor.
By the way, the data of the opened file is read with fread_unlocked (void *data, size_t size, size_t count, FILE *stream). Well this can only mean that the ransomware is meant to target Linux system with that function intact, so.. theoretically it can not be ported to unsupported UNIX platforms like macOS, FreeBSD, NetBSD, OpenBSD, Minix, AIX, HP-UX, Solaris, Cygwin, mingw, MSVC, and Android, which is good for us ;-) Again, PoC of amateur/beginner malcoder.
The following reversing code explains how to decrypt files encrypted by malware.
First, the decryption mechanism of this ransomware uses the RSA private key (held by the criminals) and the public key (held by the victim) to retrieve the encrypted AES key written in the binary, which can then be used to retrieve files encrypted by the malware.
The AES key is encrypted (in the binary) with the private key.↓
Note: We can see the pattern of output from the RSA command is written in its entirety in that "etc etc.." section. In other words, the output from the AES key encryption was parsed into the binary. It is a watermark of what it seems that a builder was used to create the binaries for each Linux ransomware. So there is an automation/framework/tool used for forming this binary. Meaning that we are not dealing with panksters who wanna hack with ransomware at all.
The block cipher spotted in this AES mode of operation is Cipher Block Chaining (CBC) which is a block mode that XORs the previous encrypted block of ciphertext to the next block of plaintext to be encrypted with the 1st encrypted block contains random data.↓)
[ xref: 0x0400836 xcall: aes_decrypt() ]
And, decrypt_file() can be reversed like this↓(in larger picture)
[ xref: 0x00400a4f xcall: setChmod() ]
《 5. Why did they use PolarSSL code? 》
When reversing this ransomware, we found functions from Mbed-TLP / PolarSSL source code. Why they did that?
The AES decryption function in this ransomware includes "mbedtls_aes_setkey_dec" and "mbedtls_aes_crypt_cbc" which are functions which are taken from Mbed-TLP / PolarSSL「mbedtls/pk.h」.
If we see the reversing pad picture at address 0x400836, where aes_decrypt'' function was called, if you trailed that function further you will see that the decryption process (for restoring the cryptid files) is using those function of "mbedtls_aes_setkey_dec" and "mbedtls_aes_crypt_cbc", these functions are being used to decrypt AES on the CBC crypt mode if you familiar with the Mbed-TLP or Polar SSL (coded in mbedtls/pk.h) - So apparently the coder is copy pasting these codes for the ransomware encryption/decryption purpose. The similar operation can be coded with common SSL Linux libraries so we can presume to make sure the ransomware encryption can be executed independently while other more generic crypto libraries can be at risk locked by encryption operations or for other similar reasons.
After that the data of the files recovered during the decryption function for encrypted files was also written by fwrite_unlocked in stdio.h.
The next is the explanation on how the ransomware decrypts AES key encrypted with RSA.
If you read the asm code for the RSA decryption function (AES key cracking function), the sequence is something like this:↓
(click for bigger picture)
At 0x400753 there is private_decrypt() function, if you trace it further you will see mbedtls_pk_decrypt() function. mbedtls_pk_decrypt() function is obviously also from Mbed-TLP / PolarSSL source code with goal to decrypt the binary encrypted AES key, and that decrypted AES key is then to be used to restore the encrypted files.
The mbedtls_pk_decrypt code itself is the source code of PolarSSL, and the purpose of this round is to decrypt messages that were originally encrypted on SSL. If you check the specifications, you will see that mbedtls_pk_decrypt supports "RSA default padding type PKCS#1 v1.5", which means that mbedtls_pk_decrypt can decrypt RSA encryption.
In accordance to the above explanation, if you reverse the decryption function of the AES key, it will look like this:↓
[ xref: 0x0400753 xcall: private_decrypt() ]
So... I wonder what crypto library was used before PolarSSL? Why did "PolarSSL" start being used recently?
Unsurprisingly, there was a version of Linux ransomware before "Linux.Encoder.1" allegedly produced by the same adversary, and I can tell that "PolarSSL" was not used at that time, but they used "OpenSSL". The evidence are the following two cases ↓
Reversing the RSA private key encryption function ↓
Reversing the encryption function of the AES key↓
※The AES key length used from the beginning was 128 bits.
The crypto library was changed probably because of the reason stated above and at that time PolarSSL libraries was more "secure" than OpenSSL to assure the execution of the encryption/decryption. Well, all we can do is just guessing right?
The above picture is my statement that time saying that Encoder.1 (with PolarSSL) was firstly detected and then Encoder.2 (with OpenSSL) was digged afterward.
- This threat is automated built, it has API (interface) to execute the crypto operations for its binary, a trick to avoid instant behavior analysis.
The last version of the encryption function was coded using PolarSSL, crypto libraries, and this encrypter is reading and writing with functions from stdio.h.
- System commands are also executed (unlink, chmod, etc.)... blocking their execution and restoration should be possible on systems that support journald.
- We have confirmed several adversaries source IP addresses, so the author appears to be from Eastern Europe.
- The record KM folks found this ransomware family is here ==> [click]
- Original analysis in 2015 (Japanese)
End of report.
reversed by @unixfreaxjp of MalwareMustDie