CryptoDefense: The Ransomware Games have begun

Author: No Comments Share:

If you see a text and / or HTML document on your Desktop called HOW_TO_DECRYPT with the following contents: The crypto defense message then you were unfortunate to be a victim of another crypto-ransomware.   Recently, several of our field engineers encountered this piece of ransomware encrypting files on victim machines. This new ransomware is being distributed via Java drive-by-downloads and it’s likely that more victims could be targeted with this new attack vector. We were able to capture the sample inside a micro-VM implemented in our product so we have all the files and traffic involved in the attack. This allows us to skip the Java exploit and 1st layer dropper for now and focus on the actual malware dropped. If we find something noteworthy in other parts of attack we’ll post a follow up article.

Infection scenario and comparison to Cryptolocker

Attack Scheme This is quite a complex infection workflow, but interestingly it doesn’t require any privilege escalation. Instead of writing code to the existing process it creates a new one (say, svchost.exe) so that it runs with the same privilege level. Thus it can write data into the created process memory, create threads etc. This piece of malware appears to be a competitor of Cryptolocker. There was an article published a while ago by Symantec explaining how to use Windows shadow copies and system restore to recover the files affected by Cryptolocker. In the case of CryptoDefense this won’t work. It makes sure system tools cannot recover the files – the shadow copies are removed and system restore is disabled. According to another report by Symantec the CryptoDefense first showed up at the end of February 2014 (this is when the first BitCoin transaction was made). It appears that by the end of March there were at least 11 000 detections (the real picture might be bigger already) and $34,000 were earned by the gang behind this. In contrast Cryptolocker has made millions of dollars already (around $27 million reported late last year).  So clearly, underground gangs are warming up to the idea of crypto-ransomware and we expect similar ransomware to come up. The Symantec report says that the malware was distributed via spam dissemination. But in our case it was a drive-by-download attack. Interestingly Cryptolocker was also reported to be spreading by spam email letters or installed by bots on the already infected systems (here, here and here). However there’s no evidence that drive-by-download attacks were not involved as well. Now this version seems even more plausible since it’s one of the ways Crypto Defense gets on the machines. Before getting to the analysis of the sample let’s compare Cryptolocker and Crypto Defense.

 Cryptolocker and Crypto Defense comparison * This flaw almost certainly will be fixed in the next update of the malware, since it’s widely discussed and reported in several security related blogs. Some details on how to decrypt your data can be found here.

Interesting details about Cryptolocker versions 1 and 2 can be found in the ESET blog article.   Now let’s look at the implementation details of the sample we acquired. MD5: 5b855b96822a1d9e0bbabc5610769308

Analysis of second stage dropper

The second stage dropper stores the payload in the code section as a sequence of instructions populating stack array as pictured below. 02_obfuscated_payload_as_array The following snippet shows how the de-obfuscated payload is called.

.text:00403A4E   call   prepare_payload
.text:00403A53   mov    [ebp+var_24], offset unpack_and_call_payload
.text:00403A5A   call   [ebp+var_24]

The payload is copied to the array inside prepare_payload function. Then the unpack_and_call_payload function allocates a buffer with execution permissions, writes the payload there and calls it:

.data:004DCCD6 loc_4DCCD6:  
.data:004DCCD6   lea     ebx, [ebp+buffer]
.data:004DCCDC   jmp     loc_4DCD77      ; jump_2_sc
;; ***
;; ***
.data:004DCD77 loc_4DCD77:  
.data:004DCD77   call    ebx

Second stage payload resolves the necessary API calls that are stored in the code section as well:

seg000:00127D41   mov   [ebp+sLoadLibraryA], 'L'
seg000:00127D48   mov   [ebp+sLoadLibraryA+1], 'o'
seg000:00127D4F   mov   [ebp+sLoadLibraryA+2], 'a'
seg000:00127D56   mov   [ebp+sLoadLibraryA+3], 'd'
seg000:00127D5D   mov   [ebp+sLoadLibraryA+4], 'L'
seg000:00127D64   mov   [ebp+sLoadLibraryA+5], 'i'
seg000:00127D6B   mov   [ebp+sLoadLibraryA+6], 'b'
seg000:00127D72   mov   [ebp+sLoadLibraryA+7], 'r'
seg000:00127D79   mov   [ebp+sLoadLibraryA+8], 'a'
seg000:00127D80   mov   [ebp+sLoadLibraryA+9], 'r'
seg000:00127D87   mov   [ebp+sLoadLibraryA+0Ah], 'y'
seg000:00127D8E   mov   [ebp+sLoadLibraryA+0Bh], 'A'
seg000:00127D95   mov   [ebp+sLoadLibraryA+0Ch], 0
seg000:00127D9C   lea   eax, [ebp+sLoadLibraryA]
seg000:00127DA2   push  eax
seg000:00127DA3   push  ebx
seg000:00127DA4   call  esi   ; GetProcAddress(hKernel32, "LoadLibraryA");

After that it “brute-forces” the JPEG resource by id. 04_getting_resource The ID of the resource is actually 53. Interestingly this payload sometimes executes the following sequence: 04_random_delay This might be a way of making a random length delay. It could be used  as an anti-emulation/tracing technique aimed at AV emulators. There’s also an interesting anti-debugging/emulation technique: segment register manipulation. Olly or Immunity Debugger cannot process the following code snippet correctly:

seg000:0012832F loc_12832F:
seg000:0012832F   mov    [ebp+payload], ebx
seg000:00128332   push   ds
seg000:00128333   lea    eax, [ebp+payload] ;
seg000:00128336   pop    gs
seg000:00128338   jmp    dword ptr gs:(loc_128207 - 128207h)[eax]

The code above jumps to yet another de-obfuscated piece of code, which on its turn launches a copy of the calling process (i.e. the second stage dropper) and replaces its image with the final payload. It starts the process in a suspended state and calls ZwUnmapViewOfSection, and then it allocates the memory in the created process and writes down the unpacked payload. Finally it calls ResumeThread. Now explorer.exe is running the malicious code.

Scratching the surface of Crypto Defense

From this point the style of code changes and we can assume that up to this moment it was one big dropper. The final executable is well obfuscated, doesn’t have any imports and almost no strings. API calls are resolved at run time and strings are stored in the code section. So it requires a bit of work before we can get to static analysis. First, we need to resolve all the API calls. The addresses of the functions are resolved by CRC32 and stored in the array or a structure. 06_resolving_IAT The get_proc_addr_by_CRC32 gets a handle to a DLL and iterates through its export table looking for the function name with the matching CRC32 hash value (passed as the second argument). The address of the function is then written to the corresponding offset of the global array (or structure) IAT. This is good because we can look the IAT up in the debugger after it’s populated. Let’s see how our Trojan calls the function:

.text:004136AD    mov    edx, [ebp+var_28]
.text:004136B0    push   edx
.text:004136B1    call   getIAT
.text:004136B6    mov    eax, [eax+218h] ; advapi32.CryptDestroyKey
.text:004136BC    call   eax

GetIAT simply returns the address of IAT array. Clearly there’s a pattern here and we can throw together a script to comment the code for us and list all the cross-references to the API functions (the IAT array is shortened here to save space, you can find the full version at the end of the article).

[code language=”python”]
# IAT as it was looked up in the debugger

IAT = [











# Address of the getIAT function

# Cross reference count
xrefs = {}

# Iterate through all the cross-references to getIAT
for addr in CodeRefsTo(GET_IAT_FUNC_ADDR, True):
# Get next instruction mov reg32, [reg32+offset]
next_inst = NextHead(addr, addr+100)

# Get the offset in bytes
val =  GetOperandValue(next_inst, 1)

# Get the offset in array
iat_offset = val/4

# Resolve function name
func_name = IAT[iat_offset]

# Comment the address where the IAT entry was accessed
MakeComm(next_inst, func_name)

# Update count
if not xrefs.has_key(func_name):
xrefs[func_name] = []

# Print everything
for fname in IAT:
if fname!=” and xrefs.has_key(fname):
print fname, len(xrefs[fname])
print ‘\n’.join(map(lambda x: ‘\t’+hex(x), xrefs[fname]))

The most interesting thing about the IAT is that it has we couldn’t find any cross-references to the CryptDecrypt function. It appears that this particular application is incapable of decrypting files. Perhaps another module is responsible for it. Finally we need to decode the strings that are stored in the code section. In malware analysis data is often much more important than code so it would be great to have a list of strings and cross-references before diving into in-depth analysis. The strings are initialized in one of two ways depicted below: 05_strings Again there is a clear pattern, which allows for the decoding of strings (if not then we can handle the outliers manually later). Here’s the script to output the strings and addresses where they are initialized:

[code language=”python”]

for seg_ea in Segments():
seg_end = SegEnd(seg_ea)
heads = Heads(seg_ea, seg_end)

head =

while head < seg_end: if isCode(GetFlags(head)): mnem = GetMnem(head) # Detect beginning of the string if mnem==’mov’: op = GetOperandValue(head, 1) # If potential string is found if op >= ASCII_START and op <= ASCII_END: h = head string = chr(op) cnt = 0 while True: # Check next instruction h = NextHead(h, seg_end) op = GetOperandValue(h, 1) if GetMnem(h)==’mov’ and op >= ASCII_START and op <= ASCII_END: string+=chr(op) cnt+=1 else: # Check next to the next instruction op = GetOperandValue(NextHead(h, seg_end), 1) if  GetMnem(h)==’mov’ and op >= ASCII_START and op <= ASCII_END: string+=chr(op) cnt+=1 h = NextHead(h, seg_end) else: break if cnt>=4:
print hex(head), string

head = h

head = NextHead(head, seg_end)

The list of strings can be found in the Appendix section at the end of the article. The good thing about this approach is that we can see all the crucial elements of the malicious workflow such as structure of HTTP requests to C&C and what information is collected from the victim machines. Crypto Defense stores CRC32 hashes of the file extensions it’s after. We ran a simple brute force script checking the extensions of size up to 5 characters:

['25msf', '3dm', '3ds', '3fr', '3g2', '3gp', 'accdb', 'ai', 'arw', 'asf', 'asp', 'aspx', 'asx', 'avi', 'back', 'bay', 'bmp', 'c', 'cdr', 'cer', 'cfm', 'cpp', 'cr2', 'crt', 'crw', 'cs', 'db', 'dbf', 'dcr', 'dds', 'der', 'dng', 'doc', 'docm', 'docx', 'dtd', 'dwg', 'dxf', 'dxg', 'eps', 'erf', 'fla', 'flac', 'flv', 'gif', 'h', 'hpp', 'indd', 'java', 'jpe', 'jpeg', 'jpg', 'js', 'jsp', 'kdc', 'key', 'lua', 'm', 'm4v', 'max', 'mdb', 'mdf', 'mef', 'mov', 'mp3', 'mp4', 'mpg', 'mrw', 'msg', 'nef', 'nrw', 'obj', 'odb', 'odc', 'odm', 'odp', 'ods', 'odt', 'orf', 'p12', 'p7b', 'p7c', 'pas', 'pct', 'pdb', 'pdd', 'pdf', 'pef', 'pem', 'pfx', 'php', 'pl', 'png', 'pps', 'ppt', 'pptm', 'pptx', 'prf', 'ps', 'psd', 'pst', 'ptx', 'py', 'r3d', 'raf', 'raw', 'rm', 'rtf', 'rw2', 'rwl', 'sql', 'sr2', 'srf', 'srt', 'srw', 'svg', 'swf', 'tex', 'tga', 'thm', 'tif', 'tiff', 'txt', 'vb', 'vob', 'wb2', 'wmv', 'wpd', 'wps', 'x3f', 'xlk', 'xlr', 'xls', 'xlsb', 'xlsm', 'xlsx', 'yuv']

We’ve got 137 out of 142 file types hardcoded in the binary. So this Trojan tries to encrypt pretty much everything starting from documents, source files to certificates and databases. Interestingly it doesn’t seem to care about archives. Now we can correlate the results of dynamic and static analysis and sum up the activities of the Trojan:

  • Removing all the shadow copies by calling vssadmin.exe Delete Shadows /All /Quiet
  • Disable recovery bcdedit /set {default} recoveryenabled No
  • Disable windows error recovery on startup bcdedit /set {default} bootstatuspolicy ignoreallfailures
  • Disabling system restore by setting the DisableSR registry key to 1
  • Adding itself to the auto-start registry keys
  • Fingerprint system to make unique machine ID
  • Disabling Windows security such as the Defender
  • Connecting to C&C located (allegedly) on one of the hard coded IP addresses
  • Given that there are file system I/O operations and crypto related DLLs, the nefarious claim in the HOW_TO_DECTYPT file is true.
  • Finally almost in every folder (Documents, User home directory, etc.) several files named HOW_TO_DECRYPT are created. The text comes from C&C, which means that it can be different on each victim machine.

Payment Web Site

Unlike Cryptolocker, this malware requires a user to visit their personal page on the CryptoDefense web site. 07_captcha The service seems pretty good so far – a number of languages available. This also tells us that the country-wise attack surface is pretty big. 08_pay Turns out we failed to pay in time (although no deadlines were given), so now we need to pay 1000 USD/EUR (it’s unfair given the dollars-euro exchange rates!). An interesting feature of the “service” is decrypting one file for free: 09_decrypt_one Since we captured this drive-by-download malware sample inside a Bromium microVM, it was isolated from the actual user data. So no damage was done to the end user and nothing really was encrypted; so we didn’t really try out this feature.


The rate of new crypto malware attacks seems to be increasing. It appears to be a profitable business for the underground crimeware gangs. With the widespread success and proliferation of such ransomware, it’s obvious that traditional approaches to end user security are failing to offer countermeasures against this kind of threat. It is worth considering Isolation based security technologies that put a barrier between your real host computer, and this any malware of this nature. If you’re trying to fight this threat using legacy security technology, may the odds be ever in your favor!

Appendix A – List of imported API calls

[code language=”python”]
IAT = [

 Appendix B – List of strings of length 4 or more

0x401219 kernel32.dll

0x4012b2 kernelbase.dll

0x401363 advapi32.dll

0x4013fc user32.dll

0x40145c ws2_32.dll

0x4014bc wininet.dll

0x401549 urlmon.dll

0x4015a9 ole32.dll

0x401600 oleaut32.dll

0x401699 gdi32.dll

0x4016f0 gdiplus.dll


0x403a96 Software\Microsoft\Windows\CurrentVersion\Run

0x403c31 Software\Microsoft\Windows\CurrentVersion\RunOnce

0x40439b {%d|%s|%s}

0x405362 Content-Type: multipart/form-data; boundary=%s—————————–%s

0x405533 —————————–%s–

0x4055e7 Content-Disposition: form-data; name=”%c”

0x405729 Content-Disposition: form-data; name=”%c”; filename=”%s”

0x4058bf Content-Type: application/octet-stream


0x4064dd def001

0x40cf8b \BaseNamedObjects\

0x40d141 \BaseNamedObjects\

0x40da3d explorer.exe

0x40db8d svchost.exe

0x40dbf6 -k netsvcs

0x40e54e \Registry\

0x40e5ae Machine\

0x40e5fc User\






0x411478 systemroot

0x41152b \system32

0x41158a \syswow64

0x411941 ProgramFiles

0x4119be ProgramFiles(x86)

0x411aea SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders

0x411e46 appdata

0x411ea5 desktop

0x411f08 documents

0x411f9a programs

0x412002 startup

0x412061 cookies

0x4120c0 history

0x412123 local appdata

0x4121e5 personal

0x41225f cache

0x4122ba common appdata

0x41238c common desktop

0x41245e common documents

0x412548 common programs

0x412626 common startup

0x412979 Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 5.2)

0x412d27 GETPOST

0x4132f8 http://

0x414aad .browsetor.comhttps://

0x414ffe shell32.dll




0x415b08 software\

0x415de3 vssadmin.exe Delete Shadows /All /Quiet

0x415ea8 bcdedit /set {default} recoveryenabled Nobcdedit /set {default} bootstatuspolicy ignoreallfailures

0x41609d wscsvc

0x4160ee WinDefend

0x416163 wuauserv

0x416205 ERSvc

0x41624a WerSvc

0x416350 Software\Microsoft\Windows\CurrentVersion\Run

0x416575 Windows Defender

0x416658 Software\Microsoft\Windows\CurrentVersion\explorer\ShellServiceObjects\{FD6905CE-952F-41F1-9A6F-135D9C6622CC}

0x416b90 SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRestore

0x416e51 DisableSR

0x417b7c all=%d

Previous Article

Application Security Training

Next Article

Lightning Strikes Twice: First Target, Now eBay

You may also like

Leave a Reply

Your email address will not be published. Required fields are marked *