Thursday, January 19, 2017

Shellcode Injection via QueueUserAPC - Hiding From Sysmon

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:

Screen Shot 2017-01-18 at 4.39.53 PM.png

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.[1]

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.

Screen Shot 2017-01-18 at 8.41.08 PM.png

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.

Screen Shot 2017-01-18 at 5.09.03 PM.png





  1. Hmmmm, interesting.

    I wonder if as a mitigation Sysmon can be configured to forward an Event 1 (process creation) where any process is started with CreateProcess with the CREATE_SUSPENDED flag? My understanding is that CREATE_SUSPENDED is not without legitimate use, but given its recently increasing popularity with malware authors it still might be worth making a point to be on the lookout for those events in many environments. (Depending on how much extra chaff vs. wheat you do actually wind up getting in your Sysmon logs, I guess.)

    1. You might be surprised how many legit processes create processes with CREATE_SUSPENDED flag. Even explorer.exe itself does that.

  2. Another way to create remote thread in win7 to bypass detection of sysmon was to use NtCreateThreadEx
    Does anybody tested in win10?