New type of articles on the blog ! This time, @0verfl0w from the Zero2Automated Malware Analysis course gave us biweekly challenges to sharpen our skills in malware analysis and reverse engineering.
The goal is to produce a writeup of the challenge and compare with others to see different perspectives.
In this particular challenge, the goal il to automatically extract C2 configuration of an IcedID sample.
We first need to unpack it, and then find the C2 config and extract it using several methods like in IDA Pro or with a static Python script.
Gathering Info and Unpacking
First, this malware is a DLL. I don’t know why it is downloaded as an exe from MalwareBazaar but the can see useful informations in its exports :
The main export here is « DllRegisterServer », which says that the DLL will be registered with regsvr.exe.
Other exports appears to be junk.
There is also a low number of imports, and no unpacking related APIs. We can assume that this malware uses API hashing to load APIs.
We can also notice a very long hex string in the bottom of the binary:
To unpack it, we will use 2 techniques. First, dynamic unpacking (with a debugger) and breakpoints on APIs of interest. Then, we will try to more understand the unpacking mechanism and develop a script to unpack it automatically.
First, I will set breakpoints on VirtualAlloc and VirtualProtect, to monitor new memory pages allocated.
The second call leads to an PE being unpacked on memory, let’s dump it and see if it is IcedID.
I dumped it with x64dbg and fixed its imports automatically by using a tool called DumpFixer. After loading it in IDA Pro, we actually have our unpacked payload !
Let’s see briefly what we can do statically :
That was my first time unpacking a sample statically.
Remember the enormous hex string? It is actually the unpacked payload and other stuff.
When jumping into the function (and with a bit of research in debugger) I actually found the RC4 key :
We can then assume that the function decrypts the hex string with this key.
With decrypted data, we can see that the string « |SPL| » is present several times. This is a separator, and the data chunk actually contains 5 different files.
Two of them are shell code, two others are pictures, and the other one is the DLL that we managed to unpack dynamically.
We can then extract the DLL statically for further analysis.
This part was bonus and not asked in the challenge.
Extracting C2 Configuration
Let’s analyse the next stage.
When loading the sample in IDA, we can see that the malware will create a thread. To see what this thread will do, we just have to clic on StartAddress.
The first function of the flow loads and perform operations with a strange chunk of data. Right after, it seems doing something with HTTP requests.
Stepping in this function in x64dbg, we can see that the return value is currently our C2 URL :
The decryption function is very simple. The data chunk contains 128 bytes of data. 64 for the C2 Url, and 64 for bytes to be XORed with C2 data.
With a very simple Python script, we easily extract this data in the malware, and unXOR it to reveal the C2 URL.
Finally, we can use a regex to extract the URL from this hideous data. Mixing it with the unpacking script, we can automatically extract C2 config from packed sample.
The complete script is available here
We managed to extract the C2 of the malware easily.
However, this script will only be able to unpack and extract C2 from this particular sample. IcedID uses obfuscation, so the hardcoded offsets in the unpacking script will not point to RC4 key or data to decode.
I could have tried to create a more general script to unpack and extract the configuration of the other samples, but I preferred to focus on the instruction so as not to waste time unnecessarily.
That was a (simple but) very cool challenge! I learned how to do static unpacking in other ways than emulation, and learned how to extract configuration from a malware.
See you for the next challenge !