DarkComet Remote Administration/Access Tool (RAT) is an application that provides remote access and administration to remote systems. Typically, the creators of this RAT can determine its capabilities during the creation process. However, some of the common DarkComet capabilities include (and are not limited to) keylogging of system and keyboard events, accessing files on the affected system and provide a remote control. Please note that this blog post is not going to cover DarkComet and its capabilities as there are many online blog posts and whitepapers (like this one by Fidelis Security and Contextis) on this subject. Instead, this blog post will explain the process hollowing technique very briefly and then focus on how the DarkComet RAT leverages the process hollowing technique to inject a payload into a memory segment of a process. This blog post will also provide a step-by-step process for using different tools to discover a process hollowing technique while a process is running in memory. In addition, this blog post will also include step-by-step process for detecting process hollowing in a memory image taken from an affected system. Once you understood how malware leverages process hollowing to inject a payload in memory (and how to detect this technique), in principle, you should always be able to use these same steps during your analysis to detect other malware variants that use the same method of injection. Finally, this blog post will explain several Windows API calls typically used to achieve process hollowing.
In a nutshell, process hollowing technique is a code (like a payload or a Portable Executable (PE) file) injection technique in which this piece of code (typically malicious in nature) is injected into a legitimate process in the memory. This technique is used by attackers especially when they want their malware to execute on the target system while evading detection by security controls and investigators. The notion behind this idea is that since a legitimate process is injected with a malicious piece of code, in principle, a security control should not detect this process as malicious when executed on the system. After its execution on the system, this process is then injected with the malware using the process hollowing technique. There are several methods to accomplish this process but this blog post will mention one of these techniques which is based on a DarkComet variant I have used for this demonstration. These technique entails the following steps:
On execution, the malware creates a new specific process using the CreateProcess Windows API function. Typically that new process is the child process of the malware itself. The CreateProcess Windows API function is shown in figure 1, including the parameters it receives as input and output:
Figure 1: CreateProcess API Function
The lpApplicationName parameter is used to point to a specific module to be loaded by this Windows API call. For example, to start Internet Explorer as a process, the malware can put the full-path to the Internet explorer executable as the following C:\Program Files\Internet Explorer\iexplore.exe (and in fact, the variant of DarkComet in the blog post does start Internet Explorer as a process as you will see later on in this blog post) to launch as a process. The malware then puts that process in a suspended state with the CREATE_SUSPENDED flag adding this flag to the dwCreationFlags parameter. According to MSDN, “The primary thread of the new process is created in a suspended state, and does not run until the ResumeThread function is called”. As you will see in the following explanation the last API call is the ResumeThread API call. Please note, at this point, the process is only launched in a suspended state therefore, allowing the malware to perform its process hollowing technique before running the ResumeThread Windows API function.
In the next step the malware uses the Windows API function NtUnmapViewOfSection (similar to the ZwUnmapViewOfSection Windows API function. We will use this API function as an example in this blog post) to hollow out (or unmap) a legitimate section from the memory. Figure 2 shows two input parameters ingested by the ZwUnmapViewOfSection Windows API function:
Figure 2: ZwUnmapViewOfSection API Function
The ProcessHandle parameter get as an input an handle of a specific process and the BaseAddress parameter gets as an input the base address from memory of that process. On a side note, if you want to learn the difference between Nt and Zw Versions of the Native System Services Routines read more about it in here. The DarkComet variant in this blog post uses the NtUnmapViewofSection Windows API function to umap a section in memory of the Internet Explorer process by getting the handle of Internet Explorer using the GetCurrentProcess Windows API function. You will see more of this later on in this blog post.
The next step in this process hollowing injection is to allocate a section in memory for the new injected code by using the VirtualAllocEx Windows API function. For this process the malware must ensure the code is marked as writeable and executable using the flProtect parameter. The VirtualAllocEx Windows API function and its parameters is shown in Figure 3:
Figure 3: VirtualAllocEx API Function
Typically, when the flProtect parameter is set with the PAGE_EXECUTE_READWRITE flag, we can assume that this section may contain a malicious code. In the DarkComet use case it is true that the readwrite flag is related to a malicious behaviour. However, please keep in mind that some malware variants may simply modify this flag to a Read/Execute or Read-only state using the VirtualProtectEx Windows API function to prevent the detection of any readwrite sections.
The next step in the process hollowing technique is the use the WriteProcessMemory Windows API function to write the new code section over the original code section. The WriteProcessMemory Windows API function and its parameters is shown in Figure 4:
Figure 4: WriteProcessMemory API Function
The next step in this process is for the malware to adjusts the remote context to point to the new code section by using the SetThreadContext Windows API function. Finally, the malware use the ResumeThread Windows API function to resume the thread and run the suspended process (Once again, in this blog post the Internet Explorer process but this process could vary depending on the technique).
On a side note, the following github resource ProcessHollowing provides a very thorough detail including Windows C++ code for the process hollowing technique. If you are a C++ programmer, I would encourage to read more about this technique as it provides good explanation on that process.
Detecting Process Hollowing in DarkComet RAT
The tools I have used for this demonstration are freely available to download and are great for performing debugging and dynamic analysis of malware. These tools are:
- Sysinternal Process Explorer
- API Monitor v2
- Volatility Memory Forensics Tool
The DarkComet variant I have used as an example in this blog post can be found in VirusTotal.
Running Processes with Sysinternal Process Explorer
Prior to executing the DarkComet PE file, we can run the Process Explorer provide visibility to what other that process are running on the system during and after the DarkComet execution. In particular, to see what other processes are spawned by the DarkComet process during its execution on the affected system. When the DarkComet PE file is executed, we can see that it created a new child process of Internet Explorer (iexplore.exe) as shown in figure 5:
Figure 5: Parent/Child Process
This is a legitimate Internet Explorer process (belongs to legitimate Internet Explorer binary). Also, please note that the state of this process is silent and running in the background. Hence, not Internet Explorer interactive Window was opened on the affected system. Figure 5 also shows that the DarkComet PE file spawned the iexplore.exe process in a suspended state. As mentioned, the suspended state allow the DarkComet PE file to inject a malicious piece of code using the process hollowing technique before the suspended state resume back to normal.
Debugging Windows API calls using API Monitor v2
According to this tool developer, the API Monitor tool can be used to execute Windows applications and then monitor and control Windows API calls made by the applications. This tool is good for troubleshooting problems in an application and from our perspective this tool is also good for performing dynamic analysis and debugging of Windows API calls. That said, before running any PE file through the API monitor tool, you first have to select in the API filter section which Windows API calls (functions) you would like the API monitor tool to monitor during the execution of an application. To accomplish this, please use the API filter on the left pane once you executed this monitor API application. Figure 6 shows the API filter section:
Figure 6: API monitor – API filer
Before going forward, click on the binoculars icon and ensure that you search for and check the checkbox next to each one of the following Windows API calls:
- Under Kernel32.dll select the following Windows API functions:
- After you have selected this API function, you will also need to create a breakpoint. Therefore, make sure that you right click on this function then go to breakpoint –> and check the before call. You will see why this is essential for the analysis further in this blog post.
- Under Ntdll.dll select the following Windows API functions:
Once you have selected all the checkboxes for the Windows API calls above (including setting a breakpoint before running the WriteProcessMemory function), you can now run the DarkComet PE file by selecting monitor new process (under the monitored process in the middle pane) as shown in figure 7:
Figure 7: Monitoring New Process
Once the process started running, after a few seconds a new window should pop-up on the breakpoint you have set under the WriteProcessMemory API call. This window appears just before the first time the WriteProcessMemory API call is about to run by the DarkComet process. If you set the breakpoint properly, you should see a similar window like the one in figure 8:
Figure 8: Breakpoint before call
Please also note that the hex values in the value column under each parameter are different on each system this PE file is executed on. At this point, you have caused the DarkComet process to stop running the next WriteProcessMemory API function and injecting a buffer to the memory section. Now you can see that injected buffer by simply right click on the lpBuffer parameter (should be line number 3) and then in the menu just click on Edit Buffer. Figure 9 provide the steps to do it:
Figure 9: Edit the buffer
Now you should see another window showing the injected buffer section as shown in figure 10:
Figure 10: Injected buffer in memory
If you have done everything properly, you should see a similar hex and ascii values on your end (like those shown in figure 10). As you can see in figure 10, the DarkComet process attempts to inject a PE file (at least the magic hex values in the header 4D 5A tell us it is a Windows PE file) inside this buffer. Please note that you can use some other tools (like the HxD hex editor) to attach to this running DarkComet process in memory and then browse to the 0x7fe40010 address (on your computer this address will be different than the one shown here in this example). Then you can attempt and dump this section/block from memory to a new file and can proceed forward with your analysis of this malware (or any malware that uses this technique). Since this blog post attempts to explain process hollowing, this dump process is out of the explanation scope at this time.
After you have done analyzing each buffer section in each breakpoint (there should be two in total for this DarkComet variant) just click on the continue button in the breakpoint window to allow the API monitor to finish its monitoring process on the rest of the API calls done by this DarkComet process. Once the process is completed, you should see on the right pane a summary of all the Windows API calls you decided to monitor when this PE was running as a process. Therefore, you should see something similar to what is shown in figure 11:
Figure 11: API calls summary
In figure 11 you should notice some of the techniques that were mentioned during the process hollowing section (above). For example, you can see that the DarkComet variant started Internet Explorer in a suspended state using the CREATE_SUSPENDED flag. Then the NtUnmapViewOfSection API call was used to unmap a section in memory of the current process (Internet explorer processes). Then the DarkComet process used the VirtualAllocEx API call to allocate new READWRITE section in memory at the 0x0000018c section. Thereafter, the DarkComet process injected to this section two new buffers using the WriteProcessMemory API call. Finally, the SetThreadContext and NtResumseThread API calls completed this injection process and caused Internet Explorer to resume from the suspended state.
Discover Process Hollowing in Memory Dump using Volatility
Assuming you have dumped a memory from the system (you can use a tool like Dumpit to accomplish this) affected by this malware, you can also attempt to detect this process hollowing technique using to memory parsing tool Volatility with the HollowFind plug-in. Simply run the following command:
#vol.py --plugins=HollowFind -f memory_dump.dmp --profile=Win7SP0x86 hollowfind -p 2532
- The –plugin flag points to the HollowFind folder of that plugin.
- The -f flag points to the dumped memory file. The filename and extension vary depending on what you named the file when you dumped memory from the system.
- The –profile belongs to the Windows profile relative to the Windows OS you dumped memory from. In this blog post case, this system was Windows 7 SP0 32 BIT OS.
- The hollowfind is the flag of that plugin and should be used by default on your end.
- The -p flag only parses a process by its process ID. In our case that PID 2532 belongs to the Internet Explorer process. One you system obviously this process will have a different value.
If all went well on your end and you didn’t receive any error messages, you should be able to see similar output to the one shown in figure 12:
Figure 12: Memory Process Hollow Output
There are several things you can already see in figure 12. First and foremost, you can see that at the memory region 0x00400000 is the magic value of the injected PE file. In addition, under the suspicious memory regions section, you can see that at this address the protection value is set to the READWRITE value (also mentioned previously in this blog post). Please note that while using Volatility, you can also use other filters and other plugins to discover signs of evil in memory related to process hollowing and so on. However, I have used the hollowfind plugin just to show a glimpse on how you could find this technique in a memory image.
Please free free to provide any comment/feedback. Please don’t hesitate to contact me if you have any question or things you would like me to add or further explain related to this blog post.