Skip to content

0xROOTPLS/Cicada

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 

Repository files navigation

Cicada PIC Stager

For security research and educational purposes only.

Features

  • Position-Independent Code (PIC) - No relocations, runs from any memory address
  • HTTPS Stage Fetching - Retrieves stage via WinHTTP with certificate validation bypass (self signed OK)
  • Sleep Obfuscation - RC4 encrypts shellcode + heap + stack during sleep via encrypted timer chain
  • Timer-Based Execution - Stage executed via NtContinue context switching
  • Self-Destruction - Stager memory freed after stage handoff
  • No String Literals - All strings built on stack
  • PEB Walking - Dynamic API resolution without GetProcAddress imports

Execution Flow

┌─────────────────────────────────────────────────────────────────┐
│ 1. API RESOLUTION                                               │
│    PEB walk → kernel32 → LoadLibraryA                           │
│    Load: ntdll, advapi32, winhttp                               │
├─────────────────────────────────────────────────────────────────┤
│ 2. PROTECTED SLEEP (11-step encrypted timer chain)              │
│    Timer 0:  Decrypt timer chain body                           │
│    Timer 1:  VirtualProtect(RW)                                 │
│    Timer 2-4: RC4 encrypt shellcode, heap, stack                │
│    Timer 5:  WaitForSingleObject (sleep)                        │
│    Timer 6-8: RC4 decrypt stack, heap, shellcode                │
│    Timer 9:  VirtualProtect(RX)                                 │
│    Timer 10: SetEvent (wake)                                    │
├─────────────────────────────────────────────────────────────────┤
│ 3. FETCH STAGE                                                  │
│    WinHTTP GET /stage → raw shellcode bytes                     │
│    VirtualAlloc(RWX) → copy stage                               │
├─────────────────────────────────────────────────────────────────┤
│ 4. EXECUTE + ZERO                                               │
│    Timer 1 (T+0):    NtContinue → execute stage                 │
│    Timer 2 (T+100ms): VirtualFree(stager) → self-destruct       │
└─────────────────────────────────────────────────────────────────┘

Build Requirements

WSL or Linux with MinGW cross-compiler:

sudo apt install gcc-mingw-w64-x86-64 binutils

Building

# Compile to flat binary
x86_64-w64-mingw32-gcc-win32 -c payload.c -o payload.o \
    -Os -fPIC -nostdlib -nostartfiles -ffreestanding \
    -fno-asynchronous-unwind-tables -fno-ident \
    -fno-stack-protector -mno-stack-arg-probe -e start -s

# Link to raw shellcode (requires linker script)
ld -T linker.ld payload.o -o payload.bin

Linker script (linker.ld):

OUTPUT_FORMAT("binary");
SECTIONS {
    . = 0x00;
    .text : {
        *(.text)
        *(.func)
    }
}

Configuration

Edit payload.c before building:

Constant Location Description
INITIAL_SLEEP_MS Line ~490 Initial sleep delay (default: 300000ms)
server[] Line ~600 C2 server address (default: 127.0.0.1)
Port 443 WinHttpConnect call HTTPS port
/stage http_get_stage Stage endpoint path

Server Requirements

The stager expects:

  • HTTPS server on configured host:port
  • GET /stage returns raw shellcode bytes
  • Self-signed certificates accepted (validation bypassed)

Sleep Obfuscation Details

Timer chain data is split into two regions:

Region Contents During Sleep
Header (~1.3KB) Timer 0 CONTEXT, Key B, body descriptor Exposed
Body (~14KB) 10 ROP CONTEXTs, Key A, region descriptors Encrypted

Protected during sleep:

  • Shellcode (encrypted with Key A)
  • Heap (encrypted with Key A)
  • Stack (encrypted with Key A)
  • Timer chain body (encrypted with Key B)

Exposed during sleep:

  • Timer 0 CONTEXT (reveals: "call SystemFunction032 on body region")
  • Key B (chain decryption key, different from main Key A)

This minimizes exposure - an analyst sees only that something decrypts something, not the actual ROP chain, targets, or main encryption key.

Entry Point

int start(PVOID shellcode_base, DWORD shellcode_size);

The loader must pass:

  • shellcode_base - Address where stager is loaded (for self-reference during sleep encryption)
  • shellcode_size - Size of stager shellcode

Size

~5400 bytes (varies with compiler optimization)

References

About

Cicada is a position-independent Windows shellcode stager featuring sleep obfuscation and remote HTTPS staging

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages