In previous posts (story of Trojan dropper part I
) we performed both static and dynamic analysis on the threat and also developed a broad idea of what the malware was doing in it’s initial stages. We now set out to investigate the reason behind the crash of the dropped file (“Adobe.exe”) and at the same time we want to retrieve the payload from this particular malware sample. Analysis:
Let’s go ahead and debug the file. This file (“Adobe.exe”) was found to be packed (custom variant) and the unpacking routine is similar to the approach detailed in part II
of this post, so let’s skip all the gory details and dive right into it.
After unpacking the entire binary in memory, control is transferred to a newly unpacked region at the address "0x401634". Now the action begins from here and we get our first decryption routine, which is a simple 1-byte XOR with a static key as seen in the image below which reveals more code
|Figure 1: Decrypt code |
If we carefully look at the new code below, we can observe that it is riddled with JMP instructions and occasionally we find a few garbage values. The code is crafted in such a way that it resists disassemble attempts which makes reverse engineering the sample more difficult and somewhat painful.
Hidden in between these JMP’s in plain sight is an instruction that is familiar to us by now(i.e the instruction to fetch the address of PEB (Process Environment Block)).
|Figure 2: Fetch address of PEB |
At this point we can only speculate on why the malware needs the PEB address. Moving further in the code, we encounter another decryption point that is exactly same as the first one, which decrypts more code. Now the control is transferred to the newly decrypted code.
|Figure 3: NtGlobalFlag (anti-debug) |
In the image above, we have an interesting bit of code. Recall that the malware already collected the address of PEB. At this point, using the instruction CMP DWORD PTR DS:[EDI+68], ECX (here EDI holds the address of PEB which is "0x7FFD4000" and ECX holds a constant 0x70 ) a comparison is performed, after which a JNZ instruction decides the fate of the control flow.
Here we get our first glimpse of the anti-debugging technique employed by this malware. The instruction CMP DWORD PTR DS:[EDI+68], ECX compares the value of the ECX register (i.e. 0x70) to the location in the PEB structure known as “NtGlobalFlag”. The field is set to a value of “0x70”, if the process is spawned under a debugger.
In our case, this is true since we are debugging the file. Finally, the JNZ instruction at "0x401511" is not taken, which lands us in an invalid region in memory, thus triggering the anti-debugging. Let’s jump here and continue with our analysis. We now have another layer of decryption, which reveals more code after which, as usual, control is transferred to this region.
We then reach another piece of code, which is revealed only if we keep up with the control flow.
|Figure 4: File-path, name identification (anti-debug) |
The above code uses “strstr” to look for a string named “sample” anywhere in file path of our currently debugged file. If found, “strstr” returns a pointer to first occurrence of search string(i.e "sample") in file-path, or else it returns zero. The malware then checks the return value in EAX and takes a conditional jump in the form of JE instruction at "0x401135". If the jump is not taken, the code lands in “ExitProcess”, a call which terminates the process.
This is the second anti-debugging technique the malware employs, although not-an effective one in my opinion considering the odds of a file-path or malware name containing the name “sample”.
|Figure 5: GetVolumeinformation, Volumeserial (anti-debug) |
Again, here we have another anti-debugging technique where the malware retrieves the Volumeserial number using the API GetVolumeinformation and compares it with “0CD1A40” and “70144646”. If either comparison matches, the code jumps to the ExitProcess call.
Another anti-debugging technique follows immediately thereafter in the form of “EnumSystemLocalesA”. The first argument that "EnumSystemLocalesA" accepts is a pointer to the callback function. Here the malware does a neat trick. If we look at the code below, at address “0x401179” a constant “0x2” is pushed onto the stack, which is followed immediately by a CALL.
When this CALL is executed, it pushes the return address onto the top of the stack (which is "0x401180") and the EIP (Instruction pointer) now lands at the "EnumSystemLocalesA" call. Now if we observe the stack, the value on top of the stack is the return address, which naturally becomes the callback function address for "EnumSystemLocalesA" . When the "EnumSystemLocalesA" API is executed, control falls to the callback function, which continues the execution of the code.
|Figure 6: EnumSystemLocalesA (anti-debug) |
Let's now continue our debugging from the address “0x401180”. Not far from here, yet another anti- debugging technique is uncovered. This time the malware retrieves the ‘Diskname’ from the registry.
|Figure 7: Diskname (anti-debug) |
"RegOpenKeyExA" (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Disk\Enum) and "RegQueryValueExA" then uses “strstr” and searches for signs of a virtual environment such as “Xen”, “Vmware”, “Qemu” and also looks for string “virtual”.
|Figure 8: Search vm strings(anti-debug) |
Once the malware detects a virtual environment, it changes the control flow and land us in an invalid memory region. If we play along, we can observe something interesting here.
|Figure 9: Adobe.exe crash |
There we go. We can finally reproduce the crash that happened during the first stage of our analysis.
Ok, so a through binary analysis is often not so straight forward after all !!!
|Figure 10: sandbox identification(anti-debug) |
Let’s move on and see what surprises the malware has this time. Below, we can see anotherpiece of code that checks for a DLL name called “sbiedll” . Here, the malware checks whether it is run in a popular sandbox called “sandboxie”. If found, as usual, the malware bails out.
Immediately afterward, the malware performs a decryption routine to reveal compressed data, which is again packed with aplib
and below we can observe the aplib
unpacking routine which decompresses the data to a PE file.
|Figure 11: Aplib decompression routine |
Soon after, control is passed to the newly decompressed file. Below, we can see the new file being executed.
|Figure 12: New PE-file in memory |
Debugging further, we can observe the malware revealing the final trick that it has up it’s sleeve ,which I will explain in the next post in this series.