$npx -y skills add SnailSploit/Claude-Red --skill offensive-shellcodeShellcode development reference for offensive security engagements. Use when writing custom x86/x64 shellcode, implementing position-independent code (PIC), building shellcode loaders, evading AV/EDR detection, or converting PE files to shellcode. Covers null byte avoidance, API
| 1 | ## Shellcode Development Workflow |
| 2 | |
| 3 | 1. Define concept and target platform (x86/x64, Windows/Linux/macOS) |
| 4 | 2. Write assembly using position-independent techniques |
| 5 | 3. Extract binary and test in controlled environment |
| 6 | 4. Apply null byte avoidance and optimizations |
| 7 | 5. Encode/encrypt to evade static detection |
| 8 | 6. Package with loader and choose delivery method |
| 9 | |
| 10 | --- |
| 11 | |
| 12 | ## Basic Concepts |
| 13 | |
| 14 | ### Execution Pattern (Allocate-Write-Execute) |
| 15 | |
| 16 | Avoid direct `PAGE_EXECUTE_READWRITE` — prefer: |
| 17 | 1. Allocate with `PAGE_READWRITE` |
| 18 | 2. Write shellcode to allocated region |
| 19 | 3. Call `VirtualProtect` to switch to `PAGE_EXECUTE_READ` |
| 20 | |
| 21 | ```c |
| 22 | char *dest = VirtualAlloc(NULL, 0x1234, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); |
| 23 | memcpy(dest, shellcode, 0x1234); |
| 24 | VirtualProtect(dest, 0x1234, PAGE_EXECUTE_READ, &old); |
| 25 | ((void(*)())dest)(); |
| 26 | ``` |
| 27 | |
| 28 | ### Position-Independent Code (PIC) Techniques |
| 29 | |
| 30 | | Method | Platform | Notes | |
| 31 | |--------|----------|-------| |
| 32 | | Call/Pop | Windows | Push next addr, pop into register | |
| 33 | | FPU state | Windows | `fstenv` saves instruction pointer | |
| 34 | | SEH | Windows | Exception handler stores EIP | |
| 35 | | GOT | Linux | Global Offset Table | |
| 36 | | VDSO | Linux | Kernel-provided shared object | |
| 37 | |
| 38 | --- |
| 39 | |
| 40 | ## Windows API Resolution (PEB Walk) |
| 41 | |
| 42 | Identifying `kernel32.dll` without imports: |
| 43 | |
| 44 | 1. Get `PEB` via `gs:[0x60]` (x64) or `fs:[0x30]` (x86) |
| 45 | 2. Walk `PEB->Ldr.InMemoryOrderModuleList` — order: exe → ntdll → kernel32 |
| 46 | 3. Hash-compare module names to locate `kernel32` |
| 47 | 4. Parse the Export Address Table (EAT) |
| 48 | 5. Find `GetProcAddress` by name hash, then resolve `LoadLibraryA` |
| 49 | 6. Use `LoadLibraryA` to load `WS2_32.dll`, resolve Winsock functions |
| 50 | |
| 51 | **WinDbg helpers for debugging PEB walk:** |
| 52 | ```bash |
| 53 | dt nt!_TEB -y ProcessEnvironmentBlock @$teb |
| 54 | dt nt!_PEB -y Ldr <peb_addr> |
| 55 | dt -r _PEB_LDR_DATA <ldr_addr> |
| 56 | dt _LDR_DATA_TABLE_ENTRY (<init_flink_addr> - 0x10) |
| 57 | lm m kernel32 # verify base address |
| 58 | r @r8 # check register |
| 59 | ``` |
| 60 | |
| 61 | --- |
| 62 | |
| 63 | ## Shellcode Loaders |
| 64 | |
| 65 | ### Loader Responsibilities |
| 66 | |
| 67 | - Environment verification / keying (sandbox detection) |
| 68 | - Shellcode decryption |
| 69 | - Safe memory allocation and injection |
| 70 | - Ends its duties after injecting |
| 71 | |
| 72 | **Recommended languages:** Zig (small, no runtime), Rust (secure), Nim, Go (watch for runtime signatures) |
| 73 | |
| 74 | ### Allocation Phase |
| 75 | |
| 76 | Avoid `RWX` allocations — use two-step: |
| 77 | - `VirtualAllocEx` / `NtAllocateVirtualMemory` — allocate `RW` |
| 78 | - `ZwCreateSection` + `NtMapViewOfSection` — alternative approach |
| 79 | - After writing: `VirtualProtectEx` to switch to `RX` |
| 80 | |
| 81 | **Other options:** code caves, stack/heap (with DEP disabled) |
| 82 | |
| 83 | ### Write Phase |
| 84 | |
| 85 | - `WriteProcessMemory` / `NtWriteVirtualMemory` |
| 86 | - `memcpy` to mapped section |
| 87 | |
| 88 | **Evasion tips:** |
| 89 | - Prepend shellcode with dummy opcodes |
| 90 | - Split into chunks, write in randomized order |
| 91 | - Add delays between writes |
| 92 | |
| 93 | ### Execute Phase |
| 94 | |
| 95 | Most scrutinized step — EDR checks thread start address against image-backed memory: |
| 96 | |
| 97 | | Technique | Notes | |
| 98 | |-----------|-------| |
| 99 | | `CreateRemoteThread` / `ZwCreateThreadEx` | Loud, heavily monitored | |
| 100 | | `NtSetContextThread` | Hijack suspended thread | |
| 101 | | `NtQueueApcThreadEx` | APC injection | |
| 102 | | API trampolines | Overwrite function prologue | |
| 103 | | ThreadlessInject | No new threads created | |
| 104 | |
| 105 | **Indirect execution resources:** |
| 106 | - [FlavorTown](https://github.com/Wra7h/FlavorTown) |
| 107 | - [AlternativeShellcodeExec](https://github.com/aahmad097/AlternativeShellcodeExec) |
| 108 | - [ThreadlessInject](https://github.com/epi052/ThreadlessInject) |
| 109 | |
| 110 | --- |
| 111 | |
| 112 | ## PE-to-Shellcode Conversion |
| 113 | |
| 114 | | Tool | Purpose | |
| 115 | |------|---------| |
| 116 | | [Donut](https://github.com/TheWover/donut) | EXE/DLL → shellcode | |
| 117 | | [sRDI](https://github.com/monoxgas/sRDI) | DLL → position-independent shellcode | |
| 118 | | [Pe2shc](https://github.com/hasherezade/pe_to_shellcode) | PE → shellcode | |
| 119 | | [Amber](https://github.com/EgeBalci/amber) | Reflective PE packer | |
| 120 | |
| 121 | **Open-source loaders:** |
| 122 | - [ScareCrow](https://github.com/optiv/ScareCrow) |
| 123 | - [NimPackt-v1](https://github.com/chvancooten/NimPackt-v1) |
| 124 | - [NullGate](https://github.com/specterops/NullGate) — indirect syscalls + junk-write sequencing |
| 125 | - [DripLoader](https://github.com/xuanxuan0/DripLoader) — chunked RW writes + direct syscalls + JMP trampoline |
| 126 | - [ProtectMyTooling](https://github.com/mgeeky/ProtectMyTooling) — chain multiple protections |
| 127 | - Direct-syscall helpers: SysWhispers3, FreshyCalls (now baseline requirements) |
| 128 | |
| 129 | --- |
| 130 | |
| 131 | ## Shellcode Storage & Hiding |
| 132 | |
| 133 | | Location | Risk | Notes | |
| 134 | |----------|------|-------| |
| 135 | | Hardcoded in `.text` | Medium | Requires recompile; stored `RW/RO` | |
| 136 | | PE Resources (`RCDATA`) | High | Most scanned by AV | |
| 137 | | Extra PE section | Medium |