Users of the net dread this screen. They feel when they see it all hope is lost.
In the case of this ransomware dropper, the same holds true.
In fact, in running this, I lost my downloads folder >:(
Indeed, a risk all malware reverse engineers take. Live and learn right? Anywho, let’s dive into this bastard already.
A quick peek in IDA shows us what its like under the hood:
Memory packed. How the hell do I know that just peeking real quick? Whenever there’s a bunch of uninitialized data (yellow) that looks like garbage, its most likely its memory packed. This most likely means they’re gonna try the either the RunPE method, or some sort of code injection. Looking through the thing in IDA, I’m not seeing the prerequisites for RunPE, but I do however see one function that stands out for code injection:
See the ‘jmp dword ptr[esi]’ sequence? This is where the malware will make its process leap to another section after preparing the loader. Also note the VirtualAllocEx call for used for allocating some space in another region. The code sequence appears to loop through code and inject it into the region returned by the VirtualAlloc call, then when its done, jumps to it.
That said, let’s load this thing into the debugger and get to work. I start by setting my breakpoints on the usual malware fare (Process creations, file, memory, thread manipulation, etc), and start, breaking at the code space mentioned in IDA:
As I suspected, the malware is injecting the code in ECX into the space pointed to by ESI or in this case 003E0000. We see our jump and more (new) instructions. Let’s hit F9 and continue on through.
There’s a lot going on in this picture. As I said in red, we got a hit, a VirtualProtect call that’s modifying the address space of the original byte space 00400000 from outside (003F00FB). Casual observation shows us an exe header in our registers pointing us to another address space at 008f0000. What does this mean? It means the malware dumped its loader into 008f0000 and is attempting to write the contents into itself in 00400000 (original address space). A form of self modifying code. This also means I was wrong with my RunPE guess. Oh well, can’t win em all right?
Let’s dump the exe in 008f0000 (right click dump, choose save file) and peek in IDA.
Further down from main, we see a function that attempts to grab something from the resources section (FindResource).
There’s something there when we load the thing up with CFF Explorer:
A cab file? Sure ok, whatever. What’s in the cab file?
RTF document. My guess is file is shown to the user so they don’t think anything is up / wrong.
The other functions are responsible for downloading the stage2, and decrypting / running it. For that, let’s step through. In this case, I used ollydump after the process changed its original bytes with the newly loaded sequence. Skipping past the part where it launches the RTF doc we just dissected with ShellExecute, we see a number of functions and a sleep.
The sub routine at 00401a8a just downloads a file. In this case, the malware is downloading the index page from Windows update I guess in an attempt to fool heuristics? After the long sleep, the malware goes through its stage2 loop and attempts to download the encrypted file.
Recall that 00401A8A is for downloading files and takes 1 argument. The value pushed is ‘evalero.com/img/cario.tar.gz’.
Sure enough, at address 01760000 we have our decrypted file complete with exe header. After returning, the code then writes the file, runs it with ShellExecute, sleeps for 10 seconds and deletes the file, exiting.
Note the FindResource call, and the long red section. This is actually garbage. Most of this binary is like this just to anger me. The only code I’m interested in is at 00402A80 with ‘jmp dword ptr [edx]’.
Look familiar? it should, it’s the same code injection jump from the previous binary. How does the thing inject the code after decrypting it? Beats the heck outta me, but there’s a lot of jumping around involved:
Let’s dive right in and break on this jump like last time shall we? Stepping into the function brings me into the area of 00A90000:
Peeking through shows a lot of dynamic address resolution and unpacking. Instead of simply just calling functions, the malware dynamically builds a string of a function and then calls it. Weird right?
See the STOS instruction? That instruction copies the value of EAX and places it in the location ES:[EDI] or 00AB0010. This is basic self modifying code with encryption. The LOOPD instruction tells it to loop and jump X number of times (657910 or so). Executing until return and checking in the dump the address 00AB0000 shows us what we want:
Which means once again I have to dive in to see what it does. I mean I could continue the program, but this is a good stopping point. Immunity complains that its packed (DUH). The first thing I encounter is a call to VirtualAlloc, most likely to free up some space and mark it RWE.
0012FF8C 00495D50 P]I. /CALL to VirtualAlloc from _00AB000.00495D4D
0012FF90 00000000 …. |Address = NULL
0012FF94 001FC000 .À. |Size = 1FC000 (2080768.)
0012FF98 00001000 ... |AllocationType = MEM_COMMIT
0012FF9C 00000004 … \Protect = PAGE_READWRITE
In an effort to save time, I need to wrap this up. The thing calls VirtualProtect next to set the range, it jumps around a lot before eventually unpacking fully and calling its main function in another address 00690000.
Eventually in the unpacked portion, the malware starts looking for files via the FindFirstFile api with a *.* wildcard. It loops through every file in the user’s working directory and base directory (nice enough to skip the system directory and program files folder), inspecting each file extension for MDF, XLS, DOC, PDF, ZIP, 7Zip, etc, but it doesn’t encrypt them yet. Only on the second run.
0012C5B8 00743D5D ]=t. /CALL to CreateFileW from 00743D57
0012C5BC 00869418 ”†. |FileName = “C:\Documents and Settings\All Users\Application Data\Adobe\usnpcde”
0012C5C0 80000000 …€ |Access = GENERIC_READ
0012C5C4 00000000 …. |ShareMode = 0
0012C5C8 00000000 …. |pSecurity = NULL
0012C5CC 00000003 … |Mode = OPEN_EXISTING
0012C5D0 00000002 … |Attributes = HIDDEN
0012C5D4 00000000 …. \hTemplateFile = NULL
After this it copies itself to the temp folder:
Copies itself to temp
0012C850 0074309C œ0t. /CALL to CreateFileW from 0074309A
0012C854 0012D2A0 Ò. |FileName = “C:\DOCUME~1\Joe\LOCALS~1\Temp\ityksxm.exe”
0012C858 40000000 …@ |Access = GENERIC_WRITE
0012C85C 00000003 … |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
0012C860 00000000 …. |pSecurity = NULL
0012C864 00000002 … |Mode = CREATE_ALWAYS
0012C868 00000000 …. |Attributes = 0
0012C86C 00000000 …. \hTemplateFile = NULL
Creates a task for persistence:
0012CB30 7583B76D m·ƒu /CALL to CreateFileW from mstask.7583B767
0012CB34 00D173A0 sÑ. |FileName = “C:\WINDOWS\Tasks\ilhorge.job”
0012CB38 00000000 …. |Access = 0
0012CB3C 00000003 … |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
0012CB40 00000000 …. |pSecurity = NULL
0012CB44 00000003 … |Mode = OPEN_EXISTING
0012CB48 00000000 …. |Attributes = 0
0012CB4C 00000000 …. \hTemplateFile = NULL
Never once does the malware’s second stage write its unencrypted contents to disk, its all contained in RAM making scraping more difficult. I was able to pull the asm contents of the main unpacked function into an IDB file and a text file. There are over 405 THOUSAND lines of assembly code in this bitch. Sure, some of it is data, and most of it is statically linked crap like crypto algorithms, but still, lots of shit to go through.
Have a peek. If you want the IDB file, have at it.
When I have time to revisit (Workshop in 1 month!!!!) I will go into more detail about the encryption used, but its pretty tight stuff – RSA Public key encryption. Block ciphers for large files.
For now though, it seems someone else beat me to the punch.