Mickaël Paradis and Marc Theberge, Arc4dia Labs
2015 11 06
One of the most active botnets of 2015, Dridex steals bank account information and is believed responsible for over $35 millions in losses worldwide. Dridex is a descendant of Bugat/Feodo/Cridex and is part of the infamous Zeus family.
In a concerted effort of the FBI and security vendors, the botnet was partly shut down at the end of 2015. Multiple command-and-control nodes were taken down and the botnet kingpin was arrested, thus considerably crippling his capabilities. When the botnet started in July 2015, it was not significant as when a new phishing campaign was launched this fall. The actors behind Dridex are still active. The present article takes a closer look into Dridex attack vector, the packer used to protect against AV solutions and the recon stage.
Dridex is using Microsoft Office documents with macros as attack vector to infect the victims. In an effort to hide the malicious macros from security scanners, the file attached to the emails sent by the botnet are MIME HTML(.MHTML), which is a web page archive format used to incorporate HTML code with all the external dependencies like images, Flash animations and/or audio files. The OLE document(.doc/.docx) with the actual macros is embedded inside the .MHTML file as an ActiveMIME objects.
Below is the base64 encoded object embedded inside the MHTML file. Being compressed as an ActiveMIME object allows the payload to escape network scanners that are not opening those objects to scan them.
Stripping the base64 reveals the actual ActiveMime object.
Finally, inside the ActiveMime container is the OLE document (.doc, .docx).
The document doesn’t make use of vulnerabilities, only macros are present. Taking a look at them is easy enough with the help of a dumping tool like OLEDump.
The first observation is that they are heavily obfuscated, but also that they are set to execute when the document is open.
To make sense of those macros, simply replace the random variable names with meaningful names and decode the strings which are split into multiple parts and encoded by a Caesar cipher of +1. The string decoding function is inside module 5.
Two actions are performed by the macros, download an executable from the C2 and then executes it on the spot with the VBA shell() function. The downloaded file is the actual Dridex Trojan.
See below the HTTP GET query and the command line used in this sample.
The packer used to protect Dridex is in pair with what we would expect from a last generation banker. It contains various AV evasion techniques like exception handling, code rewriting and an original polymorphic engine. The later is taking advantage of something well known in the exploitation world, return oriented programming (ROP). The following is an overview of this AV defence.
Loaded inside IDA, Dridex doesn’t reveal much other than endless operations with no clear goals. This code is randomized for each
compilation, thus making a unique signature each time. Static reversing being of no help in this type of situation, executing the Trojan inside a debugger is the way to go. Running first without breakpoints leads to an exception inside the rpcrt4.dll module.
The exception is provoked deliberately for anti-reversing in an attempt to hide the code logic. Somewhere before the exception is provoked, the malware registers his own handler. When the exception is thrown, the execution is passed to the malware exception handler, thus the malware is back in control.
In order to resume debugging, the malware exception handler must be located. There are various ways to achieve this, but walking the
exception handlers chain like the OS does when an exception is thrown is a quick and easy way.
The chain starts inside the Task Information Block(TIB) segment.
The first DWORD inside the TIB points to the start of the exception handler chain.
The handlers chain is constituted of EXCEPTION_REGISTRATION structures where the first member is a pointer referring to the previous registered handler and the second member is a DWORD containing the address to the handling procedure.
If the malware has registered an error handler, walking each registered handler inside the chain eventually leads to an handler that is coming from the application .text section. The following is the exception handler to whom the execution is passed when the exception is provoked.
Return Oriented Reversing
Inside the handler, the code is still very messy with enough useless and random instructions to make your eyes bleed. On top of that, Dridex is making good usage of return oriented programming(ROP). Well known in vulnerability exploitation for DEP evasion, ROP usage is not common in Trojans. Though, the situation is likely going to change in the near future, because ROP for polymorphic engine is actual a very good idea and it’s already public.
The technique is also easy to implement and hard to detect for AV solutions. A simple push instruction is needed to choose wherever the execution returns.
When the function returns, it doesn’t return where it was called like it should, but inside the chosen widget.
Rewriting the code section is a well known trick for Trojans. It avoids being caught executing outside the .text section and also hides the code logic. Dridex follows the same known pattern for self rewriting, but with the help of ROP.
First, a space is allocated with Kernel32!VirtualAlloc, but the function is never “called” like the usual way. Instead, a pointer to
Kernel32!VirtualAlloc is pushed onto the stack before a return instruction, thus executing inside the function after the return.
A shellcode is then decrypted and copied inside the new allocated space. ROP is yet again used to execute the shellcode.
Inside the shellcode, the library pointers are found using the list of already loaded modules inside the process, InLoadOrderModuleList, which is inside the PEB (Process Environment Block) structure. From each of these libraries, the function pointers are retrieved from the PE exports list.
The shellcode starts by detaching the console window using kernel32!FreeConsole, that way the trojan runs in the background without any GUI.
The next action is to rewrite the code section (.text) by first calling kernel32!VirtualProtect to allows himself write access, then copying the actual Trojan code to the new section. A last ROP sequence starts a new thread with a start address within the new code. The later is not obfuscated and written in C++.
From this point, the Trojan is unpacked and wants to communicate with his C2 with even installing himself. It starts by building a footprint of the box. It do so by querying various registry keys unique to specific Windows versions, thus allowing to correctly guess the version without raising suspicion by calling the usual kernel32!GetVersionEx. Below is the XML footprint that is collected. It contains the hostname with an unique ID, the botnet ID to whom the Trojan is related, a system ID and the architecture. The list of installed packets is also included into the exfiltrated footprint.
The footprint is then encrypted using RC4, a table of 0x100 bytes and the following key.
The encrypted data is sent to one of the C2 found in the following hard coded IP list.
If the Trojan successfully communicates with a C2, it proceeds with infecting the box, if not, it keeps retrying with a longer timeout between each retry.