FalconFriday — Process Injection revisited — 0xFF0F

In this edition of FalconFriday, we are going to revisit process injection techniques. We’ve covered process injection in a previous blog post; this one is an extension to cover other process injection techniques.

TL;DR for blue teams: The two rules in this blog provide you with (indicators of) process injection techniques that are not natively detected by Defender for Endpoint.

TL;DR for red teams: We’re trying to push you to start using more obscure process injection techniques. Injections with QueueUserApcand explicitly allocating memory in remote processes are being detected by these two rules.

In the previous FalconFriday on process injection, we covered process injection using CreateRemoteThread. This blog post covers other techniques.


I know a significant number of red teams that still use the “early bird” or “early bird special” injections, which basically rely on the QueueUserApc(or the internal NtQueueApcThread). Also other injection techniques — not being dubbed “early bird” — using this API are fairly common. And unfortunately, they’re not being detected by Defender for Endpoint as process injection. This rule is fairly accurate and allows you to detect suspicious processes using this API. We leverage Defender’s awesome FileProfile function to achieve this.

The DeviceEvents table captures all uses of QueueUserApcagainst remote processes. Hence we can leverage this to look for suspicious use. The only thing left to do is to filter out all false positives. The FileProfile functions allow us to do this very cleanly. We first categorize our potential true positives.

  1. For initial foothold, the most common trick is to use an MS Office macro. So we want to see all injections coming from MS Office. Luckily, MS Office practically doesn’t natively use the QueueUserApc API. So we can easily include these in our results.
  2. If it’s not coming from MS Office, it could be that the persistence is through some kind of .exe. We assume that the global prevalence of such a C2 executable, which is at the start of any process injection chain, is fairly low (i.e. <1000 on global scale).

So if we filter out all calls to QueueUserApc which originate from an executable with a low global prevalence or from an MS Office application, we can easily catch those two cases. You can find the query here.

Red: Obviously, this leaves some blind spots. The process injection could be coming from:

  1. A DLL started by Rundll32.
  2. A DLL which is hijacked, running inside a trusted process.
  3. A COM object which lives inside a trusted process, such as dllhost.exe.
  4. Using AppInit_DLL to load your malicious DLL inside a trusted process.
  5. Use shims to load your malicious DLL inside a trusted process.

Trick 1 is obviously easily detected by most EDRs and there are a large number of rules to detect Rundll32 misuse. However, trick 2 and 3 are fairly neat and I haven’t seen them being used very often. Although abusing dllhost.exe as target to inject into is very common, making dllhost.exe run a malicious COM object which injects into other processes is way more unique.


Another, less stealthy, trick for process injection is the use of VirtualAllocEx and the whole family of functions which perform similar tasks, allocating memory in another process. Although this is not equal to process injection, it is often an indicator of potentially malicious activity. This rule can be used stand-alone for alerting, but if it is generating too much noise you can use it as signal to further improve your detection accuracy of malicious process injections.

The approach is the same as before. We try to identify remote memory allocations and filter out false positives based on global prevalence of the executing executable. Since the approach of this rule is very similar to the previous one, there isn’t much else to add from a blue/detection perspective.

Grab a copy of the rule here.

Red: Bypassing this rule as a red teamer is easier than than the previous one. There are other ways of writing into other processes memory space without explicitly allocating memory with this API. You can find a nice overview in the BlackHat 19 presentation of Amit Klein: https://i.blackhat.com/USA-19/Thursday/us-19-Kotler-Process-Injection-Techniques-Gotta-Catch-Them-All.pdf

Closing words

If you’re interested in learning to build such detection rules: we’re offering an advanced detection engineering training for Windows during Black Hat USA 21. Check out the details here: https://www.blackhat.com/us-21/training/schedule/#advanced-detection-engineering-for-windows-22048.

Knowledge center

Other articles

BloodHound — Calculating AD metrics 0x02

BloodHound — Calculating AD metrics 0x02

[dsm_breadcrumbs show_home_icon="off" separator_icon="K||divi||400" admin_label="Supreme Breadcrumbs" _builder_version="4.18.0" _module_preset="default" items_font="||||||||" items_text_color="rgba(255,255,255,0.6)" custom_css_main_element="color:...

BloodHound — Calculating AD metrics 0x01

BloodHound — Calculating AD metrics 0x01

[dsm_breadcrumbs show_home_icon="off" separator_icon="K||divi||400" admin_label="Supreme Breadcrumbs" _builder_version="4.18.0" _module_preset="default" items_font="||||||||" items_text_color="rgba(255,255,255,0.6)" custom_css_main_element="color:...

Together. Secure. Today.

Stay in the loop and sign up to our newsletter

FalconForce realizes ambitions by working closely with its customers in a methodical manner, improving their security in the digital domain.

Energieweg 3
3542 DZ Utrecht
The Netherlands

FalconForce B.V.
[email protected]
(+31) 85 044 93 34

KVK 76682307
BTW NL860745314B01