After my last post about CTB-Locker I received a lot of e-mails from people asking for a complete analysis of the malware. Most of them wanted to know if it’s possible to restore the compromised files without paying the ransom. The answer is simple: it’s impossible without knowing the Master key! That key resides on the malicious server and it’s the only way to restore every single compromised file.
There are a some articles on the net about CTB-Locker’s modus-operandi. Everyone knows that ZLib is used, AES is used but only few of them mention the use of SHA256+Curve. To explain everything in details I’ll show you how encryption/decryption is done, step by step.
Preamble: HIDDENINFO
HiddenInfo file is the core of the malware, it’s full of precious data. There’s no need to explain every field of the file, a closer look at the first part of it would suffice because it has an important part in the encryption/decryption scheme.
DCE1C1 call ds:CryptGenRandom DCE1C7 lea eax, [ebp+systemTimeAsFileTime] DCE1CA push eax DCE1CB call ds:GetSystemTimeAsFileTime DCE1D1 call ds:GetTickCount DCE1D7 mov [ebp+gettickcountVal], eax DCE1DA call ds:GetCurrentThreadId DCE1E0 mov esi, eax DCE1E2 rol esi, 10h ; Shift ThreadID DCE1E5 call ds:GetCurrentProcessId DCE1EB xor eax, esi ; ThreadID and ProcessID values inside the same dword DCE1ED mov [ebp+threadID_processID], eax DCE1F0 mov esi, 0EB7910h DCE1F5 lea edi, [ebp+machineGuid] DCE1F8 movsd ; Move MachineGUID DCE1F9 movsd DCE1FA movsd DCE1FB lea eax, [ebp+random] ; Random sequence of bytes DCE1FE push 34h ; Number of bytes to hash DCE200 push eax ; Sequence of bytes to hash DCE201 mov ecx, ebx ; Output buffer DCE203 movsd DCE204 call SHA256 ; SHA256(random) DCE209 mov al, [ebx+1Fh] DCE20C and byte ptr [ebx], 0F8h DCE20F push 0E98718h ; Basepoint DCE214 and al, 3Fh DCE216 push ebx ; SHA256(random) DCE217 push [ebp+outputBuffer] ; Public key DCE21A or al, 40h DCE21C mov [ebx+1Fh], al DCE21F call curve_25519
The snippet is part of a procedure I called GenSecretAndPublicKeys. The secret key is obtained applying SHA256 to a random sequence of 0x34 bytes composed by:
0x14 bytes: from CryptGenRandom function 0x08 bytes: from GetSystemTimeAsFileTime 0x04 bytes: from GetTickCount 0x04 bytes: from (ThreadID ^ ProcessID) 0x10 bytes: MachineGuid
Curve25519 is used to generate the corresponding public key. You can recognize the algo from Basepoint vector because it’s a 0x09 byte followed by a series of 0x00 bytes (For a quick overview over the Elliptic curve algorithm used by the malware take a look here: http://cr.yp.to/ecdh.html).
GenSecretAndPublicKeys is called two times, so two private and two public keys are created. I name them as ASecret, APublic, BSecret and BPublic.
DCF1E7 mov [esp+274h+public], offset MasterPublic ; MPublic key DCF1EE push eax ; BSecret DCF1EF lea eax, [ebp+Shared_1] ; Shared_1 DCF1F5 push eax DCF1F6 call curve_25519 DCF1FB add esp, 0Ch DCF1FE lea eax, [ebp+Shared_1] DCF204 push 20h DCF206 push eax DCF207 lea ecx, [ebp+aesKey] ; Hash is saved here DCF20A call SHA256
SHA256(curve_25519(Shared_1, BSecret, MPublic))
Shared secret computation takes place. MPublic is the Master public key and it’s visible inside the memory address space of the malware. The Master secret key remains on the malicious server. To locate the Master public key is pretty easy because it’s between the information section (sequence of info in various languages) and the “.onion” address. Shared secret is then putted inside SHA256 hash algorithm, and the result is used as a key for AES encryption:
DCF20F lea eax, [ebp+aesExpandedKey] DCF215 push eax DCF216 mov edx, 100h DCF21B lea ecx, [ebp+aesKey] DCF21E call AEXExpandKey DCF223 add esp, 0Ch DCF226 xor edi, edi DCF228 lea ecx, [ebp+aesExpandedKey] DCF22E lea eax, [edi+0EF71ACh] DCF234 push ecx DCF235 push eax DCF236 push eax DCF237 call AES_ENCRYPT ; AES encryption
The malware encrypts a block of bytes (named SecretInfo) composed by:
SecretInfo: ASecret ; a secret key generated by GenSecretAndPublicKeys MachineGuid ; Used to identify the infected machine Various information (fixed value, checksum val among others)
Not so hard but it’s better to outline everything:
ASecret = SHA256(0x34_random_bytes)
Curve_25519(APublic, ASecret, BasePoint)
BSecret = SHA256(0x34_random_bytes)
Curve_25519(BPublic, BSecret, BasePoint)
Curve_25519(Shared_1, BSecret, MPublic)
AES_KEY_1 = SHA256(Shared_1)
Encrypted_SecretInfo = AES_ENCRYPT(SecretInfo, AES_KEY_1)
Part of these informations are saved inside HiddenInfo file, more precisely at the beginning of it:
HiddenInfo: +0x00 offset: APublic +0x24 offset: BPublic +0x44 offset: Encrypted_SecretInfo
So, two public keys are visible, but private key ASecret is encrypted. It’s impossible to get the real ASecret value without the AES key…
Ok, now that you know how HiddenInfo file is created I can start with the file encryption scheme.
CTB-Locker file encryption
C74834 lea eax, [ebp+50h+var_124] ; Hash will be saved here C7483A push eax C7483B lea eax, [ebp+50h+var_E4] C74841 push 30h C74843 lea edi, [ebp+50h+var_D4] C74849 push eax ; 0x30 random bytes C7484A rep movsd C7484C call SHA256Hash ... C7486E push eax ; BasePoint C7486F lea eax, [ebp+50h+var_124] C74875 push eax ; CSecret: SHA256(0x30_random_bytes) C74876 lea eax, [ebp+50h+var_B4] C74879 push eax ; CPublic C7487A call curve25519 ; Generate a public key C7487F push offset dword_C943B8 ; DPublic: first 32 bytes of HiddenInfo (*) C74884 lea eax, [ebp+50h+var_124] C7488A push eax ; CSecret C7488B lea eax, [ebp+50h+var_164] C74891 push eax ; Shared_2 C74892 call curve25519 ; Generate shared secret C74897 lea eax, [ebp+50h+var_144] C7489D push eax C7489E lea eax, [ebp+50h+var_164] C748A4 push 20h C748A6 push eax ; Shared_2 C748A7 call SHA256Hash ; SHA256(Shared_2) ... C74955 push 34h C74957 push [ebp+50h+var_18] ; Compression level: 3 C7495A lea eax, [ebp+50h+PointerToFileToEncrypt] C7495D push eax ; Original file bytes to compress C7495E call ZLibCompress ... C74B1F push [ebp+50h+var_4] C74B22 lea ecx, [ebp+50h+expandedKey] ; SHA256(Share_2) is used as key C74B28 push [ebp+50h+var_4] C74B2B call AES_Encrypt ; It encrypts 16 bytes per round starting from the first 16 bytes of the ZLib compressed file C74B30 add [ebp+50h+var_4], 10h C74B34 dec ebx ; Decrease the pointer to the bytes to encrypt C74B35 jnz short loc_C74B1F ; Jump up and encrypt the next 16 bytes
It’s quite easy indeed, it uses the same functions (SHA256, Curve, AES). To understand what’s going on you only have to follow the code. The operations sequence is:
CSecret = SHA256(0x30_random_bytes)
Curve_25519(CPublic, CSecret, BasePoint)
Curve_15519(Shared_2, CSecret, APublic) (*)
AES_KEY_2 = SHA256(Shared_2)
ZLibFile = ZLibCompress(OriginalFile)
Encrypted_File = AES_Encrypt(ZLibFile, AES_KEY2)
(*) DPublic inside the disassembled code is indeed APublic (first 32 bytes of HiddenInfo)
That’s the way how CTB-Locker encrypts the bytes of the orginal file. These bytes are saved into the new compromised file with some more data. A typical compromised file has the next structure:
+0x00 offset: CPublic +0x20 offset: AES_Encrypt(InfoVector, AES_KEY_2) +0x30 offset: AES_Encrypt(ZLibFile, AES_KEY2)
InfoVector is a sequence of 16 bytes with the first four equals to “CTB1”, this tag word is used to check the correctness of the key provided by the server during the decryption routine.
The decryption demonstration feature, implemented by the malware to prove that it can restore the file, uses
AES_KEY_2 directly. If you remember the key was saved inside HiddenInfo, there are a total of five saved keys.
In this case if you have CSecret you can easily follow the process described above (remember that APublic comes from the first 32 bytes of HiddenInfo), but without CSecret it’s impossible to restore the original files.
It’s important to note that in the encryption process CTB-Locker doesn’t need an open internet connection. It doesn’t send keys/data to the server, it simply encrypts everything! Internet connection is needed in the decryption part only.
CTB-Locker file decryption
At some point, before the real decryption process, there’s a data exchange between the infected machine and the malicious server. The malware sends a block of bytes (taken from HiddenInfo) to the server and the server replies sending back the unique decryption key. The block is composed by the BPublic key, SecretInfo and some minor things:
DataToServer: 32 bytes: BPublic 90 bytes: SecretInfo 16 bytes: general info
The malware uses the key to restore the files. Do you remember the decryption part from my last post? Well, the real decryption scheme is not so different. There’s one more step, the calculation of the AES key. To do that the unique key sent by the server is used to decrypt every file:
curve_25519(Shared, Unique_Key, first_0x20_byte_from_compromised_file)
AES_DECRYPTION_KEY = SHA256(Shared)
ZLibFile = AES_Decrypt(Encrypted_File, AES_DECRYPTION_KEY)
OriginalFile = ZLibDecompress(ZLibFile)
The unique key is sent just one time, so the decryption method needs only one key to decrypt all the compromised files. How is it possible?
My explanation
From HiddenInfo part I have:
Curve_25519(APublic, Asecret, BasePoint)
Curve_25519(BPublic, BSecret, BasePoint)
Curve_25519(Shared_1, BSecret, MPublic)
AES_KEY_1 = SHA256(Shared_1)
Encrypted_SecretInfo = AES_ENCRYPT(SecretInfo, AES_KEY_1)
The server receives DataToServer and it applies the principle of elliptic curve:
Curve_25519(Shared_1, MSecret, BPublic)
Shared_1 from the server is equal to Shared_1 calculated in the HiddenInfo creation part.
Now, with Shared_1 it AES decrypts SecretInfo obtaining ASecret key. ASecret is the key used to decrypt all the compromised files.
From Encryption part:
Curve_25519(CPublic, CSecret, BasePoint)
Curve_15519(Shared_2, CSecret, APublic)
AES_KEY_2 = SHA256(Shared_2)
ZLibFile = ZLibCompress(OriginalFile)
Encrypted_File = AES_Encrypt(ZLibFile, AES_KEY_2)
Saying that, here is how to use ASecret in the decryption process (applying the same EC principle):
Curve_25519(Shared_2, ASecret, CPublic)
AES_KEY_2 = SHA256(Shared_2)
ZLibFile = AES_Decrypt(Encrypted_File, AES_KEY_2)
OriginalFile =ZLibDecompress(ZLibFile)
So, ASecret is the Unique_Key computed by the server and it’s used to decrypt every file. That means one thing only, without MSecret you can’t restore your original files…
Final thoughts
There’s nothing much to say really. CTB-Locker is dangerous and it will damage systems until people will do double-click over attachments.. sad but true.
Feel free to contact me for comments, criticisms, suggestions, etcetc!
I was wondering if during files ecription AES_KEY_1 can be retrived dumping the RAM, and if CTB locker attempt to encrypt new files added on the computer…
You can dump the key during encryption, but it doesn’t help you too much because the key is randomly created…
New files are not touched by CTB.
I understand, it’s near impossibile to decrypt…
The only way could be to search for the aes key into the swap file, but it’s needed many luck…
Pingback: Actus Sécurité Confirmé 2015 S08 | La Mare du Gof
Pingback: 1 – CTB-Locker encryption/decryption scheme in details | blog.offeryour.com
One of my employee infected . as it person,
how can i recover his file??
Will this file help you?
http://nethost.co.il/support/ctblocker/CTB-Unlocker.exe
Thats the file the scammers sent to a victim who actually paid.
Unfortunately no… thx anyway
I am a professional photographer. A few weeks ago my computer was attacked by CTB-LOCKER the one with the black screen and code KEY. Proven Data Recovery has been able to identify the VARIENT of the virus I have. It is – RSA-2048 CTB-Locker encryption virus.
They want 2,600 for the decryption of 300 image files that this virus has encrypted on a SD CARD. The computer still reads close to 900mb of data on the card and I have been told by multiple sources that there is a chance my images are still there, but I have had no luck and it’s going to take me quite some time to come up with this money so in mean time I am exploring other options and learning more about computers and code than I would otherwise have never cared to.
It angers me to no end that people can actually even do this. That they can hurt total strangers in this away. Hurt their jobs. Effect their lives just for the sake of doing so and then dangle our data in front of us so we freak out and jump. I refuse to pay this RANSOM and it is frustrating to no end that the supposed GOOD GUYS want WAY THE HELL MORE!! It’s very backwards to me and does not seem right. It is almost impossible to get a simple strait answer from people in this area and there is a lot of double talk and I have bad a couple people remote access my computer and I see them try things even I have tried.
The files that are blocked were never on my hard drive. I didn’t even have time to make a hard copy. One moment they were find and the next they were encrypted. I have done 2 system restored and a factory restore and computer has updated protection but the files remain locked on my card.
Is there any effective decryption for CTB-LOCKER – RSA-2048 CTB-Locker encryption virus
What are the odds? Is it even worth saving all this money for these people? He did ID the variant. Even that came as a shock. It’s all I have to go on. Maybe, if you think you have a solution for me of course I would be willing to work put pay arrangement but I would need to see at lest SOME proof. Maybe do one or two that I can see. There are 300 on the card and I am really quite desperate for this material, or to be told convincingly and enough times that all hop is lost. I am not at that point yet.
Thanks for your time
Sincerely
Scott
Is it possible to reconfigure the master key, when u have all keys but the master, and both the source and the of a crypted file?
I was also wondering if the Master could be decrypted if all the other elements are known, and both files (encrypted and before encryption) are available?
hi , any news regarding decrypting ctb locker? I have some files encrypted,thanks
Pingback: The state of Ransomware in 2015 | Fox-IT International blog
Pingback: The state of Ransomware in 2015 | vulnerablelife
Pingback: A king’s ransom: an analysis of the CTB-locker ransomware | vulnerablelife
my PC want ransomeware
Pingback: The current state of ransomware: CTB-Locker – Net Universe International Corp
Any possibility to decrypt files (by paying ransom) if CTB removed (but still have the “DecryptAllFiles.txt”) from PC?
If not… any possibility if infected again?
thanks
Pingback: The current state of ransomware: CTB-Locker - The Cloud Key
Thanks for your explanation of CTB-locker.
From your description I conclude that the only thing I have to keep to be able to decrypt the files in the future (If master secret key is somehow found e.a. by police) is the files them selfs. The hardware identification is stored in the encrypted files, so decryption can take place on another computer. (If the Master secret key is miraculously retrieved from the malicious server.)