Shellcode Obfuscation — Hiding Payloads from Static Detection

Why Shellcode Needs Obfuscation

Antivirus products and EDRs perform static analysis of files and memory buffers looking for signatures — known byte sequences that identify malicious code. A Meterpreter or Cobalt Strike Beacon shellcode has highly recognizable byte patterns that any modern AV detects immediately.

Shellcode obfuscation has two goals: evading static detection (signatures in files or memory) and making reverse engineering analysis harder.

┌──────────────────────────────────────────────────────────────────────┐
│              Static Detection vs. Obfuscated Shellcode               │
│                                                                      │
│  Raw shellcode:                                                      │
│  FC 48 83 E4 F0 E8 C0 00 00 00 41 51 41 50 52 51 56 48 31 D2...    │
│  ↳ Windows Defender detects in < 1 second                           │
│                                                                      │
│  XOR shellcode with key 0x41:                                       │
│  BD 09 C2 A5 B1 A9 81 41 41 41 00 10 00 11 13 10 17 09 70 93...    │
│  ↳ Static signature doesn't match                                   │
│                                                                      │
│  At runtime, decodes and executes — AMSI and EDR can still          │
│  detect via memory scan and behavioral analysis.                     │
└──────────────────────────────────────────────────────────────────────┘

Technique 1: Simple XOR Cipher

The most basic and widely known method. Each byte of the shellcode is XOR'd with a key.

Limitation: XOR with a static key is trivially detectable. Null bytes in shellcode (common in addresses) produce the key itself in plain text, enabling detection.


Technique 2: Rolling XOR Key

A variant that uses the previously decoded byte as part of the next byte's key, making analysis significantly harder:


Technique 3: UUID Encoding

A more creative technique that represents shellcode as a list of UUIDs (Universally Unique Identifiers). UUIDs are strings that appear benign and that security tools don't typically scan the same way as arbitrary byte sequences.


Technique 4: MAC/IPv4 Address Encoding

Similar to UUID, but using network address representations — even more "innocent" looking:


Technique 5: Sleep-Based Deobfuscation and Timing Evasion

Automated analysis sandboxes have limited execution time (typically 2-3 minutes). If the loader "sleeps" before decoding the shellcode, the sandbox may time out without executing the payload.

However, modern sandboxes simulate accelerated time. More sophisticated techniques measure real elapsed time via operations that cannot be simulated:


Technique 6: Environment-Derived Key

The payload can only be decoded in the specific target environment, using local information as the key:


Technique 7: Shellcode in PE Resources

Store the shellcode as a PE resource (.rsrc) with apparently legitimate content (icon, bitmap, localization string) and decode it at runtime:


Technique Comparison


References

  • Sektor7, "Malware Development: Intermediate — Payload Obfuscation" — sektor7.net

  • NCC Group, "Shellcode Obfuscation" — nccgroup.com (2021)

  • theXcellerator, "Shellcode Encoding Techniques" — thexcellerator.github.io

  • ired.team, "Shellcode Encryption and Obfuscation" — ired.team/offensive-security/defense-evasion/

  • VX-API, "Shellcode Collection and Encoding" — github.com/vxunderground/VX-API

  • MDSec, "Bypassing AV with Shellcode Encoding" — mdsec.co.uk (2021)

  • Solomon Sklash, "Malware Techniques: UUID Shellcode Execution" — solomonsklash.io (2021)

Last updated