Due to popular request I'm starting a new reverse engineering article series which will detail how I go about analyzing various samples, instead of just presenting my findings like I normally do. Most of the posts will be centered around IDA Pro (evaluation edition should work too) with WinDbg as a backend (you can use whatever backend you're comfortable with). If you're using something like Immunity or OllyDbg for malware analysis, I recommended following these posts anyway as you'll soon see why it's worth learning IDA. I should also add that I am by no means a professional, so if you have a better way to do something please leave a comment explaining your method.
Starting Off
I actually got the loader binary off virustotal so didn't have to deal with macros, but if you find yourself starting out with one of Dridex's signature malicious word documents, you can follow
| Dridex checking in to the C&C |
As we can see above, explorer makes an outbound connection to a residential IP on port 443 (during first execution it will also bind port 443 or 8443). This is pretty good indicator of compromise (IoC) due to the fact explorer almost never makes connections; but, because it's a favorite for malware to hide in, it can often be seen checking in to botnet C&C servers.
Now that we know the code is in explorer, we need to find it and get it out. One way to find injected code is to open the process in Process Hacker and visit the "Memory" page.
Interestingly enough the return address isn't in the giant RWX region, but it is in a region close to it (likely also belonging to the malware). We can use the WinDbg command "!vprot" on the address to retrieve various information about it, most importantly the "Allocation Base" which needs some explaining.
When using functions like VirtualAlloc(Ex) or NtAllocateVirtualMemory to allocate memory, the kernel allocates in terms of pages. A page is a 4 KB block of memory, if you allocate 1 Byte of memory using one of the above functions you get 4 KB, if you allocate 6 KB you get two 4 KB pages in a row, you get the idea. When an allocation bigger than 4 KB is made (multiple pages), the "Allocation Base" for every page in the allocation will bet set to the start address of the first page, if some malware allocated a bunch of pages and wrote a PE file there, the allocation base would be the start of the DOS header.
. All we need to do is run it with the parameters "-pid <explorer pid> -a <address where PE starts>" and we have the main, unpacked malware binary.
A useful note: if the above methods fail, you can just run pd with the parameter "-pid <explorer pid>" which will dump all modules in explorer, marking any not present in the LDR table (Injected via PE injection) with _hidden_ in the file name.
Well after reading through the extremely long list of imports, we can deduce that none of the 3 are of any real interest and no executable can run on those alone, so the main functions are probably loaded dynamically at runtime. Luckily we don't have to do much legwork as we already know where one of the dynamically loaded functions is called from (the connect() return address from earlier), there would be a good place to start.
The fact the function is called from a thousand different places adds to the theory that it is called every time a function is needed, not just used to resolve them all at startup. We could manually reverse the function to see how it works then write down which id corresponds to which function, or we could cheat.
IDA Python
IDA python is the reason why I pick IDA over a plain debugger, you have the flexibility of python with the power of IDA's API, allowing you to do pretty much anything you could ever want. For future references, here is the
Once we run the script, we'll see output in the IDA output box and a load of new breakpoints.
If we set the console mode to python (click the button that says WINDBG), we can use the DumpNames() function in my script to get a nice list of every function called while the script was running.
Wonderful!
I did previously try to have the script step through and find the "call <reg>" instruction and comment + xref that, but it prove to be incredibly slow and quite buggy, so I settled for just commenting the call to the resolver (it's pretty easy to find the corresponding call if you need to). As well as using xrefs, you can find the comments by hitting ALT + T (search text) and entering the comment name (e.g. ws2_32_connect).
That's all for today, in the next part I'll show how to use a similar technique to locate and dump all the encrypted strings.
SOCIAL SHARE CARD GENERATOR