Inkasso Trojaner – Part 1Date: 2013-06-18 07:56:00
Some days ago we received an email with a double zipped dropper agent included. We decided to start an analysis. This is the first part with our results, in this blogpost we only focus on the dropper itself.
The malware propagation vector is email. After execution, the malware itself is capable to hide its presence within the system, thus it can bypass the unskilled eye. The dropper is already detected by several AV engines (which is shown below), thus newer versions will appear perhaps in the close future.
The dropper itself was design to communicate with several hardcoded C&C (Command and Control systems) to receive more commands. Most of them are directly related to download and install a second stage malware – the botnet agent.
|Filename:||Firstname Lastname Mahngebühren 13.05.2013 RandomNumber www.landsend.de.zip|
|Create Date (GMT):||2013-05-13 17:40:20|
The module is a double zipped Win32 PE executable file compiled in Microsoft Visual C++ 7/8. Its main purpose is to drop a second stage executable.
|Filename:||Vertragliche Mahnung vom 13.05.2013 Inkasso.zip (second archive)|
|Create Date (GMT):||2013-05-13 17:14:20|
|Filename:||Vertragliche Mahnung vom 13.05.2013 Inkasso.com (target executable)|
|Create Date (GMT):||2013-05-13 17:13:28|
The executable masks its presence behind .com extension (perhaps to fool less technical orientated users) however it’s a plain PE file (Portable and Executable – also called PE/COFF because of its roots in an old COFF file format derived from UNIX systems). COM file was adopted directly from MS-DOS and doesn’t contain any special headers nor sections – it contains code and data in one 64K memory segment. To confirm that this is just a straight PE/COFF file we used simple hexdump shown below:
First two bytes 4D5A (which translate to “MZ” string) indicate a “magic value” representing PE/COFF executable. Then the DOS stub is really easy to spot (i.e. string “This program cannot be run in DOS mode”). After loading it into our favorite disassembler IDA Pro our tool of choice shows generic PE sections:
Brief analysis of IAT (Import Address Table – section of PE file which is used as a lookup table when the application is calling a function in a different module) shows that the given binary utilizes several API calls from generic DLLs (comdlg32.dll, kernel32.dll, ole32.dll):
Moving forward – auditor checked for some “hidden” data within the binary and found interesting strings altogether with cloned resources section from NeroStartSmart.exe.
Below is a dump of some interesting strings found within the binary:
And here is a partial dump of .rsrc section:
Resources were cloned from NeroStartSmart.exe executable (which is part of the Nero Burning ROM package created by Ahead Software AG).
The entry point of the executable points to address 00402067 which contains calls to __security_init_cookie() and __tmainCRTStartup() where WinMain() function is localized at address 00401130.
At 004011FE address in WinMain() there is a call to first decryption routine:
It contains a call to _puts which is nothing but a “junk code”. This routine basically loads a byte from 0040E000[index] and performs simple XOR one-byte decryption (CB byte). Next it performs offset calculation and stores the resulting decrypted byte back into its place and increments index variable. It continues these operations in the loop until the whole data block is decrypted. The data block size is 15060 bytes – as pointed at 00401243. It starts at 0040E000 and ends at 00411AD4 (0040E000 + 00003AD4):
Next, the EAX register is loaded with a static address 00411323 (beginning of the previously decrypted code) and the code performs CALL EAX.
At this point we switched over to dynamic analysis.
The new code starts with a big stack allocation (later on this) and PEB (Program Environment Block) traversal using direct access to FS:[30h] (on Windows systems FS maps to a Thread Information Block – TIB). Then it resolves the full pathname and performs some sanity checks by comparing single bytes with specific offsets in the path:
If one of the bytes is found in the pathname then the code jumps to the exit routine located at 004113C0 which terminates the process. Several instructions later we can spot another decryption routine. First EBX register gets loaded with a beginning of previously allocated stack memory, next it gets populated with a data from 004113E1 which is encrypted with a simple one-byte XOR (0x6F). After this a CALL EAX (where EAX holds address of decrypted code) instruction is performed:
The decrypted code starts with a recreation of strings in the memory by storing single bytes directly in the allocated stack space to reconstruct a list of API calls to resolve later. The first one is GetConsoleAlias:
Next, the code retrieves a base address of kernel32.dll by traversing PEB structure and it’s InLoadOrderModuleList linked list to resolve exported functions. It is a common task to hide API calls from IAT and resolve them during the runtime:
After obtaining address of GetProcAddress() by calculating necessary offset the code tries to resolve following API calls:
After this the code tries to resolve encrypted code hidden in the resources section. It looks for resource type 13 with the size greater then 0x3E8:
The code decrypts newly acquired data using 3 different XOR keys as shown below following with a CALL GS:[EAX] instruction. On 32bit Windows, GS register is not saved in the execution context – when the OS switches from an application to another, the content of GS is lost. It’s usually used as an anti-emulating or an anti-stepping:
By patching JMP GS:[EAX] instruction with JMP DS:[EAX] instruction it is possible to continue the dynamic analysis of the program.
The code resolves several API calls by recreating strings in the memory:
After this step was take the code tries to unpack another code chunk into the newly allocated memory (here it’s 00930000 but it can be different on other machines):
Follows with the above sequence with a simple single-byte XOR (0×71):
After this that several sanity checks are performed (to check if the executable was properly decrypted). Then some interesting chunk of code occurs which implements a technique called RunPE.
RunPE is a technique often used by a virus authors to hide their viruses from an AV scanner. It works by using a small launcher application (here – a copy of the dropper itself) that has the executable virus file embedded in an encrypted state. Then RunPE loader replaces its loaded process image with the decrypted virus body:
- 1. RunPE loader launches a copy of the dropper in the CREATE_SUSPENDED state using CreateProcessA API. This will suspend the process right after it is mapped into the memory, but before the Windows PE loader loads all additional libraries.
- 2. Next, the RunPE loader calls GetThreadContext to retrieve all register values.
- 3. The loader calls ZwUnmapViewOfSection to free memory within the process namespace.
- 4. Then the loader reads the virus body and maps all the headers and all sections into the innocent process using WriteProcessMemory (with correct memory pages permissions).
- 5. The loader writes the new base address into the PEB and calls SetThreadContext to point EAX to the new EP.
- 6. Finally, the loader resumes the main thread of the target process with ResumeThread and the Windows PE loader will do it’s magic. The executable is mapped into the memory without ever touching a disk.
In Part 2 we will show more parts of the dropper, the used staging domains and commands of the c&c. In Part 3 the downloaded Trojaner will be documented.
Curesec Research Team is part of Curesec GmbH, find us here: curesec.com