object.title
Registre privé Docker : s'attaquer au cycle de développement d'une application

Cet article est un retour sur la conférence présentée par Geoffrey SAUVAGEOT-BERTLAND au Hack 2024[1], abordant les vulnérabilités potentielles liées à l'utilisation d'un registre privé Docker mal sécurisé.

Un registre privé Docker permet aux entreprises de gérer et de stocker leurs images Docker de manière centralisée, souvent pour des raisons de confidentialité ou de personnalisation. Cependant, l'absence de sécurisation adéquate, souvent due à une configuration par défaut, peut exposer ces registres à des attaques ciblées.

Pourquoi utiliser un registre privé Docker ?

Un registre privé Docker offre un contrôle total sur la gestion des images d'applications, notamment pour des environnements de développement, de test et de production. Contrairement au registre public Docker Hub, les images hébergées en privé peuvent inclure des composants sensibles ou des configurations spécifiques. Cela permet également de respecter des exigences de conformité en matière de sécurité et de confidentialité des données.

Cependant, une mauvaise configuration de ces registres peut exposer des systèmes sensibles à des attaques. Il est crucial de comprendre les risques et les techniques d'attaque pour anticiper et sécuriser correctement ces environnements.

Cet article couvrira deux scénarios d'attaque :

  1. Le vol et la revue d'une image Docker privée.
  2. La modification d'une image pour compromettre la supply chain.

Vol et revue d'une image

Identification d'un registre Docker privé vulnérable

La première étape pour mener une attaque est d'identifier un registre Docker privé vulnérable. Un outil simple et efficace pour cette tâche est Nmap, un scanner réseau utilisé pour découvrir des services en cours d'exécution sur une machine cible. En lançant un scan, il devient possible de détecter un registre Docker sur un serveur mal configuré :

nmap -p- -sV <ip_server>

  • L'argument -p- permet de scanner l'ensemble des ports d'une machine.
  • L'option -sV permet d'identifier les versions des services en cours d'exécution sur les ports ouverts. Cela facilite l'identification du port du registre Docker.

Une fois le registre localisé, il devient possible d'exploiter sa configuration si celui-ci est accessible sans authentification (accès anonyme).

Récupération de l'image

Une première action possible pourra être de réaliser une requête sur l'URL suivante :

http://<ip_registre>:<port>/v2/_catalog

Cette simple vérification permet d'obtenir deux informations cruciales :

  1. Accès anonyme : Si le serveur renvoie un code HTTP 200, cela confirme que le registre est ouvert et accessible sans authentification. L'attaquant peut alors procéder à une récupération des images.
  2. Liste des images : La réponse inclut une liste de toutes les images hébergées, offrant un aperçu de ce qui peut être téléchargé et étudié.

Une fois cette liste obtenue, les images peuvent donc être téléchargées via une simple commande docker pull :

docker pull <image_name>

Revue de l'image

Une fois le téléchargement effectué, l'image peut être exécutée dans un conteneur afin d'examiner son contenu. En se connectant directement à son shell via la commande suivante :

docker run -it <image_docker> sh

Cela permet d'accéder à tous les composants inclus dans l'image, notamment le code source des applications. Ce code peut contenir des informations sensibles comme :

  • Des clés API.
  • Des jetons d'accès.
  • Des variables d'environnement ou des fichiers .env contenant des identifiants et mots de passe.

Cette étape d'investigation peut s'avérer particulièrement critique, car elle offre la possibilité de récupérer des informations confidentielles qui peuvent ensuite être utilisées pour attaquer d'autres systèmes connectés à l'application.


Modification d'une image

Amplification de l'attaque via la supply chain

Les conséquences d'une attaque de vol d'image peuvent être amplifiées en ciblant directement la supply chain. L'idée est de compromettre une image, puis de la réinjecter dans le registre sans que personne ne s'en aperçoive. Cela peut se faire en ajoutant, par exemple, une backdoor à l'image compromise.

Une fois modifiée, l'image est renvoyée sur le registre avec le même tag et la même version que l'image originale. Cela remplace discrètement l'image légitime, sans déclencher d'alerte immédiate.

Les répercussions d'une telle attaque sont potentiellement graves :

  • Toute personne ou système téléchargeant l'image corrompue peut être compromis.
  • Des environnements de production peuvent être infectés, créant des vulnérabilités dans des infrastructures critiques.

Création de la backdoor

Lors de la présentation, une image web a été utilisée comme exemple. L'outil Weevely a été employé pour générer une backdoor simple à intégrer à l'image :

weevely generate 123456 backdoor.php

Cette commande génère un fichier backdoor.php, qui peut ensuite être utilisé pour créer un webshell semi-interactif. Ce webshell est accessible avec le mot de passe 123456, offrant à l'attaquant un accès distant discret.

Ajout de la backdoor dans l'image

Pour intégrer la backdoor dans l'image, un fichier Dockerfile est nécessaire. Celui-ci contient les instructions de modification de l'image Docker originale :

  1. FROM : Utiliser l'image d'origine comme base.
  2. COPY : Copier le fichier backdoor.php dans le répertoire /var/www/html ou un autre emplacement adapté.
  3. RUN : Installer l'utilitaire sudo pour permettre une élévation de privilèges via le webshell.
  4. RUN : Changer le mot de passe de l'utilisateur www-data.
  5. RUN : Ajouter l'utilisateur www-data au groupe sudo.

Une fois les modifications effectuées, l'image peut être construite et renvoyée sur le registre en utilisant la commande suivante :

docker build -t <image_tag>:<version>

docker push <image_tag>:<version>

Si aucune version n'est spécifiée, le tag latest est utilisé par défaut.

Déploiement automatique et surveillance

Dans certains environnements, une application de déploiement automatique, telle que watchtower, peut être utilisée pour surveiller et déployer automatiquement les nouvelles versions des images. Cela présente un risque supplémentaire, car les images compromises peuvent être déployées sans vérification manuelle préalable, amplifiant ainsi la portée de l'attaque.

Dans un tel cas, l'image modifiée sera immédiatement mise en production après son déploiement sur le registre.

Exploitation

Une fois l'image modifiée déployée sur une machine cible, il est possible d'exploiter la backdoor en accédant au webshell via la commande suivante :

weevely http://<ip_server>/backdoor.php 123456

L'ajout de l'utilisateur www-data au groupe sudo permet une élévation de privilèges, offrant ainsi un contrôle complet du conteneur pour effectuer d'autres actions malveillantes.


Remédiations possibles

Afin d'éviter de telles attaques, les mesures de sécurité suivantes peuvent, par exemple, être mises en place :

Utilisation de politiques d'image

Il est essentiel de mettre en place des politiques strictes d'admission pour les images Docker dans les environnements Kubernetes. Des outils comme Kyverno ou OPA (Open Policy Agent) peuvent être utilisés pour définir des règles empêchant le déploiement d'images ne respectant pas les normes de sécurité. De plus, l'utilisation de scanners de vulnérabilités tels que Trivy ou Anchore permet d'analyser les images avant leur déploiement afin de s'assurer qu'elles ne contiennent aucune faille connue susceptible de compromettre les systèmes.

Utilisation d'images Docker minimales

Pour réduire la surface d'attaque, il est recommandé de privilégier des images Docker minimales. L'utilisation d'images légères, comme Alpine, permet de limiter les composants superflus et, par conséquent, les vulnérabilités. Il est également important de supprimer tous les paquets et composants non indispensables dans les images, afin de réduire le nombre de dépendances vulnérables. Moins une image contient de logiciels inutiles, moins elle présente de risques pour la sécurité.

Sécurisation des certificats TLS

La protection des communications avec le registre Docker est cruciale. La mise en place d'une politique de rotation régulière des certificats et des clés de signature permet de réduire la période pendant laquelle un certificat ou une clé compromise pourrait être exploité. L'utilisation d'un gestionnaire de certificats comme Let's Encrypt peut faciliter l'automatisation de la gestion et du renouvellement des certificats TLS, renforçant ainsi la sécurité des infrastructures.

Segmentation réseau

Une segmentation réseau efficace est indispensable pour limiter l'exposition des registres Docker. Il est recommandé de configurer des pares-feux et des listes de contrôle d'accès (ACL) afin de filtrer et limiter les accès aux registres. En outre, la séparation des réseaux de développement, de production et de gestion des registres Docker contribue à réduire les mouvements latéraux en cas de compromission, tout en protégeant les environnements critiques.

Signature des images Docker

Pour garantir l'intégrité des images Docker, il est conseillé de mettre en place un processus de signature numérique. La signature des images permet de s'assurer qu'elles n'ont pas été modifiées ou corrompues avant leur déploiement. Des outils comme Docker Content Trust (DCT) ou Notary sont adaptés pour signer et vérifier les images Docker. De plus, il est important de configurer les pipelines CI/CD de manière à n'accepter que des images signées, garantissant ainsi que seules des images sûres et validées sont utilisées dans les environnements de production.


Conclusion

En conclusion, cette présentation effectuée par Geoffrey SAUVAGEOT-BERTLAND au Hack 2024, m'a montré à quel point un registre Docker mal sécurisé peut constituer une porte d'entrée pour des attaques. Cependant, elle m'a aussi permis de voir qu'en prenant des mesures proactives pour sécuriser l'infrastructure et en adoptant des pratiques de sécurité robustes, nous pouvons réduire considérablement les risques associés à l'utilisation des registres Docker privés.


[1] Vous pouvez consulter la rediffusion de la conférence : https://youtu.be/f8t-z0M9C-k?si=UN4_nK12ZQ0JDIoD


Gaspard LUNETTA
Consultant DevSecOps