Maktub Locker is another ransomware that comes with a beautifully designed GUI and few interesting features. Its name originates from the Arabic word maktub which means “this is written” or “this is fate”. The authors were probably trying to make a joke by referencing the act of getting infected with ransomware, hinting that it is uninvited and unavoidable, just like fate.
Analyzed samples
- 74add6536cdcfb8b77d10a1e7be6b9ef
- b24952857ff5cb26b2e97331800fa142 <- main focus of this analysis
- 38eff2f7c6c8810a055ca14628a378e7 – payload (C.dll)
Special thanks to MalwareHunterTeam and Yonathan Klijnsma for sharing the samples.
Behavioral analysis
This ransomware comes in a spam campaign, pretending to be a document with a Terms-Of-Service update. This time full packing have a consistent theme: name of the attachment is made to resemble a document (examples: “TOS-update-[…].scr”, “20160321_tos.scr”), also it has a a document-like icon:
An interesting trick used by this ransomware to spoof legitimate behavior is that it really displays a document! Specifically, a fake TOS update in .rtf format:
While the user is busy reading the document, the malicious program runs in the background and encrypts his/her files.
Encryption process
Maktub Locker does not need to download a key from the CnC server – data can be encrypted offline as well. Extensions given to the encrypted files are random, generated at runtime – their pattern is: [a-z]{4,6}
The new and surprising thing is that encrypted files are much smaller than the original ones. It seems this ransomware not only encrypts but also compresses files.
Original files and their sizes:
The same files after encryption:
See below a visualization of bytes.
square.bmp : left – original, right encrypted with Maktub Locker:
^– the bitmap is compressed very well, so the encrypted file is tiny
A possible reason of compressing files first is to speed up the encryption process.
Encrypted content is different on each run of the sample. However, in a single run, files with the same content will give the same output. We can conclude that the random key is generated only once – at program’s start. After that, every file is encrypted using the same key.
After the encryption is finished, the following GUI pops up:
It provides a victim a custom-formatted key: 82 chunks, each 5 character long (chunk format: [A-Z0-9]{5}). Each time the sample runs, this key is newly generated.
The same information (and layout) can be found in an HTML file ( _DECRYPT_INFO_[$EXTENSION].html), dropped in each encrypted directory.
Website for the victim
These days, it’s a common feature of ransomware to provide a TOR-accessed website for the victim and Maktub Locker is no different. Similar to the ransom note, the website is only available in English. In order to access the individual page, the victim is supposed to paste his/her key (the one supplied in the ransom note) into the input box provided on the website.
It then redirects to the main website. In comparison to other ransomware families, Maktub Locker actually has a very nicely designed website, including clean and polite language used.
It comes with a demo, allowing the decryption of 2 selected files:
The price of decrypting files starts with 1.4 BTC and increases with time. The distributors warn that the website can be taken down and then it would not be possible to recover encrypted files:
Inside
Maktub Locker comes packed in a well-written crypter/FUD, so the code is not readable at first. Also, due to the FUD’s functions, detection is problematic and samples have a low detection ratio in the first hours/days after the campaign starts.
Unpacking
Execution starts in the FUD’s code. At first we can see many harmless-looking (and completely useless) API calls and random strings.
This code is executed first, to deceive tools used to detect malicious behavior. Then it is completely overwritten by new code. However, this is also not the malware code, but just another layer of deception techniques. Below, you can see a fragment of the code responsible for unpacking and executing the bogus TOS update (it is first unpacked from the resources and dropped into the %TEMP% folder as a cabinet file):
The real malicious code starts in another module that is unpacked into dynamically allocated memory.
You can see above 2 threads with entry: 0x10001230. They belong to this malicious module. If we try to dump this memory area, we obtain a new PE file:
This PE file is loaded in a continuous area of dynamically allocated memory and used as a new virtual section.
Unfortunately this time, dumping it will not give us the independent payload – unpacked content has invalid headers, i.e:
This trick is used by the crypter in order to protect the payload from automated dumping tools. However, if we capture the unpacking at the right moment, before the headers are overwritten, we still can recover the original payload. It turns out to be a DLL (packed with UPX):
The code responsible for encrypting files is located in the function “one”.
The DLL is packed with genuine version of UPX, so we can easily unpack it, getting an deobfuscated DLL as result with the following sections layout (unpacked C.dll : 38eff2f7c6c8810a055ca14628a378e7 ):
However, we will still not see valid strings. Imports also seems irrelevant to the functionality (we will not find there, for example, any reference to the windows Crypto API). It is due to the fact that real imports are resolved dynamically. At the beginning of execution, the function “one” loads them on it’s own – first,decrypting their names:
Then, they are accessed via dynamically loaded handles.
Execution flow
This malware first makes a list of all the files, and then processes them one by one. It also unpacks a built-in configuration with list of restricted paths and attacked executables. Each processed path is first checked against this list.
Below you can see a fragment of code opening file that is chosen to be encrypted. Call to the function CreateFileA is performed via handle and dynamically loaded into the EAX register:
Then, a new file is created – with an extension added:
At first both files coexist in the system – the newly created file has 0 size. After it is filled by the encrypted content, the original file gets deleted.
After the process of encryption finished, the malware creates and pops up the dialog box.
Below – code responsible for popping up the GUI with a ransom note:
What is attacked?
It is common practice to exclude some chosen countries from the attack. In this case, before deploying the malicious actions, the application fetches the keyboard locale list. If it finds Russian (value 0x419 = 1049) among them, the malware exits without infecting files:
Excluded from the attack are also some predefined folders:
"\internet explorer\;\history\;\mozilla\;\chrome\;\temp\;\program files\;\program files (x86)\;\microsoft\;\chache\;\chaches\;\appdata\;"
The built-in configuration also specifies what are the extensions to attack:
Like other ransomware families, it attacks not only the local disk but also network shares and disks mounted by virtual environments, including external hard drives.
How does the encryption work?
Maktub Locker uses Window Crypto API. But, as we concluded from the analysis, it uses only one key for all files (does not generate a random key per file). Let’s see what technique it uses to obtain keys…
In this run, the key supplied to a user was:
[code]X25HE-J53ZU-QERDZ-ZNUJ3-SERJ6-J617E-UUASZ-AFG2G-83B08-2SHC1-AUYFZ-GJHF2-W7321-144TM VKFKR-6TKRV-STG4B-CE5MZ-TAH4W-MP541-GD3SB-HE43J-ZF4TK-ZNZTG-R7ZBZ-AKM2U-T6TYN-53J7H MU6J6-BTSJC-FQVQR-EH755-C1WCJ-7SNPT-MHFBS-Q638V-MASEB-R16HW-P84P2-7EEX8-KXAHB-D10F7 GF071-U37K3-GJ5Q5-WD0PD-2EG16-KMC5R-RPCBX-R8EV3-ZPXQV-TDVXM-SEEFX-XK23J-FCH4Z-RNBPN XE6X5-4W8CT-WJQJU-071T5-DSUZW-JGSZA-KFKZ6-4DU0S-80H1H-CEP2J-PDSKA-UXBR8-8C1BB-SDQNC 1C8F7-HPZ2G-Q5JVN-F6WXH-PMUSR-8G4HT-RNYVW-DZNQ3-Y8KZJ-NYC1G-SPR3T-U5GD5 [/code]
Let’s investigate what is the relationship between this key and the key used to encrypt files. So far we know that it must be generated locally.
First it initialized two crypto contexts – both with the same settings, using provider type: PROV_DH_SCHANNEL
Gets 32 random bytes, using function CryptGenRandom
Creates MD5 sum of this random data (using: CryptCreateHash, CryptHashData)
Then, using function CryptDeriveKey it converts the MD5 hash into a 256 bit AES key (AlgID = 0x6610 -> CALG_AES_256).
It also imports RSA public key (2048 bit). This key is hardcoded in the binary.
The random 32 bytes (base of the AES key), along with the random extension, are concatenated together. Then, the prepared buffer is RSA encrypted:
Output is converted using the predefined charset and given to a victim as the individual ID:
That’s why, when the user submit his/her individual ID, the attackers, having the appropriate private key, can decrypt the original data and easily recover the random AES key.
After this operation, the previously generated AES key is used to encrypt files.
First, file content is compressed by a dedicated function (BZip2):
Then, the buffer containing compressed data is AES encrypted – using CryptEncrypt
The encrypted data is saved to the file with the generated extension added.
Conclusion
Maktub Locker has clearly been developed by professionals. The full product’s complexity suggests that it is the work of a team of people with different areas of expertise. From the packing operations to the website, everything is well-polished. We are not sure if the crypter/FUD is designed by the same team – it could also be a commercial solution available on the black market. However, it is not the only level of defense – the core DLL is also obfuscated and for sure prepared by someone with experience in writing malware.
Malwarebytes Anti-Malware detects this threat as: Ransom.Maktub.
Appendix
http://www.bleepingcomputer.com/news/security/the-art-of-the-maktub-locker-ransomware/ – “The Art of the Maktub Locker Ransomware” (detailed description of the graphical design)