Skip to content

13. Fun with Shellcode(loaders) by Jean Maes

Jean Maes

Analysts investigate attack surfaces and defenses concerning 13. Fun with Shellcode(loaders) by Jean Maes.

Summary

### Overview In this presentation at ZEVcon, SANS instructor Jean Maes presents an educational narrative tracing the journey of a novice penetration tester, "Jimmy the Skid Johnson," transitioning into red teaming. Through Jimmy's iterative failures and discoveries, the talk explores why out-of-the-box payloads fail against modern defenses and explains the foundational concepts behind shellcode loaders, payload delivery strategies, language selection, and operational security (opsec) hygiene.

### Key Topics - **Static vs. Dynamic Detections**: Antivirus and EDR solutions rely heavily on static signatures—described conceptually as glorified regular expressions targeting known bad strings or byte patterns—as well as dynamic detection mechanisms like userland hooks on API calls to inspect execution flow and parameters. - **The Evolution from Executables to Shellcode**: Moving from raw MSFVenom binaries to PowerShell download cradles encounters controls like the Anti-Malware Scan Interface (AMSI). To counter static signature matching, operators leverage position-independent shellcode wrapped in custom loaders, using techniques such as string hashing modification (e.g., altering ROR13) or instruction substitution (e.g., replacing Cobalt Strike's initial `push r10; pop r10` 4-byte sequence with equivalent NOP operations via LLM assistance). - **Staged vs. Stageless Trade-offs**: Staged payloads offer small stubs suitable for small code caves, but exposing stagers publicly creates severe opsec risks. Unprotected staging servers (illustrated via a real-world case by Rob Fuller) get scanned and downloaded by automated threat intelligence bots and sandboxes, burning infrastructure and leading to domain categorization blocks by enterprise web proxies. Conversely, stageless payloads embed full functionality, though they increase binary size and can cause issues like lengthy C compilation times. - **Runner Language Considerations**: Choice of language impacts opsec, scrutiny, and control. Managed languages running on the Common Language Runtime (CLR) like PowerShell, C#, and VBA face automatic AMSI and Event Tracing for Windows (ETW) inspection and are easy to decompile. Low-level languages like C and C++ afford granular memory management (e.g., `VirtualAlloc`, `WriteProcessMemory`) and avoid CLR scrutiny, but require manual error handling to prevent crashes. Non-native languages like Python lack default Windows interpreters, while Go produces large binaries.

### Technical Details - **Decoupled Architecture**: Maes advocates for a hybrid model: hosting an encrypted stageless payload on an adequately protected staging server with redirection rules, and fetching it into memory via Windows networking APIs such as `WinINet` or `WinHTTP`. - **Execution and Persistence Techniques**: The runner can execute in-process (e.g., `CreateThread`, threadless execution, callback functions cataloged by resources like rop-gadget) or target remote processes (e.g., classic injection, APC queuing, process hollowing, thread hijacking, early bird injection). For persistence, Maes recommends decoupling the trigger from operator actions, favoring stealthy on-disk artifacts like COM or DLL hijacking that wait patiently for normal user activity (e.g., opening Teams or OneDrive). - **Advanced Evasion Tradecraft**: Modern tradecraft focuses on userland hook evasion and call stack inspection, including indirect syscalls, stack spoofing, hardware breakpoints, and tools such as SysWhispers or Call Stack Smasher.

### Takeaways & Opsec Tips - **Strip Debug Symbols**: Failing to strip debug symbols often leaks compilation file paths containing the developer's username directly into the binary. - **Clone Metadata and Timestomp**: Legitimate binaries contain rich version and company metadata. Custom binaries should clone authentic metadata and modify file creation timestamps (timestomping) to blend in with surrounding files on disk. - **Know Your Tools**: Operators must inspect proof-of-concept code rather than blindly running it, understand what artifacts or Sysmon telemetry (such as Sysmon Event ID 1) they generate, avoid obvious exported function names like `runme` or `malware`, and recognize how blue teams analyze decompiled payloads.

Related talks