GandCrab String Decryption
Introduction
In the last arcitle about Ursnif campaign have been presented the ursnif powershell downloader, which was also able to download the GandCrab payload. This payload was injected as DLL library into the running process and during the last analysis I have extracted it. Now, it is time to look more closely at this GandCrab sample.
Obfuscated strings
After a quick look at the disassembly we can notice many calls to one particular function, in our case named by IDA as sub_10009E69
. These calls appear right after the bunch of mov
instructions with the integer values as the second operands. These values are moved to the local variable placed in the stack. In our case, before these mov
instructions we can see pushing the address of the local variable to the stack. Usually this address is loaded to the eax
register and then pushed. For better imagination, see the following screenshot taken from IDA:
Now, lets dive into the function sub_10009E69
. For clarity purposes, I renamed this function as gandcrab_decrypt_string
. It takes one string argument (char *
) and extracts from it the key for encryption, encrypted data and length of the encrypted data (this is computed as xor of two DWORD values). The encryption key is in this case always 10-bytes long. After that, this is used as parameters for decryption routine.
The decryption routine is RC4. Again, I renamed it as gandcrab_RC4_decrypt
for clarity purposes. In the following picture we can see the RC4 key-scheduling algorithm consisting of two for-cycles from 0 to 255. First is for initialization of identity permutation in the array var_104
, the second for-cycle is for mixing bytes in this array, which results in the pseudorandom permutation of bytes. The 100h values and structure of this two for-cycles can be a good hint for identification of RC4 encryption.
Decryption of the strings
At this point we know enough about string obfuscation, and we should be able to decrypt these obfuscated strings even without executing the sample in debugger. It is time to create IDA script for automatic decryption of these strings. I choose IDC language instead of IDAPython, mainly because the IDAPython is officially not available in the freeware or demo version of the IDA. So IDC script should be more usable also for enthusiasts and students without IDA Pro license.
First, reimplementing the RC4 algorithm in IDC is the easy part, as we can use various online resources with pseudocode implementation, like Wikipedia.
Second, we need to identify the most used function. The function for decryption is usually heavily used, thus this function will be referenced in calls for many times. We can use IDC API and count the xrefs for all of the functions. We can obtain functions with NextFunction(addr)
and xrefs with RfirstB(addr)
and RnextB(addr,ref)
. UPDATE: it turns out that this is not always true and this assumption doesn’t work with GandCrab v5.2 and v5.3 EXE files. See post about updated version.
Next steps are more challenging, we need to reconstruct string argument for gandcrab_decrypt_string
: for each call to this function we need to search backwards for register which is pushed to the stack and holds address of string (offset of ebp). Then we need search for mov
instructions, compute maximal offset of ebp and determine the length of string argument and initialize the null-string with this length. Only now we can replace the placeholder bytes in our string with the values from mov
instructions. This is because sometimes the mov
instructions aren’t sequentially and it can happen that one ‘mov’ sets the 4 bytes at the end of the string, but next mov
sets bytes in the middle of string, so we can not simply append the next 4 bytes to the end of reconstructed string.
Finally, we need to extract the parameters for RC4 decryption: key
, data_length
and data
, decrypt obfuscated strings and display decrypted values, e.g. we can make a comment in disassembly and log them to the script output window.
Now, put it all together and we have the IDC script for GandCrab string decryption. After run, we will obtain the following output from decryption script:
List of decrypted strings
From the following list it is clear which programs are interesting for the GandCrab. It will kill all running instances of Office programs, because they can block the encryption of opened files. It also perform checks for antivirus programs. There are also the mentions of GandCrab (keys, messages, instructions for decryption and so on).
- “Global\iyAzNATdi7a94U8TAO7zVm5qzEjzks” (length: 0x26)
- “Global\%s.luck” (length: 0x10)
- ”@hashbreaker Daniel J. Bernstein let’s dance salsa <3” (length: 0x36)
- ”@hashbreaker :)))” (length: 0x12)
- “A” (length: 0x2)
- “onenote.exe” (length: 0xc)
- “outlook.exe” (length: 0xc)
- “powerpnt.exe” (length: 0xe)
- “steam.exe” (length: 0xa)
- “thebat.exe” (length: 0xc)
- “thebat64.exe” (length: 0xe)
- “thunderbird.exe” (length: 0x10)
- “visio.exe” (length: 0xa)
- “winword.exe” (length: 0xc)
- “wordpad.exe” (length: 0xc)
- “runas” (length: 0x6)
- ”—BEGIN GANDCRAB KEY—” (length: 0x1a)
- ”—END GANDCRAB KEY—” (length: 0x18)
- ”—BEGIN PC DATA—” (length: 0x14)
- ”—END PC DATA—” (length: 0x12)
- “pc_user” (length: 0x8)
- “pc_name” (length: 0x8)
- “pc_group” (length: 0xa)
- “av” (length: 0x4)
- “pc_lang” (length: 0x8)
- “pc_keyb” (length: 0x8)
- “os_major” (length: 0xa)
- “os_bit” (length: 0x8)
- “ransom_id” (length: 0xa)
- “hdd” (length: 0x4)
- “ip” (length: 0x4)
- “ransom_id=” (length: 0xc)
- “SOFTWARE\keys_data\data” (length: 0x18)
- “public” (length: 0x8)
- “private” (length: 0x8)
- “open” (length: 0x6)
- “Keyboard Layout\Preload” (length: 0x18)
- “00000419” (length: 0xa)
- ”/c timeout -c 5 & del “%s” /f /q” (length: 0x22)
- “open” (length: 0x6)
- “cmd.exe” (length: 0x8)
- “pc_user” (length: 0x8)
- “pc_name” (length: 0x8)
- “pc_group” (length: 0xa)
- “av” (length: 0x4)
- “pc_lang” (length: 0x8)
- “pc_keyb” (length: 0x8)
- “os_major” (length: 0xa)
- “os_bit” (length: 0x8)
- “ransom_id” (length: 0xa)
- “hdd” (length: 0x4)
- “ip” (length: 0x4)
- “&id=” (length: 0x6)
- “&sub_id=” (length: 0xa)
- “&version=” (length: 0xa)
- “&action=call” (length: 0xe)
- ”%s/%s/%s/%s.%s” (length: 0x10)
- “wp-content” (length: 0xc)
- “static” (length: 0x8)
- “content” (length: 0x8)
- “includes” (length: 0xa)
- “data” (length: 0x6)
- “uploads” (length: 0x8)
- “news” (length: 0x6)
- “jpg” (length: 0x4)
- “png” (length: 0x4)
- “gif” (length: 0x4)
- “bmp” (length: 0x4)
- “im” (length: 0x4)
- “de” (length: 0x4)
- “ka” (length: 0x4)
- “ke” (length: 0x4)
- “am” (length: 0x4)
- “so” (length: 0x4)
- “fu” (length: 0x4)
- “se” (length: 0x4)
- “da” (length: 0x4)
- “he” (length: 0x4)
- “me” (length: 0x4)
- “mo” (length: 0x4)
- “th” (length: 0x4)
- “zu” (length: 0x4)
- “images” (length: 0x8)
- “pictures” (length: 0xa)
- “image” (length: 0x6)
- “graphic” (length: 0x8)
- “assets” (length: 0x8)
- “pics” (length: 0x6)
- “imgs” (length: 0x6)
- “tmp” (length: 0x4)
- “http://%s” (length: 0xa)
- “POST” (length: 0x6)
- “Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko” (length: 0xc5)
- “GET” (length: 0x4)
- “HTTP/1.1” (length: 0xa)
- ”%s\%s-DECRYPT.txt” (length: 0x12)
- ”%s\KRAB-DECRYPT.txt” (length: 0x14)
- ”%s.KRAB” (length: 0x8)
- “ntdll�dll” (length: 0xc)
- “NtSetInformationFile” (length: 0x18)
- “d9sktop.ini” (length: 0xe)
- “autorun.inf” (length: 0xc)
- “ntuser.dat” (length: 0xc)
- “iconcache.db” (length: 0xe)
- “bootsect.bak” (length: 0xe)
- “boot.ini” (length: 0xa)
- “ntuser.dat.log” (length: 0x10)
- “thumbs.db” (length: 0xa)
- ”-DECRYPT.txt” (length: 0xe)
- ”-DECRYPT.html” (length: 0xe)
- ”%s-DECRYPT.html” (length: 0x10)
- ”%s-DECRYPT.txt” (length: 0x10)
- “KRAB-DECRYPT.html” (length: 0x12)
- “CRAB-DECRYPT.html” (length: 0x12)
- “KRAB-DECRYPT.txt” (length: 0x12)
- “CRAB-DECRYPT.txt” (length: 0x12)
- “ntldr” (length: 0x6)
- “NTDETECT.COM” (length: 0xe)
- “Bootfont.bin” (length: 0xe)
- “SQL” (length: 0x4)
- ”%s%x%x%x%x.lock” (length: 0x10)
- “\ProgramData\” (length: 0xe)
- “\IETldCache\” (length: 0xe)
- “\Boot\” (length: 0x8)
- “\Program Files\” (length: 0x10)
- “\Tor Browser\” (length: 0xe)
- “\All Users\” (length: 0xc)
- “\Local Settings\” (length: 0x12)
- “\Windows\” (length: 0xa)
- ”=” (length: 0x2)
- “&” (length: 0x2)
- “undefined” (length: 0xa)
- “AVP.EXE” (length: 0x8)
- “ekrn.exe” (length: 0xa)
- “avgnt.exe” (length: 0xa)
- “ashDisp.exe” (length: 0xc)
- “NortonAntiBot.exe” (length: 0x12)
- “Mcshield.exe” (length: 0xe)
- “avengine.exe” (length: 0xe)
- “cmdagent.exe” (length: 0xe)
- “smc.exe” (length: 0x8)
- “persfw.exe” (length: 0xc)
- “pccpfw.exe” (length: 0xc)
- “fsguiexe.exe” (length: 0xe)
- “cfp.exe” (length: 0x8)
- “msmpeng.exe” (length: 0xc)
- “SYSTEM\CurrentControlSet\services\Tcpip\Parameters” (length: 0x34)
- “WORKGROUP” (length: 0xa)
- “Contro6 Panel\International” (length: 0x1e)
- “LocaleName” (length: 0xc)
- “Keyboard Layout\Preload” (length: 0x18)
- “00000419” (length: 0xa)
- “productName” (length: 0xc)
- “SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion” (length: 0x3a)
- “productName” (length: 0xc)
- “error” (length: 0x6)
- “x86” (length: 0x4)
- “HARDWARE\DESCRIPTION\System\CentralProcessor\0” (length: 0x30)
- “ProcessorNameString” (length: 0x14)
- “Identifier” (length: 0xc)
- “ntdll.dll” (length: 0xa)
- “RtlComputeCrc32” (length: 0x10)
- “UNKNOWN” (length: 0x8)
- “NO_ROOT_DIR” (length: 0xc)
- “REMOVABLE” (length: 0xa)
- “FIXED” (length: 0x7)
- “REMOTE” (length: 0x8)
- “CDROM” (length: 0x7)
- “RAMDISK” (length: 0x8)
- “Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko” (length: 0x1fc5)
- “HTTP/1.1” (length: 0xa)
- “ENCRYPTED BY GANDCRAB %s” (length: 0x1c)
- “DEAR %s, ” (length: 0xa)
- “DEAR USER, ” (length: 0xc)
- “YOUR FILES ARE UNDER STRONG PROTECTION BY OUR SOFTWARE. IN ORDER TO RESTORE IT YOU MUST BUY DECRYPTOR” (length: 0x68)
- “For further steps read %s-DECRYPT.%s that is located in every Mncrypted folder” (length: 0x4f)