🕵️ 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
|
|