Unpacking Malware: Dridex

Dridex is a malware which has long been targeting the financial sector in attempts to steal user credentials and compromise individuals. It targets individuals by sending phishing emails with Microsoft Office-based attachments embedding malicious macros which download additional payload and attain the authors' objectives. Since the first-stage malware is typically packed by Dridex, we’ll uncover how to unpack it and continue with analysis of subsequent stages.

Acquiring the Malware Sample

Here’s the hash of the malware sample we’ll be using for the unpacking:

TypeHash
MD56a8401448a5bd2b540850f811b20a66d
SHA19f01d4442c495c7128649b98201187bc0c58dedd
SHA256178ba564b39bd07577e974a9b677dfd86ffa1f1d0299dfd958eb883c5ef6c3e1

You can acquire the malware sample from MalwareBazaar.

Unpacking Dridex

Let’s jump into the section where we discuss the packing of the Dridex malware.

Indicators of Packing

Loading the executable into PEStudio, we can see several indicators which point toward a packed executable:

  • Lack of API imports
Lack of Imports

Lack of Imports

  • Size of code is zero
Size of Code

Size of Code

  • Presence of the non-standard .text1 section
Text1 Section

Text1 Section

Unpacking via Dynamic Analysis (x32Dbg)

To get started, load the binary into x32Dbg (we can also use OllyDbg for our analysis). We’ll be setting up a few breakpoints on critical Windows API calls which are typically used by packed malware to load the unpacked malware into memory. The calls include:

  • VirtualAlloc
    • Used to allocate memory in the calling processes' virtual address space
    • Typically used to allocate chunks of memory where the unpacked executable is stored
  • VirtualProtect
    • Used to change the protections on pages (memory segments) within the calling processes' virtual address space

You can use the Command input at the bottom of the screen to use the bp command and set up the desired breakpoints. Here’s an example:

  • bp VirtualAlloc
  • bp VirtualProtect
Setting Up Breakpoints

Setting Up Breakpoints

Let’s kick it off. First, let’s move into user-code so we’re not dwelling in libraries.

NTDLL Library

NTDLL Library

Now EIP should be at the EntryPointof the executable. I’ll simply be executing until our desired breakpoints are hit [F9]. The VirtualAlloc call isn’t of prime importance to us. It’s the address it returns in EAX which points to the recently allocated memory. Let’s execute to return and see what address is returned in EAX. It’s0x490000. Let’s follow it in the first dump.

Address in EAX

Address in EAX (VirtualAlloc)

Now, let’s continue and see if any data is written to this address. Run again and we hit another VirtualAlloc call. Interesting. Let’s execute to return (CTRL+F9) again and see what address is stored in EAX. Let’s follow the address, 0x5A0000 in dump two.

Address in EAX

Address in EAX (VirtualAlloc)

Press Run again and a VirtualAlloc call is hit again. But notice the addresses you previously followed in dumps. They’re not updated with some data. Take a closer look and you’ll see it’s has the MZ header at the start indicating it might be the unpacked PE. But why is it allocating three separate segments of memory? If you go back to dump one (with the address, 0x490000) and scroll down a bit, you’ll see the DOS message (but no MZ header indicating it might be copying data from this segment to the segment in dump two but that’s just one guess since we aren’t properly looking at what it does with the data just yet).

MZ Header in Dump Two

MZ Header in Dump Two

For the third VirtualAlloc call, let’s go to its return and check the address at EAX again. It’s 0x5B0000. Let’s follow this in dump three. Run again and a VirtualProtect call is hit and there’s another MZ header (followed by more data) loaded in dump three. Well, this is a different PE since there’s clearly a difference in terms of data after the PE header. So, what is this binary actually doing? Are there multiple decoys?

MZ Header in Dump Three

MZ Header in Dump Three

Let’s go to the return of the VirtualProtect call now and step out of it by pressing F8 (step over). Since all allocation is done, the VirtualProtect calls are likely just to change the permissions/protections on the pages and make the code executable. We’re interested in dumping the mapped PE out. To do so, let’s see if the addresses we’ve been following are called or jumped to for execution. These are typically jmp or call instructions with the address being pointed to by the eax register. You can breakpoint on these instructions in advance and dump the PE out from the address since this is the point where the binary is now actually going to execute the PE without playing around with any other decoy binary.

JMP Instructions

JMP Instructions

Run past all other breakpoints and stop at the jmp eax breakpoint. Step into the jmp instruction and you’ll see this is where the execution of the unpacked executable begins.

Unpacked Dridex

Unpacked Dridex

We’ve now seen the segment at which the mapped executable begins its execution - 10000000. You can either dump out the mapped binary from the Memory Map using x32Dbg or use a tool like ProcessHacker to do so. I’ll be using Process Hacker to dump the memory. Open up the tool, double click the process (running under x32Dbg), and dump out the entire PE from the address.

Process Memory in ProcessHacker

Process Memory in ProcessHacker

Since this is still a memory-mapped executable, we’ll need to cleanse some bits before it’s usable. Open it up in PE-BEAR and let’s realign the sections. Let’s first fix the section headers such that each section’s raw and virtual sizes are the same. Then, fix the raw sizes such that the size of the first section is equal to the raw address of the second section minus the first one. For the last section, you can fill it up such that the map on the bottom shows perfectly mapped sections on the raw end (usually, you do so by trial-and-error of increasing raw size values. As soon as the red section fills up, you’ve done your bit). For us, it’s C000.

Misaligned Sections

Misaligned Sections

Aligned Sections

Aligned Sections

Now that it’s done, you can see the imports, exports, and executable information which was previously not available to us. One final thing - if you’re to continue your analysis in a static analysis tool like IDA, you’d have to fix the image base address of the executable. Let’s just change it in the Optional Headers from the default of 400000 to 10000000.

Updating the Base Address

Updating the Base Address

That’s it. You’ve got the unpacked executable all ready for further analysis!