Matthew Profile picture
Malware Researcher & Reverse Engineer | Creating and Sharing Educational Cyber Content

Sep 25, 2022, 14 tweets

A quick demo of how to identify "real" exported functions from a #obfuscated #IcedID dll file.

I'll also briefly touch on some #Ghidra tips, and how to extract #shellcode using a debugger.

A moderate sized thread😃
[1/13]

[2/13] You can find the relevant files here. Special thanks to @malware_traffic.

First, download the .zip in the screenshot.👇

Then unzip and locate the "rarest.db" file in the "scabs" folder.

(Make sure to do this inside an isolated Virtual Machine)
malware-traffic-analysis.net/2022/09/23/ind…

[3/14] Drag the "rarest.db" file into Pe-Studio and navigate to the exports tab.

There are 11 exported functions here. 🧐

Most of them have junk names to throw off analysis.

One of them is "real", the rest are "decoys" which don't do anything if executed.

[4/14] As a quick example, we can execute the 11th function using rundll32.

Using procmon, you can see the process exits almost immediately, and no new proceses are spawned.

The same will happen for all except 1 of the exported functions.

[5/14] To identify the "real" exported function, I typically use a disassembler.

For this example i'll use #Ghidra.

Open Ghidra and load your file. Then accept all the default settings.

Once Ghidra is loaded, browse to the Symbol Tree -> Exports.

[6/14] In exports (on the left), you should see the same exported function names as you saw in Pe-studio.

Pick one, then focus on the "decompile" view on the right.

(You can ignore the "listing" view in the middle of the screen for now)

[7/14] If you go through the exported functions one-by-one, you'll see that most are duds.

They just "return 0" 👀

This effectively does nothing and exits the malware.

If you encounter this, assume the function is a decoy and click on the next name available.

[8/14] Eventually, you'll find a function which contains a large amount of code.

Without using any crazy analysis skills, it's obvious that this function is different. 👀

In most cases, this is the function that contains "real" #malware code.

[9/14] Now that you have the "real" exported function, you have multiple options to continue analysis.

1⃣ Execute again with rundll32 and analyse with procmon.

2⃣ Continue delving with Ghidra.

3⃣ Use a debugger to execute from the "real" function.

[10/14] Option 1:

Return to rundll32 and execute the malware, this time using the "real" exported function.

From here you can use #procmon or #processhacker to observe further activity.

Look for process creations and file writes.

[11/14] Option 2:

Continue analysis using #Ghidra. Looking for suspicious behaviours and function calls.

In this case, you can quickly notice memory allocations using VirtualAllocEx 🌶️

⏬Below are some indicators that something suspicious is being decrypted or unpacked.

[12/14] Option 3:

Load the file into #x64dbg, then set execution to the newly found function.

Now you can set breakpoints on memory allocations (VirtualAlloc/VirtualAllocEx) and find decoded content.

I previously wrote about this concept here.

[13/14] For the purpose this thread, I've assumed that the analyst does not have access to the scripts which call rundll32 and load the dll.

Those scripts are in the "scabs" folder, you can play around with them and potentially skip the first few steps of this thread 😃

[14/14] That's it for today 🖐️

I'm hoping to write some beginner-friendly on Ghidra and Debuggers in future. So leave a comment if there's any topics you'd be interested in reading about 📘

Share this Scrolly Tale with your friends.

A Scrolly Tale is a new way to read Twitter threads with a more visually immersive experience.
Discover more beautiful Scrolly Tales like this.

Keep scrolling