This injection technique allows the injected code to run before the entry point of the main thread of the process, thereby allowing avoiding detection by anti-malware products’ hooks.
Code injection is commonly used by malware to evade detection by injecting a malicious code into a legitimate process, information security experts said. This way the legitimate process serves as camouflage so all anti-malware tools can see running is the legitimate process and thus obfuscates the malicious code execution.
Experts researched a code injection technique that appeared in malware samples at the Cyberbit malware research lab. It is a simple yet powerful code injection technique. Its stealth allows execution of malicious code before the entry point of the main thread of a process, hence – it can bypass security product hooks if they are not placed before the main thread has its execution resumed. But before the execution of the code of that thread, the APC executes.
The researchers saw this technique used by various malware. Among them, the “TurnedUp” backdoor written by APT33. The malware code injection flow works as follows:
- Create a suspended process (most likely to be a legitimate windows process)
- Allocate and write malicious code into that process
- Queue an asynchronous procedure call (APC) to that process
- Resume the main thread of the process to execute the APC
Hooks are code sections that are inserted by legitimate anti-malware products when a process starts running. They are placed on specific Windows API calls. The goal of the hooks is to monitor API calls with their parameters to find malicious calls or call patterns.
Synopsys of Technical Analysis of Early Bird Code Injection Technique
While information security professionals were analyzing samples at lab, they came across a very interesting malware sample (SHA256: 9173b5a1c2ca928dfa821fb1502470c7f13b66ac2a1638361fda141b4547b792)
It starts with the .net sample deobfuscating itself, then performing process hollowing and filling the hollowed process with a native Windows image. The native Windows image injects into the explorer.exe process. The payload inside explorer.exe creates a suspended process – svchost.exe and injects into it. The sample consists of three different injection methods (We consider process hollowing to be an injection technique as well). The SHA256 of the payload inside svchost.exe is c54b92a86c9051172954fd64573dd1b9a5e950d3ebc581d02c8213c01bd6bf14. As of 20 March 2018, this payload was signed by only 29 out of 62 anti-malware vendors.
While the process hollowing and the second injection into explorer.exe are trivial, the 3rd technique caught our attention. The professionals take a look at the debugger before the injection to svchost.exe happens.
At this point the malware creates a suspended svchost.exe process. Common legitimate Windows processes are among malwares’ favorite choices. svchost.exe is a Windows process designated to host services.
After creating the process, the malware allocates memory in it and writes a code in the allocated memory region. To execute this code, it calls NtQueueApcThread to queue an asynchronous procedure call (APC) on the main thread of svchost.exe. Next, it calls NtResumeThread to decrease the suspend count of that thread to zero, consequently the main thread of svchost.exe will resume execution; if this thread in alertable state, the APC will execute first.
When queuing an APC to a thread, the thread must be in an alertable state in order for that APC to execute. According to the Microsoft documentation:
“When a user-mode APC is queued, the thread to which it is queued is not directed to call the APC function unless it is in an alertable state. A thread enters an alertable state when it calls the SleepEx, SignalObjectAndWait, MsgWaitForMultipleObjectsEx, WaitForMultipleObjectsEx, or WaitForSingleObjectEx function”
But the thread has not even started its execution since the process was created in a suspended state.
To check this out, the information security experts patched the malware so it will inject to other processes of our choice and witnessed it also working with various other processes. The experts went further to research what is going on when a main thread is resumed after its process is created in a suspended state.
By putting a breakpoint on the call to NtQueueApcThread, we can see the APC address on svchost.exe is at 0x00062f5b. We attached a debugger to this process and put a breakpoint on that address. Here is what the svchost.exe process looks like at 0x000625fb (start address of the APC).
We first have to note that every user-mode thread begins its execution at the LdrInitializeThunk function. When the researchers look at the bottom of the call stack we see that LdrpInitialize, which is called from LdrInitializeThunk, was called. We trace into LdrpInitialize and see that it jumps to the function _LdrpInitialize. Inside _LdrpInitialize, we see a call to NtTestAlert which is a function responsible for checking if there is an APC queued to the current thread – if there is one – it notifies the kernel. Before returning to user-mode, the kernel prepares the user-mode thread to jump to KiUserApcDispatcher which will execute the malicious code in our case.
We can see evidence that this APC was executed by KiUserApcDispatcher, by looking at the call stack again, and see that the return address of 0x00062f5b is 0x76e36f9d – right after the call from KiUserApcDispatcher.
To sum it up, the execution flow that led to the execution of the APC is:
LdrInitializeThunk → LdrpInitialize → _LdrpInitialize → NtTestAlert → KiUserApcDispatcher
In the wild
This technique was seen in other samples in our lab (SHA 256):
The last two samples in this list are the most recent. These samples are the “TurnedUp” backdoor written by the Iranian hackers group APT33.
The APC is used to maintain persistence on the system. Now the information security experts can see where the APC starts (0x90000) inside rundll32.exe. Going just a bit further reveals that the malware will write a key to the Windows registry to maintain persistence by executing ShellExecuteA with cmd and a specific command (figure 11). The cmd command is:
“/c REG ADD HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run /v RESTART_STICKY_NOTESS /f /t REG_SZ /d \”C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\StikyNote.exe\””\
In this case, if a hook on ShellExecuteA was placed after the APC was called, this ‘Early Bird’ call and its parameters will sneak by before the hook, hence, failing to detect an important malware behavior.