Malware that steals banking credentials is still one of today’s most lucrative cybercrime schemes. It’s not unusual for a banking Trojan to evolve over the years, and Ramnit is a perfect example. It was active for several years until it was disrupted in early 2015 by Europol working with several tech companies. It resurfaced in late 2015, and again in mid-2016.
I was surprised by this behavior because the challenge for investigating malware usually lies in fetching the configuration from the C&C server. Typically, after the configuration is fetched, it is stored on the infected machine until an update is due. However, based on user data sent from the Trojan, the C&C server might decide not to fetch the configuration for a variety of reasons (for example, because it’s running on a virtual machine). In any case, it is unusual for the configuration to be fetched and then deleted.
Could this behavior of deleting the configuration mean that Ramnit is now adding more complexity to make it more difficult to detect during execution? Or, could this indicate a bug in the malware functionality?
Whatever the reason might be, I didn’t want to theorize before having complete data. I had to find a way to preserve the configuration data to continue my web inject research. Before I could do that, I had to understand the exact flow of the configuration data within the Ramnit processes and modules and find out which process was responsible for deleting the configuration.
During its execution, Ramnit creates and injects its modules into several processes:
I started by checking how the configuration finds its way to the browser’s memory. The module that is responsible for Ramnit’s webinject capability is hooker.dll. This module is originally injected into explorer.exe, and when the browser is launched, the module is propagated into the browser’s memory by copying its own code from explorer.exe’s memory.
The propagation method that hooker.dll uses is as follows:
Figure 1: The hooker.dll function responsible for hooking ZwResumeThread
Once hooker.dll is unpacked in the browser’s memory, it tries to map the configuration data into the browser’s memory from shared memory sections. This is done using a dedicated worker thread:
3. The Ramnit configuration consists of the following parts:
Each configuration part has its own shared memory section, which is named in the following format:
The worker thread continues its execution regardless of whether the configuration is present in the shared memory section. There is only one flow for both cases.
The only interaction the browser’s process has with the configuration data in the shared memory is a read operation. This led me to the conclusion that the browser process is not the one responsible for removing the configuration. So, I continued the search for another process that is responsible.
Even though the explorer.exe process is the one that I immediately suspected, a quick check revealed that it does not interact with shared memory, meaning it cannot be the process I was looking for.
Ramnit’s execution flow creates two svchost.exe processes:
Rmnsoft.dll uses pipe communication to relay C&C commands to modules.dll.
Inspecting the processing flow of data that modules.dll receives from the pipe communication reveal the actions that are taken by the module once receiving the configuration data:
2. Modules.dll encrypts (crc32+XOR) and writes the configuration into the shared memory. The configuration struct in the shared memory has the following fields:
So, now it is evident that mapping the configuration data into shared memory happens constantly following a pipe conversation between modules.dll and rmnsoft.dll, and it does not depend on a specific event occurring (such as opening of a browser). This allows Ramnit to constantly change and update its configuration from the C&C server.
But, despite the fact that the writing access to the shared memory occurs in modules.dll, while inspecting all of the writing occurrences within modules.dll, I found that the configuration was never deleted there.
So, I needed to inspect other modules that access the shared memory. The footprints once again lead to the “hooker.dll” module, but now it is an additional instance inside the svchost.exe process where modules.dll resides with other Ramnit modules.
During its communication with the C&C server, rmnsoft.dll receives additional modules and delivers them to modules.dll through the pipe communication. Then, modules.dll maps the received modules to the memory of the svchost.exe process.
Each module (vncinstall.dll, bond.dll, cookie.dll, hooker.dll, etc.) has its own field of responsibility that is activated by exported functions.
Modules.dll receives commands through the pipe and calls the exported functions accordingly.
During the inspection, I found that CommandRoutine, which is one of hooker.dll’s exported functions, tries to access the configuration in the shared memory mapping.
CommandRoutine receives a struct with command data and a handle to a pipe. In the flow that I inspected, CommandRoutine was called four times:
Finally, I had found the guilty function!
Example of the webinjects configuration removal routine:
So, the next time the browser tries to map a copy of the shared memory into its own memory (which holds the configuration), it receives the config struct which has a valid field structure, but with 2-byte data length instead of the original config length and without any configuration data:
Now the injection to the targeted web pages will not occur anymore. Mystery solved!
Figure 13 illustrates the complete configuration data flow within the Ramnit modules.
My main goal in this investigation was to preserve Ramnit’s configuration data so I could analyze it’s webinject content. Since the configuration was deleted from the memory I had to find out the exact flow that processes the removal and the reason for it. After investigating a number of Ramnit’s processes and finding the function responsible for removing the configuration, it was possible for me to bypass this flow and preserve the data.
It seems that the actual decision as to why to remove the configuration is done on the C&C server and not by a logic in Ramnit’s processes. It is definitely a conscious decision designed to make the malware more difficult to investigate, and not a bug in the malware’s functionality.
Sampled MD5: eeefe08b66f68b3ab10ca1c8ae3840cc
MODIFIED: Jul 06, 2017