Recently, our team was discussing some defender capabilities. One excellent tool is Sysmon from Sysinternals. This tool allows you to collect detailed information on processes, network connections, and several other artifacts. Check out these resources for additional detail.
One of the events that is collected by Sysmon is explained as follows.
Event ID 8: CreateRemoteThread
“The CreateRemoteThread event detects when a process creates a thread in another process. This technique is used by malware to inject code and hide in other processes. The event indicates the source and target process. It gives information on the code that will be run in the new thread: StartAddress, StartModule and StartFunction. Note that StartModule and StartFunction fields are inferred, they might be empty if the starting address is outside loaded modules or known exported functions.” -Sysmon Documentation
This can be seen in a event like this:
There are some really solid indicators here, including the base address of our shellcode.
So, the next question we had was to see if we could avoid these types of alerts and still accomplish our action on objective. The answer is yes, yes you can ;-) !
First some background on a function called QueueUserAPC. This actually allows us to execute a block of shellcode by attaching it to the APC Queue. Every Asynchronous Procedure Call (APC) waiting to execute resides in a thread-specific, kernel-managed queue and every thread in the system contains two APC queues, one for user-mode APCs and another for kernel-mode APCs.
For additional background on this tactic, see Practical Malware Analysis: The Hands-On Guide to Dissecting Malicious Software.
In this example, I’m taking a departure from the normal approach and combining something like process hollowing and thread hijacking. First, we will create a process in the suspended state and copy our shellcode into that child process. Next, we will call QueueUserAPC to attach our shellcode to a thread queue, so it executes when we resume.
Example code here.
You can invoke this as either a standalone exe or from InstallUtil.exe. Also, here is an example using MSBuild.exe.
Most everything is pretty standard. Here is where the interesting code is.
So, there you have it. This is one way that attackers might attempt to circumvent your CreateRemoteThread log collection. No more meddling Sysmon Event ID 8 alerts *grin*.
That is all I have today.