FalconFriday — Evasive LOLBINs and burning the CACTUSTORCH — 0xFF04

We realized that the previous versions of FalconFriday were “too blue”. Starting from this part, we will cover each rule also from a Red perspective and provide some blind spots to abuse.

Today’s content

  • Hunting renamed LOLBINs that try to evade detection.
  • Detecting CACTUSTORCH and similar DotNetToJS techniques.

Evasive LOLBINs

Summary: Find LOLBIN abuse based on file hashes instead of filename. Two queries provided; one for all documented LOLBINs and another for specific LOLBIN.

Blue: LOLBINs can be an attacker’s friend when trying to stay off the radar in organizations with basic detection capabilities. More and more blue teams are catching up and are trying to detect LOLBINs with varying levels of success. Today’s query will help you detecting LOLBINs that are trying to evade detection by renaming. Of course, the sysmon blue teams are blessed with the OriginalFileName field, which gives you the filename straight from the PE header. But for the Microsoft Defender for Endpoint (MDfE?) users, the following trick will help you to find renamed LOLBINs.

First, list all the unique file hashes of the LOLBIN you’re looking for and then search for the LOLBINs based on file hash. There are roughly three approaches:

  1. Use the DeviceProcessEvents table to identify all earlier execution of the LOLBINs and summarize those into a unique list of file hashes. If you’re looking for DLLs, you can use DeviceImageLoadEvents in the same way.
  2. Use the DeviceFileEvents to identify read actions of the LOLBINs and summarize the LOLBINs that way.
  3. Use an external data source which contains all known hashes of your LOLBINs.

This technique is only as good as the list of unique hashes you can compile. Options 1 and 2 are fairly successful in large multi-national deployments of MDfE, since a large deployment provides sufficient coverage of various common versions. Options 3 is obviously the best from content perspective, but obtaining and maintaining such a database is not straightforward. One source you could use is Winbindex. But this data needs processing before it can be loaded into MDfE.

Once you have these hashes, the query is fairly straightforward and doesn’t need any more explanation.

Slightly trickier is a(n optimized) query to find active usage of all renamed LOLBINs. It requires some Kusto magic, which we’ve already performed for you.

Both queries are on this page on GitHub.

Note: that the query to find all LOLBINs is quite resource intensive. Running this query with a 7 day lookback gave me the warning that I was “using 18% of my organization’s allocated resources for 15 mins”.

Note2: Don’t run this query on Friday. It might ruin your weekend 😉

Red: We see two obvious ways to bypass this rule, both based on “bringing your own land”.

  1. Use an obscure version of your LOLBIN. Depending on your target environment, using greatly outdated or obscure language versions of the LOLBINs (if they’re not language neutral). For some, you might even get away with using Win 7 or Win 8 versions of the files.
  2. Modifying the binary to break the file hash. This obviously will also break the signature, but who cares? Most environments are not very picky on running unsigned code. And running an unsigned, unique binary is not going to trigger any rule if you avoid using very specific command-line parameters.


Summary: Detect current implementations of DotNetToJS/CACTUSTORCH by detecting the load of the .NET runtime into an unmanaged process, followed by the creation of a child process or a process injection.

Blue: This technique is “bootstrapping an arbitrary .NET assembly and class” from an unmanaged process. The trick to detect this, is to use the fundamental principles this technique is based on: loading the .NET runtime into an unmanaged process. While working on a way to figure out how this can be done, I realized that you need a two-staged approach.

Stage 1: we make a distinction between DotNetToJS inside and outside of an Office process. Office processes sometimes load the .NET runtime; I haven’t figured out why/when they do that. Based on my data set, this happens for approx. 2–3% of the Office processes. DotNetToJS outside of Office processes (mshta.exe, wscript.exe, cscript.exe) rarely load the .NET runtime, so we can use that as our main signal.

Stage 2: we need to refine our results to filter out the noise as much as possible. We do this by looking at the second stage, after the .NET runtime is loaded. Most malicious documents will either spawn a child process, or perform a process injection.

You would need 4 queries to cover this completely:

  1. Office process loads .NET and creates a child process
  2. Office process loads .NET and performs process injection
  3. Non-Office process loads .NET and creates child process
  4. Non-Office process loads .NET and performs process injection

To further increase the accuracy, we try to filter out benign child processes by first matching it against known LOLBINs from the LOLBAS project and then checking the “Global Prevalence” for all files that aren’t on the LOLBIN list.

We’ve implemented query 1 and 2. For 3 and 4, we have the basics of the query, but increasing the accuracy (stage 2) is left as an exercise to the reader ;-).

As usual, you can find these queries on this GitHub page.

Red: We see some bypasses for this rule — some more feasible than others. Some bypass ideas to ponder:

  1. Don’t spawn a child process, use a more advanced technique for process injection instead of using “CreateRemoteThread”.
  2. Use your private LOLBINs which aren’t in the rule.
  3. “Bring-your-own-land” and hide from the LOLBIN filter by dropping your own LOLBIN using a different filename.
  4. Place your JScript/HTA/VBS in a file/folder which is commonly whitelisted by blue teams to reduce noise.
  5. Social engineer your victim to open your maldoc via “File => Open” instead of double clicking it from Explorer/Outlook.


  • Don’t expect to copy-paste the queries in your environment and be done with it. We provide a foundational query which can detect a certain technique. You will need to fine-tune/extend the query to your organisation’s specifics to make it work in your environment and integrate into your monitoring solution.
  • The queries will be free to use in any way you like, although we appreciate a reference back to @falconforceteam Twitter / FalconForce GitHub.
  • Direct link to our FalconFriday Github page: https://github.com/FalconForceTeam/FalconFriday

Final words

Want to learn how you can develop detection content yourself? Create your own detection engineering pipeline? We built a training exactly for this purpose! 4 half-day sessions, starting on 9th of November. Sign up via https://www.falconforce.nl/en/training/

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