
Framework C2 en assembly x64 sans fichier avec pivotement de protocole ICMP/DNS à double canal, exécution directe d'appels système et injection de processus basée sur ptrace pour une exécution furtive de commandes et une exfiltration de données.
________ ___ ___ ________ ________ _________ ________ ________
|\ ____\|\ \|\ \|\ __ \|\ ____\|\___ ___\ |\ ____\|\_____ \
\ \ \___| \ \ \\\ \ \ \|\ \ \ \___|\|___ \ \_| \ \ \___|\|____|\ \
\ \ \ __ \ \ __ \ \ \\\ \ \_____ \ \ \ \ \ \ \ ____\_\ \
\ \ \|\ \ \ \ \ \ \ \\\ \|____|\ \ \ \ \ \ \ \___|\____ \ \
\ \_______\ \__\ \__\ \_______\____\_\ \ \ \__\ \ \______\\_________\
\|_______|\|__|\|__|\|_______|\_________\ \|__| \|______\|_________|
\|_________|
Implant C2 sans fichier, purement en assembleur x64, utilisant une architecture à double canal (ICMP / DNS). Zéro libc. Zéro disque. Invisible pour les sondes EDR standards.
⭐️ Si vous trouvez cette recherche utile, merci de considérer lui donner une étoile pour soutenir son développement.
🚨 RECHERCHE TECHNIQUE COMPLÈTE & CODE SOURCE : Ce dépôt est un résumé. Pour la description architecturale complète, les détails d'évasion mémoire W^X et l'implémentation de la VTable, visitez la page officielle du projet : ICMP-Ghost Technical Breakdown
Ghost-C2 est un framework de commande et de contrôle entièrement écrit en assembleur x64 Linux pur, sans dépendance à libc. Chaque opération passe par des appels système directs. Il n'y a pas de tables d'import, pas d'artefacts de l'éditeur de liens dynamique et aucune écriture sur le disque.
Initialement construit comme un canal furtif brut ICMP, la version 3.6.2 introduit une architecture de pivotement de protocole à double canal. Les opérateurs peuvent basculer de manière transparente le canal de communication de l'implant entre les sockets brutes ICMP silencieuses et le tunneling UDP DNS furtif à la volée. L'implant réside exclusivement dans la RAM, injecté dans un processus système en cours via un chargeur personnalisé basé sur ptrace.
Ce projet a été développé pour explorer jusqu'où la furtivité en espace utilisateur et la synchronisation d'état réseau peuvent aller sans toucher au noyau.
┌─────────────────────────────────────────────────────────────┐
│ MACHINE OPÉRATEUR │
│ │
│ ┌──────────────┐ │
│ │ client.asm │ ← Terminal UI : Prompt IP/Domaine + Cmd │
│ │ (Console │ Chiffre la charge utile avec XOR │
│ │ Opérateur) │ rotatif │
│ │ │ Sync. état : mode ICMP / mode DNS │
│ └──────┬───────┘ │
│ │ │
└──────────┼──────────────────────────────────────────────────┘
│ Canal 1 : ICMP brut (Sans état, Sans port)
│ Canal 2 : DNS UDP Port 53 (Asymétrique)
┌──────────┼──────────────────────────────────────────────────┐
│ │ MACHINE CIBLE │
│ ▼ │
│ ┌──────────────┐ ┌─────────────────────────────────┐ │
│ │ loader.asm │────▶│ sniff.asm (PIC) │ │
│ │ (Chargeur │ │ Vit uniquement en RAM │ │
│ │ Fantôme) │ │ à l'intérieur d'un proc.│ │
│ └──────────────┘ └────────────────┬────────────────┘ │
│ │ │
│ 1. Scanne /proc pour le PID cible │ Écoute ICMP/DNS │
│ 2. ptrace ATTACH │ Valide Auth │
│ 3. Force mmap distant (RW) │ Déchiffre cmd │
│ 4. Injecte le shellcode PIC │ fork+execve │
│ 5. mprotect → RX │ memfd_create │
│ 6. Redirige RIP vers le shellcode │ Compresse (DPCM- │
│ 7. ptrace DETACH → se termine │ RLE) │
│ │ Chiffre & Fragm. │
│ │ Envoie Réponse │
└─────────────────────────────────────────┼───────────────────┘
│ Trafic Chiffré
▼
[ client.asm ]
Reçoit & Valide
Déchiffre Charge Utile
Décompresse (Hybride)
Réassemble & Affiche
client.asm — Console OpérateurLe terminal côté attaquant. Gère l'interface utilisateur, la gestion dynamique de la mémoire et la synchronisation de l'état de la cible. Peut envoyer des paquets sous forme de requêtes d'écho ICMP ou de requêtes DNS TXT. Écoute les réponses fragmentées, empêche les débordements de tampon et reconstruit la sortie. Dispose d'un module de "Reconnexion de cible active" pour récupérer des sessions orphelines.
sniff.asm — Agent Implant PICL'implant s'exécutant sur la cible. Compilé en binaire brut (indépendant de la position, sans en-têtes ELF) pour pouvoir être injecté dans des adresses mémoire arbitraires. Il met à jour dynamiquement sa VTable interne pour basculer entre l'écoute ICMP et la liaison UDP DNS en fonction des commandes de pivotement de l'opérateur.
Phantom_Loader/loader.asm — Moteur d'InjectionLe mécanisme de livraison. Scanne /proc, trouve un processus cible par son nom de comm, et injecte le shellcode PIC dans celui-ci via une machine d'état ptrace en plusieurs étapes. Se termine proprement après l'injection — ne laisse aucune trace.
Ghost-C2 v3.6.2 permet à l'opérateur de changer à chaud le protocole réseau sans perdre l'agent. En envoyant des commandes de pivotement spécifiques, les VTables du Maître et de l'Agent sont dynamiquement réécrites :
!D (Pivoter vers DNS) : Les deux nœuds ferment les sockets ICMP et initialisent la communication UDP sur le Port 53. Idéal pour contourner un filtrage strict de couche 3 en se fondant dans le trafic DNS d'entreprise.!I (Pivoter vers ICMP) : L'Agent ferme les sockets UDP, tue les liaisons de port et retourne en écoute silencieuse sur socket brute. Parfait pour le mode furtif "Fantôme".Le moteur de transmission de données de Ghost-C2 utilise une couche de compression et d'encodage hybride fortement optimisée en assembleur x86-64.
Chaque paquet ICMP sortant est structuré pour être indistinguable d'un ping Linux standard :
struct timeval.iputils Linux (0x10 à 0x1F) contourne les pare-feux heuristiques de base.Les deux directions sont chiffrées avec une clé QWORD qui se décale progressivement. Cela maintient une entropie de Shannon faible (contrairement à AES, qui obtient ~8.0 et déclenche des anomalies DPI). Le XOR rotatif produit une entropie qui ressemble à des données naturellement bruitées. Pas de constantes cryptographiques, pas de S-box, rien que YARA puisse reconnaître.
L'implant ignore tous les paquets ICMP où ID + SEQ ≠ 45 000. L'implant répond avec des paquets où ID + SEQ = 55 000. Cela évite les confusions d'écho OS et filtre les scanners internet ou les honeypots.
memfd_createLa sortie des commandes ne touche jamais le disque. La sortie du shell est capturée via un fichier RAM anonyme (memfd_create), nommé [shm] pour se fondre dans les mappages mémoire partagés légitimes de /proc/PID/fd.
Défait les mitigations modernes du noyau qui interdisent la mémoire RWX. Le chargeur utilise une approche en deux phases (Remote mmap avec RW → Injecte → Remote mprotect avec RX). Aucune page n'est jamais simultanément W et X.
Tous les numéros d'appels système sont répartis sur deux instructions pour déjouer l'analyse statique et les scanners simples basés sur grep.
Pour maintenir une OPSEC stricte, l'agent Ghost-C2 (sniff.asm) n'utilise pas de configurations externes. Vous devez définir votre IP Maître C2, votre Port et votre Domaine DNS leurre directement dans le code assembleur avant de compiler et d'injecter.
Ouvrez sniff.asm et descendez tout en bas du segment .text. (Remarque : comme l'agent est un code indépendant de la position (PIC) strict, il n'y a pas de segment .data. Toutes les variables de configuration sont stockées en ligne).
Modifiez les valeurs suivantes pour correspondre à votre Serveur Maître :
db 127, 0, 0, 1 par l'IP de votre Maître.dw 0xB414 (Port 5300) par votre port souhaité en ordre d'octets réseau (ex. 0x3500 pour le Port 53).nasm -f bin sniff.asm -o shellcode.bin
python3 -c "data = open('shellcode.bin', 'rb').read(); lines = ['\tdb ' + ', '.join(f'0x{b:02x}' for b in data[i:i+12]) for i in range(0, len(data), 12)]; open('c2_payload.txt', 'w').write('\n'.join(lines))"
c2_payload.txt généré.xor.py et remplacez le contenu de la variable raw_asm par votre shellcode copié.python3 xor.py et copiez la sortie chiffrée.loader.asm.c2_payload:.target db "cron", 10).nasm -f elf64 loader.asm -o loader.o
ld loader.o -o loader
Exécutez sur la machine cible avec les privilèges root (sudo ./loader). L'agent s'exécute désormais entièrement sans fichier.
Avant de compiler la Console Maître, vous devez vous assurer que ses profils d'écoute et de cible correspondent à la configuration de votre Agent. Ouvrez client.asm et accédez à la section .data.
Localisez master_bind_addr. C'est ici que le Maître écoute les balises DNS entrantes.
Port UDP : Remplacez dw 0xB414 par le port sur lequel votre Agent envoie.
Remarque : Celui-ci doit être en ordre d'octets réseau. Pour le Port 53, utilisez
0x3500.
Localisez target_addr. Ce port est utilisé lorsque vous effectuez un Pivotement DNS (!D) ou utilisez le module de Reconnexion.
Alignement du Port : Remplacez dw 0xB414 par le port UDP sur lequel l'Agent écoute. Si ces ports ne correspondent pas, un (Deadlock) se produira car le Maître enverra dans le vide.
Une fois configurée, assemblez et liez le Maître :
nasm -f elf64 client.asm -o client.o
ld client.o -o client
Astuce : Gardez toujours une "Fiche de Profil" pour votre opération. Si vous changez le port en 0x3500 (Port 53) dans sniff.asm, vous DEVEZ mettre à jour à la fois master_bind_addr et target_addr dans client.asm avant le début de l'opération.
Remarque : La Console Opérateur nécessite les privilèges root pour lier les sockets brutes et le port UDP 53.
Pour garantir un accès persistant et éviter la perte de session, pivotez toujours l'Agent vers le mode ICMP (!I) avant de terminer votre session Console Maître.
La Logique : ICMP est le "Canal d'Or" de Ghost-C2 — il est sans état, passif et toujours accessible via l'IP cible.
Le Risque : Le mode DNS repose sur une synchronisation dynamique de port UDP. Si la Console Maître est fermée alors qu'elle est en mode DNS, l'Agent reste "piégé" dans un état d'écoute UDP. Rétablir la connexion nécessiterait de connaître le port éphémère spécifique de l'Agent, qui est perdu lors du redémarrage du Maître.
Testé dans un environnement de laboratoire contrôlé contre une inspection de trafic active :
| Test | Résultat |
|---|---|
| Suricata v8.0.3 (règles Emerging Threats) | ✅ Contourné |
| Suricata v8.0.3 (règles personnalisées de charge utile ICMP) | ✅ Contourné |
| Passerelle DigitalOcean FRA1 | ✅ Exfiltration réussie à 100 % |
| Alertes générées lors de l'exfiltration d'environ 25 Ko | 0 |
Ghost-C2 interagit directement avec le noyau Linux :
mprotectL'absence de PTY est une décision architecturale, pas une limitation :
/dev/ptmx et des appels ioctl que les EDR surveillent intensément.Ghost-C2 est un implant d'exécution de commandes et d'exfiltration hyper-furtif. L'interactivité échange l'invisibilité contre la commodité — ce projet a choisi l'invisibilité.
Par conception, les Pull Requests et les Forks sont strictement ignorés. L'architecture de ce projet est maintenue directement par l'auteur. Si vous trouvez un bogue, une faille logique ou avez une suggestion de fonctionnalité, veuillez ouvrir une Issue. Restez objectif et technique.
Ghost-C2 est construit avec passion, sueur et pur assembleur x64. Si ce projet vous a aidé à comprendre l'évasion bas niveau, le mimétisme de protocole, ou a simplement facilité vos opérations d'équipe rouge, envisagez de soutenir le développement !
Ghost-C2 est développé strictement à des fins éducatives, de rétro-ingénierie et de recherche en cybersécurité autorisée.
À partir de la version 3.6.1 et ultérieures, ce projet est sous licence GNU Affero General Public License v3.0 (AGPLv3). Toute entité interagissant avec ou modifiant ce logiciel sur un réseau doit divulguer son code source complet comme l'exige la licence. L'exploitation commerciale ou l'intégration dans des plateformes propriétaires/à source fermée est strictement interdite.
Copyright (c) 2026 JM00NJ (commSync). Tous droits réservés.
L'auteur n'est pas responsable de toute utilisation illégale ou de tout dommage causé par cet outil. Utilisez-le à vos propres risques.
| Appel système | Numéro | Utilisation |
|---|
sys_socket | 41 | Création de socket brute ICMP / UDP |
sys_recvfrom | 45 | Capture passive de paquets ICMP/UDP |
sys_sendto | 44 | Transmission de réponse ICMP/UDP |
sys_bind | 49 | Liaison du port UDP DNS |
sys_memfd_create | 319 | Fichier RAM anonyme pour la sortie |
sys_dup2 | 33 | Redirection stdout/stderr |
sys_execve | 59 | Exécution de commande shell |
sys_fork | 57 | Isolation de processus |
sys_ptrace | 101 | Injection de processus + anti-débogage |
sys_getdents64 | 217 | Analyse du répertoire /proc |
sys_mmap | 9 | Allocation mémoire distante |
sys_mprotect | 10 | Commutation de permissions W^X |