Reverse Engineering (Manual Unpacking) IcedID/Bokbot Malware Write-up

This post will explain how to reverse engineer malware that is packed by UPX packer. Packing is a common technique used by malware authors to make analysis more difficult to analyze malware. We will use pestudio for initial analysis, DetectItEasy, PE Bear, HxD and use x64dbg, & cutter to disassemble the binary.

METHOD 1.

Tools

pestudio Detectiteasy
x64dbg
PE Bear

hxd

Disclaimer

You are dealing with a real malware sample. Run and Analyze it in a controlled environment (sandbox) with no connections to the internal network or internet. I am not responsible for any consequences or damage if you fail to obey this rule.

Static Analysis:
A windows virtual machine was setup with above mentioned tools. Ensured that a clean state of Windows VM with all tools is taken as a snapshot. The below IceID variant is going to be used in following analysis.

Hash

SHA256: 0ca2971ffedf0704ac5a2b6584f462ce27bac60f17888557dc8cd414558b479e

Static analysis of IceID in PEStudio shows the sections are packed using UPX and DIE confirms that it is packed due to its high entophy. The sample does not have ASLR enabled. This is confirmed by CFF explorer-setdll characteristics or ProcessHacker.

Dynamic Analysis
Hybdrid analysis shows the sample starts a copy of itself and subprocesses svchost and others. svchost presence depicts injection.
Load the malware sample to x64dbg/x32dbg for unpacking and set breakpoints at some common APIs:
CreateProcessInternalW (when malware creates the process)
WriteProcessMemory (when malware writes something to that process)
ResumeThread (Incase we mess up and reume created process)
1.After placing the breakpoints as stated, press F9 to execute. First hit will be at the entry point, then run (press F9) the malware again at hit the WriteProcessMemory breakpoint.
Next we will have to find out what the malware is writing in and see if we can see a PE File is in memory which we can curve out. For this to happen, we need to find out what arguments are passed and this is found on the MSDN for WriteProcessMemory. The third agrument is the pointer to the buffer(lpBuffer) which we will be going to use to follow in dump from the stack. Ist thing on the stack is the return address for the call, then after that we start the count. next will be handle to the process, base address then the buffer pointer.
2. Next, Right click on the third argument on the stack (4th overall) then click on "follow DWORD in dump" as shown below.
3.Looking at the dump section, we dont see a PE file with a MZ header (4d 5a) written to the process as in the image below.
Since we didnt see any executable written, we run the malware again (F9) to hit the next WriteProcessMemory API, follow the 3rd argument on the stack window and follow DWORD in dump and check for a MZ header on the dump window ie repeat process 1,2 and 3. Repeat this process until you find a PE which is depicted with a MZ header. After 6 times you get the PE that has been written into the process space of the process that is created.
Next we dump the PE file by right clicking on the dump section then follow in memory map.
Next we retrieve the file by chosing "dump the memory to file".
The PE was written directly into the process space of the process that is created in its mapped format. Normal PE /.exe files is in its file or unmapped format. When mapped into memory to run, all sections are readdressed to virtual addresses to run in memory ie mapped format. Looking at the dumped file in PE Bear section header, we see two different values in the raw and virtual addresses and section names are called UPX.
Looking at the dumped file in HxD, we see that the code starts at the same value seen in the virual address meaning there was a section overwrite. Instead of code starting at 400 (unmapped format), we also have code starting at 6000 (mapped). Code was written and execution transffered to 6000.
We need to change the raw addressed and size to match the virtual addresses and size because we have dumped a mapped PE file.
We save the new file as unmapped.exe. Next, we will unpack the PE using the tail jump method. We load the PE is IDA, right click on the CPU section and chose graph view. Scroll to the bottom on the graph view to find the tail jump and put a break point on it by clicking on F2 or Right click> breakpoint> toggle.
Run the malware to hit the break point. In other cases, you can use breakpoints to VirtualAlloc and VirtualProtect.
Next, we jump/step into the code by pressing F7. We are now at the OEP (Original Entry Point) for the unpacked section ie where the EIP points to in the CPU window.
Next we use Scylla tool to dump the file out. Syclla plugin is available on X64bdg/x32dbg. Open Scylla and attach it the the unmapped process.
Next, change the OEP on Scylla to match the one on x64 DBG that the EIP was pointing to on the cpu window and click on "dump" to dump the file.
Next, fix the import address table using Scylla by clicking on the IAT (Import Address Table) Auto search button, accept using the advanced results, click OK and then click on Get Imports. Finally click on fix dump and select the last dumped IceID unmapped file.
Now we have the unpacked version of the IceID PE file. You can load the PE on IDA or Cutter and check the pseudocode to see what the malware is doing.
METHOD2:
We will be skipping the static analysis section that has been covered in the previous section and dive straight into dynamic analysis. Just to highlight, the code section has a high entrophy meaning it's packed per PE Studio.
Once again load the malware using x64dbg to unpack it and set breakpoints at the below functions/APIs. A quick look at the Import section (ctrl + N) shows common anti debugging functions such as IsDebuggerPresent and GetTickCount.
VirtualAlloc
VirtualProtect
CreateProcessInternalW
WriteProcessMemory
After placing the breakpoints, run the malware by pressing F9 and we hit the first VirtualAlloc.
Next, click on Execute till Return (Ctrl+F9) to pause execution after current function is done executing and then click on EAX in the memory section, right click it and follow in dump the allocated memory (return in EAX register).
Looking at the dump section, we do not see any PE/Executable usually indicated by the MZ (4d 5a) header.
Next, Continue running the malware with F9, we hit the second call to VirtualAlloc, Execute till Return (Ctrl+F9), and observe changes in the allocated memory (EAX- follow in dump again). We see new bytes being written to the dump section and it is likely a shellcode but has no MZ header. Repeat the same process again to hit the 3rd virtual alloc, ctl + f9, follow new EAX in dump and finally a executable with MZ header is written to the dump section.
Finally, right click on the dump section to "Follow in Memory Map", then "Dump Memory to FIle" to acquire the executable that had been written to memory.
Using PE Bear, CFF explorer or PE Studio, we see that the PE is packed with UPX and we can use UPX tool to unpack the malware by: "upe.exe -d -o packed.exe unpacked.exe"
Conclusion
This was an introductory post to how to identify and unpack packed malware.
Special Thanks to @OALabs (Open Analysis Live) for pioneering, inspiring in this and making understanding malware reversing alot easier for self taught individuals like myself.

Comments