Malware Analysis —Manual Unpacking of Redaman
In this post, we are looking to manually unpack the sample called Redaman, which is a banking trojan. Some of its capabilities include:
- Monitor browser activity,
- Downloading files to the infected host
- Keylogging activity
- Capture screen shots and record video of the Windows desktop
- Collecting and exfiltrating financial data, specifically targeting Russian banks
- Smart card monitoring
- Shutting down the infected host
- Altering DNS configuration through the Windows host file
- Retrieving clipboard data
- Terminating running processes
- Adding certificates to the Windows store
What makes this sample unique and an excellent training sample to practice manual unpacking is because this sample performs a fairly simple packing process: PE overwrite and a secondary DLL Injection.
Self-Injection, or in this example the PE Overwrite occurs when the malware allocates a “stub” in itself, transfers to that stub address, allocates that stub area and write whatever malicious content it needs to in there, and then changes the permissions, and then run from that overwritten area.
We can identify this file as packed based on a number of info:
High level entropy on the main file with PEStudio:
Checking in IDA, we see that first there is some obfuscation, barely any functions, and only a small amount of analyzed code (blue bar at the top of screenshot)
To start we look for where virtual allocation of memory takes place which in this case it is the function VirtualAlloc. The return value for VirtualAlloc is the base address of the allocated region. Which we can find in the EAX register. We put a breakpoint at the return of the function:
This will help us to see how many times and where memory is being virtually allocated.
We also want to add a breakpoint at the entry of VirtualProtect, this is where the protections and access is changed. The first argument to VirtualProtect will be the address to the memory section which protections will be changed. It needs to change the protections to get the permission to write
Now we run the debugger until we hit our second breakpoint (First one is always on the entry point of the file).
From the screenshot we hit the breakpoint, we right click on the address in EAX and follow in dump. We can see that at address 0003000 there is a large amount of zeros where VirtualAlloc has allocated space.
Continuing on we hit the return of VirtualAlloc again at address 021B0000. So we know that VirtualAlloc is used at address 0003000 and 021B0000. Our next hit is the entry of VirtualProtect:
Checking the first argument passed to VirtualProtect in the EAX register we can automatically see that instead of zeros we now have what looks to be an exe (the MZ or hex 4D 5A gives it away). At this point we now have gotten to the point in the malware where not only has the main payload been unpacked but now it is ready to have its permissions and access changed, we now right click on the dump and choose the “Follow in Memory Map”
In memory map we can see that at the address where the exe is loaded, (021B0000) that location has read and write protections. We now dump out that location and examine it.
Immediately after opening the “unpacked” file we notice that is indeed packed again based on IDA.
There are not enough functions and small amount of analyzed code by IDA. Looking at the few functions that are available we can start to see some interesting actions taking place.
loc_4011AA looks to be a loop. The key is moved to EDX and XORed with a byte from unk_403000 then rotated left. Then theres some decreasing and increasing happening and then there is a conditional jnz which moves the code along only if not being equal to zero.
This is most likely the encryption or encoding algorithm used.
Following along we can see that it is loading DLLs into a buffer. LoadLibraryA is called which provides a return to a handle that can be used in GetProcAddress below:
Next it pushes into a buffer RTLDecompressBuffer which decompresses the buffer which is in this case: NTDLL.DLL
Next called up is DLLGetGlassObject of NTDLL.DLL and then a call to GetProcAddress.
We then see that EAX which holds RTLDecompressBuffer is moved to EDX and then called again. Looking at the documentation for RTLDecompressBuffer, the parameters are:
- [in] CompressionFormat which is 102h
- [Out] UncompressedBuffer Buffer which is [ebp+lpBuffer]
- [in] UncompressedBufferSize which is [ebp+dwSize]
- [in] CompressedBuffer buffer that contains the data in ECX which holds unk_403000 (encryption method)
- [in] CompressedBufferSize which is the length 29CD6h
- [out] FinalUncompressedSize which is the return stored at EAX
This result is then cmp with itself and if it meets the conditional it continues on.
sub_40102A loads KERNEL32.DLL and calls RTLDecompressBuffer in the same way NTDLL.DLL is loaded in. Then we start to see the formation of a temp file
The malware uses GetTempFileNameW, creates the file with CreateFileW, writes to the file using WriteFile and then loads the file as a DLL using LoadLibraryA. (Partially Pictured)
An finally a buffer with the string “host 00000000000” before the code ends. The zeros are probably changed to some unique ID that the malware uses to send back to a C&C server.
That’s all we can get out of IDA so now we move to the debugger and use the same methods to find the payload DLL
Unpacking the “Unpacked” File
Since we know the next step of this malware is to perform a DLL injection, we can put a breakpoint at LoadLibraryW (not LoadLibraryA)…
'A'stands for ASCII and
'W'stands for byte string and the
'A'calls are just the wrappers around the
'W'ones so placing the breakpoint at the
LoadLibraryWwill hit all the load DLL calls.
and from there we can see the path where the DLL will be dropped.
Checking that location we can find the file and checking in PEStudio we can see that it is a DLL (file maybe hidden).
So to wrap things up, we successfully unpacked the inital Redaman file using VirtalAlloc and VirtualProtect, we then discovered the encryption algorithm it uses, and finally unpacked once again with LoadLibraryW to find the payload DLL.
Thanks for reading.