Configuration d’une balise Cobalt Strike : ce qu’elle révèle
Extraire statiquement la configuration d’une balise Cobalt Strike et transformer chaque champ — C2, sleep, pipes, spawn-to, watermark, clé publique — en piste.
En bref. Une balise (beacon) Cobalt Strike embarque toute sa configuration dans le binaire : où elle se connecte, à quelle fréquence, comment elle se cache, dans quel processus elle s’injecte. La décoder statiquement transforme un échantillon en une liste de recherches concrètes dans les journaux du proxy, la télémétrie EDR et sur les autres postes. Le PE Parser la décode dans le navigateur et l’affiche dans un onglet Config.
Pourquoi la configuration compte
Quand une balise apparaît pendant une investigation, le binaire est la partie la moins intéressante : c’est un implant générique. Ce qui en fait cette intrusion, c’est la configuration choisie par l’opérateur — domaines C2, URI, user-agent, canaux nommés, processus utilisé pour les tâches de post-exploitation. Chacune de ces valeurs se recherche ailleurs, et aucune n’exige d’exécuter l’échantillon.
Où se trouve la configuration
La balise stocke ses réglages dans une table d’entrées numérotées (type, longueur, valeur), encodée par un XOR d’un seul octet : 0x69 dans les anciennes versions, 0x2e en 4.x. Les chargeurs ajoutent souvent une couche — la DLL de la balise encodée par XOR avec une clé de quatre octets dans un stager, ou compressée dans un overlay. Le PE Parser cherche la table dans le fichier lui-même, dans les couches qu’il dépaquette (UPX) et dans les exécutables qu’il extrait du fichier : la configuration est trouvée où que soit la balise.
Les petits stagers sont différents : ils ne contiennent pas la balise, seulement le shellcode qui la télécharge. Pour eux, l’outil indique le type de stager (reverse_http, reverse_https, reverse_tcp) et ce qu’il peut lire dans le shellcode : hôte, port, URI et user-agent.
Lire les champs
| Champ | Signification | Où chercher |
|---|---|---|
| Type de balise | HTTP, HTTPS, DNS, SMB (canal nommé) ou TCP | Quels journaux examiner en premier |
| Serveurs C2 | Noms d’hôte et URI contactés | Journaux proxy, DNS, pare-feu ; DNS passif |
| Port | Port de l’écouteur C2 | Pare-feu et netflow |
| Sleep / jitter | Intervalle de rappel et sa variation aléatoire | Détection de beaconing dans les journaux réseau |
| User-agent, URI POST | Allure des requêtes | Journaux proxy, souvent très distinctifs |
| Nom du pipe | Canal nommé des balises SMB et des tâches post-ex | Événements de canaux nommés sur les postes (par exemple Sysmon 17 et 18) |
| Spawn to (x86 / x64) | Processus lancé pour la post-exploitation | Créations de processus : ce processus sans argument, lancé par un parent inhabituel |
| Watermark | Nombre lié à la licence qui a généré la balise | Regrouper des échantillons entre incidents |
| Clé publique (SHA-256) | Empreinte de la clé du team server | Regrouper les balises servies par le même team server |
Quelques remarques pratiques :
- Le processus spawn-to est l’une des meilleures recherches côté poste. Par défaut c’est
rundll32.exe; unrundll32.exelancé sans DLL en argument est rarement légitime. - Sleep et jitter décrivent le beaconing sur le réseau : un sleep de 60 secondes avec 20 % de jitter donne un rappel toutes les 48 à 72 secondes.
- Le watermark relie les échantillons générés depuis une même installation. Les copies fuitées et crackées partagent quelques valeurs courantes : un watermark identique est une piste, pas une attribution.
- L’empreinte de la clé publique est souvent une meilleure clé de regroupement que le watermark : les balises générées par le même team server la partagent.
L’extraire avec le PE Parser
- Déposez le fichier (ou un ZIP de la collecte) sur le PE Parser. Rien n’est envoyé ni exécuté.
- Si une configuration est trouvée, le fichier reçoit un indicateur de sévérité haute, Configuration malveillante décodée, et un onglet Config apparaît.
- L’onglet liste d’abord les entrées C2, puis chaque réglage décodé, avec l’offset où se trouve la table — cliquez-le pour ouvrir la vue hexadécimale sur ces octets.
- L’onglet IOC reprend les URL et noms d’hôte C2, le user-agent et le nom du pipe, prêts à exporter en CSV, en événement MISP ou en bundle STIX 2.1 (exporter les IOC).
Le même onglet gère quelques autres familles dont la configuration se lit statiquement : AsyncRAT et ses dérivés (DcRat, VenomRAT), QuasarRAT, njRAT et Remcos.
Limites
- Chargeurs packés ou chiffrés. Si la balise est enveloppée dans un crypter maison, la configuration n’apparaît qu’une fois cette couche retirée, en général dynamiquement en bac à sable. UPX et les couches simples (XOR, compression) sont gérés ; les crypters maison non.
- Évolution du format. Le format a changé selon les versions et les générateurs peuvent être modifiés. L’extracteur vérifie strictement la structure de la table pour ne pas inventer de champs ; une version inhabituelle peut simplement ne pas être décodée.
- Leurres. Les opérateurs laissent parfois des valeurs trompeuses (faux hôtes, watermark cracké). Confirmez avec des preuves réseau avant d’agir sur un seul champ.
- Pas une preuve de malveillance en soi. Les red teams utilisent Cobalt Strike légitimement. Une configuration décodée dit ce qu’est le binaire, pas qui l’a lancé — vérifiez auprès de votre red team avant d’escalader.