Analysis of “Heaven’s Gate” part 2
Beyond the “Heaven’s gate”
This article is a continuation of part 1. In part 1, I succeeded in extracting the 64-bit code executed by Heaven’s Gate. Analyzing this code, I found that it was injecting the code into the memory of the “svchost.exe” process created by the original code and resuming the thread. The extracted 64-bit code will fail this process.
There are two reasons:
- It isn’t known the handle of the process and thread to inject into “svchost.exe” created by the original 32-bit code.
- It refers to the decrypted malware payload in the memory of the original 32-bit code.
Perhaps it’s enough to know that what Heaven’s Gate does is injection and resume into the process. But I really wanted it to run and attach to the injected “svchost.exe”. As a result of trial and error, I succeeded in doing so.
This article describes the procedure.
Target malware hash value:
In order for the extracted 64-bit code to be successfully injected into “svchost.exe”, I needed to know:
- Handles of processes and threads of “svchost.exe” created and suspended by 32-bit code
- Data in memory referenced on 32-bit code(probably malicious code)
- Parameters passed when executing Heaven’s Gate
The 32-bit code is running on IDA just before Heaven’s Gate. Therefore, I can refer to the data in the memory of the 32-bit code.
As a result of analysis of 64-bit code, I found that parameters are passed by “rcx” from 32-bit code. The value of “rcx” was the address of the structure in memory of the 32-bit code. The structure contained the address for malicious code, size, and handles of the “svchost.exe” process and thread. I think this depends on the case. If you do the same analysis on different specimen, you need the skills to read this.
The following problems occur when executing with the extracted 64-bit code.
- The handle value of the structure in the 32-bit code cannot be used because the process is different.
- The 32-bit code memory cannot be referenced because the process is different.
I solved these in a very muddy way. The procedure is shown below.
Getting process handle
I thought the solution would be to “OpenHandle” on the extracted 64-bit code. This is a rudimentary knowledge of Windows programming. “OpenHandle” requires a process ID. I was able to find out with “ProcessHacker” tool(Figure 1).
In this case, “3656” is the process ID.
But is it possible to execute “Open Handle” that is not described in the program? I tried running the program in an adventurous way. The method is to search for Kernel32.dll, find “OpenHandle”, and execute it using the “Set IP” function. I have tried this violent method.
I went to the Kernel32.dll segment and selected “Search”-”Text Search” from the menu. I typed “Open Process” in the dialog and pressed “OK”(Figure 2).
I was able to discover “OpenProcess” in Kernel32.dll(Figure 3).
Let’s run this “OpenProcess”. “Set IP” moves the EIP to the “Open Process” address. “Open Process” requires arguments. The arguments should be examined on MSDN. The third parameter is the process ID. The decimal number “3656” is the hexadecimal number “0xE48”. Set the first argument to rcx, the second argument to rdx, and the third argument to r8. Don’t forget to move the stack pointer to a safe position(Figure 4).
Processes before the return. Then, 0x0000000000000088 is set in EAX(Figure 5). This value is the process handle for “svchost.exe” on this 64-bit code!
We were able to get the target process handle.
Getting thread handle
“OpenThread” can also be executed in the same way as “OpenProcess”. The thread ID could be found by referring to the properties of the “ProcessHacker” tool(Figure 6).
I found out that the thread ID is 5008. I searched for “OpenThread” in the same way as “OpenProcess”. The third parameter is the thread ID. The decimal number “5008” is the hexadecimal number “0x1390”. Then, use “Set IP” and execute it in the same way as “OpenProcess”(Figure 7).
Processes before the return. Then, 0x000000000000008C is included in EAX (Figure 8).
Reference of malicious code
The structure passed by “Heaven’s Gate” had the address and size of the malicious code. I needed to be able to reference this data in a 64-bit code. Dumping this memory data is easy because the structure contains the address and size on the 32-bit code. I saved it to a file in the same way as Pert 1. The extension was “.dmp”.
I tried to load this file. But it didn’t succeed. Because the “Load file” function must have a memory area on the process. Therefore, I had to provide a memory area on the process.
How to get memory area? I chose to use “VirtualAlloc”. The method is the same as “OpenProcess”.
I ran VirtualAlloc with a large enough memory area. Then, 0x0000000002410000 is included in EAX. I got a memory area to load the data.
Let’s load the binary file in the prepared area. We can load it by selecting “File”-”Load file”-”Additional binary file…” from the menu (Figure 11).
Select the file to load from the dialog (Figure 12). As parameters to note, set “Loading segument” to blank and “Loading offset” to the address obtained by VirtualAlloc.
The data load was successful. From the 64-bit code process, I could now refer to the data that was on the 32-bit code process.
Accurate execution of 64-bit code and attach to the code of the injected svchost.exe
I knew the required parameters and was able to load the data. I thought I could simulate the exact behavior of Heaven’s Gate’s 64-bit code by running in this condition. I set the stack pointer correctly and set the EIP to the starting position with “Set IP” (Figure 15). The correct starting position had to be obtained by analysis in advance.
I will only introduce the important points of the processing to be executed.
The first point is calling the “NtAllocateVirtualMemory” API. The malware tried to allocate a memory area on the “svchost.exe” process. The malware set the handle of the “svchost.exe” process in the first argument. Therefore, the allocated area was on the “svchost.exe” process (Figure 16).
There is one supplementary information. The 64-bit code process copied the contents of the 32-bit code structure before this process. That means that the address and size of the malicious code, and process and thread handles for “svchost.exe” have been copied onto the stack. Overwrite these parameters with the address and size of the loaded data, and the results of OpenProcess and OpenThread. This makes it possible to analyze more smoothly.
The second point is calling the “NtWriteVirtualMemory” API. The malware set the handle of the “svchost.exe” process in the first argument. Therefore, the malicious code was copied to the memory area allocated on “svchost.exe” (Figure 17).
“NtWriteVirtualMemory” was executed twice. The first time, the payload of the malware loaded by “Load file” was copied. The second time, a small 16-byte code was copied (Figure 18). This second code was the code to jump to the first copied code when thread was resumed.
The third point is calling the “ResumeThread” API. Resuming the code injected into “svchost.exe” will execute the malicious payload (Figure 19). This could be the real process of malware. The malware set the handle of the “svchost.exe” thread obtained by “OpenThread” as the first argument.
Before running “ResumeThread”, I had to attach to the process “svchost.exe” in the debugger.I was able to easily attach using IDA. I started IDA and selected “Debugger”-”Attach”-”Local Windows debugger” (Figure 20). Then, I selected the target “svchost.exe” (note the process ID) (Figure 21).
I knew a suspicious address. It was the address where the code was copied by the second NtWriteVirtualMemory run. I knew from preliminary analysis that it was the code to jump to the malicious payload.
When I jumped to that address, I was able to find the code to jump to the malicious payload. I set a breakpoint at the beginning of the code (Figure 22).
It’s finally the last step. I ran “Resume Thread”. At this time, the attached process was paused. Processes attached by the debugger are automatically paused. I have resumed the attached process that was paused. Then, the process stopped at a breakpoint (Figure 23).
I was able to stand at the starting point of malicious code injected into “svchost.exe”. If We analyze this code with a debugger, we will understand many behaviors of malware.
I wanted to analyze how the 64-bit code executed by Heaven’s Gate launches malware. And I wanted to accurately attach to the malware by imitating that behavior. I used a very muddy method, but I was able to achieve my goal. Please note that a correct analysis must be done in advance for this method to be successful. This is not a smart method, but if it is useful for your analysis, please refer to it.