🛠️ IP2ROOT Partie 1 : Déploiement automatisé d'un C2 via Python et Docker SDK

Introduction
Durant cette série de trois articles nous mettrons en lumière différentes briques techniques de notre projet, ip2root.
Contexte
ip2root est un projet que nous menons au cours de notre 5ème annĂ©e du cycle IngĂ©nieur CyberdĂ©fense Ă l’ENSIBS. Les objectifs du projet sont les suivants :
- fournir aux Ă©quipes de pentest ou Red Team, un outil clĂ© en main permettant d’exploiter automatiquement des vulnĂ©rabilitĂ©s communes afin de gagner du temps
- A partir d’une adresse rĂ©seau ou une plage rĂ©seau fournie en entrĂ©e, l’outil retourne :
- un accès en ligne de commande (privilĂ©giĂ© si l’escalade de privilège a fonctionnĂ©) aux machines compromises
- un rapport d’exploitation, le tout sans aucune interaction de l’utilisateur
Le projet est open-source et disponible sur Github : https://github.com/ip2root/ip2root
Organisation
Les trois articles de cette série aborderont les thématiques suivantes :
- DĂ©ploiement automatisĂ© d’un
C2
(Serveur de commande et de contrĂ´le) viaPython
etDocker SDK
- Reconnaissance des services grâce aux outils
Nmap
ainsi queMasscan
et corrĂ©lation avec les exploits implĂ©mentĂ©s pour obtenir un accès intial - EnumĂ©rer les possibilitĂ©s d’Ă©lĂ©vation de privilèges sous
Linux
etWindows
avecPython
Command and Control (C2)
Glossaire
C2 : Une infrastructure Commande et ContrĂ´le, aussi appelĂ©e C2 ou C&C, est l’infrastructure utilisĂ©e par les attaquants pour maintenir la communication avec des appareils compromis, Ă la suite d’une première exploitation. (A noter que nous ne souhaitons pas aider les attaquants mais nous avons besoin de nous placer du cĂ´tĂ© offensif afin de dĂ©celer les failles d’un SI donnĂ©)
Stager : Une charge utile à executer sur la machine compromise afin que cette dernière puisse recevoir et exécuter les commandes du C2.
Listener : Outil permettant de recevoir des connexions sur un port donné.
Entrons dans le vif du sujet, comment avons-nous choisi notre C2 ? Comment avons-nous automatisé son déploiement ?
Besoins et objectifs du C2
L’outil Ă©tait initialement prĂ©vu pour gĂ©rer une seule adresse rĂ©seau et donc un seul accès en ligne de commande.
Nous sommes alors partis sur un simple listener
. Nous avons rapidement observé les limites de cette méthode :
- complexitĂ© d’envoi de fichiers
- complexité de gestion de plusieurs accès
- sujets Ă des bugs (mineurs)
En plus de ces problèmes, nous avons dĂ©cidĂ© de permettre Ă l’utilisateur de fournir une plage rĂ©seau en entrĂ©e. Il nous faut donc pouvoir gĂ©rer plusieurs accès en ligne de commande et ceci n’est pas possible avec un simple listener
. Pour ce faire, nous avons décidé de déployer un C2 permettant de gérer tous nos accès en ligne de commande.
Le C2 doit rĂ©pondre Ă ces besoins afin qu’il corresponde au projet :
- API exposée -> interagir facilement via notre outil
- Stagers compatibles linux et windows -> garder l’exhaustivitĂ© de notre outil
- Déployable via
Docker
-> simplifier l’utilisation de l’outil - Intuitif -> tous les utilisateurs de l’outil ne sont pas forcĂ©ment familiers avec les C2
Après avoir épluché les différentes offres présentes sur le marché, nous avons (notamment) le choix entre Covenant
et PS Empire
.
Nous choisissons PS Empire
car nous avons une (petite) expérience sur ce dernier.
Automatisation du déploiement
Il est maintenant l’heure de mettre les mains dans le cambouis.
La première Ă©tape est de vĂ©rifier si l’utilisateur ne possède pas dĂ©jĂ un C2 de dĂ©ployĂ© sur sa machine (dans le cas ou notre outil a dĂ©jĂ Ă©tĂ© utilisĂ© par ce dernier).
Nous commençons par importer la librairie docker
avec pip3 install docker
et import docker
dans notre code.
Dans notre code, nous pouvons désormais initialiser le client Docker
:
|
|
On itère dans la liste de ceux présents afin de chercher si un conteneur empire
existe déjà :
|
|
Et on le dĂ©marre s’il existe : start()
.
Si aucun conteneur Empire
n’existe, nous appelons la fonction permettant d’en dĂ©ployer un de zĂ©ro :
|
|
On crée et démarre le conteneur avec les paramètres souhaités :
- Image : bcsecurity/empire:latest
- Ports :
1337:1337
,5000:5000
et8888:8888
- Nom : empire
- Interactif : oui
- Détaché : oui
Ce qui nous donne en Python
avec Docker SDK
:
|
|
Une fois que nous avons un conteneur dĂ©ployĂ©, que ce soit parce qu’il l’Ă©tait dĂ©jĂ ou après l’avoir créé, il nous faut rĂ©cupĂ©rer le token permettant d’interagir avec l’API REST
.
Nous appelons la fonction permettant de récupérer le token de la sorte :
|
|
Dans la fonction associĂ©e, nous commençons par dĂ©finir l’endpoint de l’API
à joindre ainsi que les en-têtes de requête et paramètres à fournir :
|
|
Puis, nous récupérons le token dans la réponse de la requête POST
:
|
|
Maintenant que nous avons rĂ©cupĂ©rĂ© le token, nous pouvons communiquer plus en dĂ©tail avec l’API du C2.
Afin que le C2 soit opérationnel il nous reste deux tâches à effectuer :
- Créer un
listener
(permet de rĂ©cupĂ©rer l’accès dĂ©clenchĂ© par l’exploitation d’une vulnĂ©rabilitĂ©) - CrĂ©er une fonction permettant de gĂ©nĂ©rer un
stager
adapté (charge utile permettant de joindre le serveur de contrôle via lelistener
)
Pour la première tâche, comme prĂ©cĂ©demment, nous spĂ©cifions l’endpoint de l’API Ă joindre avec les paramètres requis pour la crĂ©ation d’un listener (nom et port et adresse rĂ©seau) :
|
|
Ici, notre listener
se nommera CLIHTTP
et sera disponible sur le port 8888
.
Pour la fonction permettant de générer les stagers, nous définissons les mêmes prérequis pour effectuer la requête sur notre C2 :
|
|
Le nom du stager
choisi ("StagerName":"{0}".format(system)
) est défini par le paramètre OS
entré dans le fichier de configuration de la vulnérabilité exploitée : soit multi/bash
pour un Linux, soit multi/launcher
pour un Windows.
On associe le stager
Ă notre listener
: CLIHTTP
.
On rĂ©cupère le payload et on l’encode en base64 afin de faciliter l’envoi du payload (retour Ă la ligne, caractères spĂ©ciaux, etc.) :
|
|
Une fois tout ceci fait, nous avons finalisĂ© le dĂ©ploiement automatique et transparent du C2 pour l’utilisateur.
Client
Pour administrer le C2 et commander les machines infectées qui sont inscrites dessus, il faut un client.
Nous utiliserons Starkiller
. Toujours dans l’optique de faciliter la vie de l’utilisateur, nous vĂ©rifions s’il existe dĂ©jĂ dans le rĂ©pertoire /tmp
de notre utilisateur, sinon, nous le téléchargeons depuis github:
|
|
Une fois qu’il est tĂ©lĂ©chargĂ©, nous appliquons les droits d’exĂ©cution sur le binaire puis nous le dĂ©marrons.
|
|
L’utilisateur n’a alors plus qu’Ă entrer ses identifiants pour administrer le C2 :

Conclusion
Pour conclure, nous avons pu mettre en oeuvre l’automatisation du dĂ©ploiement d’un C2 pour notre projet Ă l’aide de Python
, Docker SDK
et de PS Empire
. Cela permet de faciliter la vie de l’utilisateur et de lui faire gagner du temps lors d’audits de sĂ©curitĂ©.
Le code complet est disponible sur le Github du projet Ă l’adresse suivante : https://github.com/ip2root/ip2root/blob/dev/c2/c2.py
A noter que l’implĂ©mentation du C2 est encore en dĂ©veloppement et l’outil n’est pas encore complètement compatible avec. La version fonctionnelle de notre outil (sans le C2 pour l’instant) est disponible ici : https://github.com/ip2root/ip2root Le prochain article traitera de la partie Reconnaissance des services grâce aux outils
Nmap
etMasscan
et corrélation avec les exploits implémentés pour obtenir un accès intial avec les fichiers de configurationPython
Annexe
Code complet
|
|