Comment j’ai piraté des conteneurs Docker en exploitant des vulnérabilités d’ImageMagick
11 mars 2021
0 minutes de lectureEt si je vous disais que l’utilisation d’images Docker vulnérables vous expose à un risque important et imminent de faille d’injection de commandes, permettant de pirater les conteneurs Docker qui les utilisent ?
Dans cet article, je vous guide pas à pas dans le piratage d’un conteneur, en exploitant une application web basée sur Node.js qui utilise une image Docker de base officielle pour Node.js, mais vulnérable.
Piratage d’un conteneur à partir d’une image Node.js vulnérable
Pour illustrer cette vulnérabilité, je vais utiliser une ancienne version du runtime Node.js avec une application Fastify qui redimensionne des images. Le redimensionnement consiste à déléguer le traitement à la bibliothèque ImageMagick, qui propose le pratique outil en ligne de commande convert.
ImageMagick est un ensemble de liaisons pour langages de programmation et d’outils en ligne de commande couramment utilisés dans les applications web pour traiter des images : conversion d’un format à un autre, redimensionnement, recadrage, etc.
Malheureusement, ImageMagick a présenté au fil des ans de nombreuses vulnérabilités de sécurité, dont la célèbre faille ImageTragick (CVE-2016-3714). Cette faille est classée comme une validation incorrecte des entrées, mais des exploits de preuve de concept circulent depuis 2016 et peuvent entraîner une injection de commandes à distance.
Cette histoire montre comment des conteneurs peuvent être piratés, non pas en raison du non-respect des bonnes pratiques de sécurité ou de dépendances vulnérables des applications Node.js, mais à cause de composants open source tiers qui peuvent être présents dans une application Node.js basée sur Docker.
L’application Node.js
Commençons par l’image Docker qui regroupe l’application Node.js. Pour simplifier, je vais utiliser une configuration Dockerfile très légère :
Notez que ce Dockerfile ne respecte pas les recommandations de sécurité pour la création d’images Docker et qu’il est présenté ainsi uniquement par souci de concision. Consultez notre aide-mémoire sur les 10 bonnes pratiques pour conteneuriser des applications web Node.js avec Docker pour connaître les bonnes pratiques de sécurité.
L’application web Fastify expose une route **/**upload qui accepte le téléversement de fichiers et exécute le processus /usr/bin/convert avec l’image envoyée pour la convertir à la taille demandée, puis redirige l’utilisateur vers une page de confirmation.
Le code utilise bien une API Node.js sécurisée pour exécuter le processus, sans concaténer de chaînes.
Est-ce une bonne pratique de lancer des shells système et d’exécuter des processus ? Pas vraiment, du moins sans bonne raison. Si ce processus de travail Node.js traite des messages d’une file d’attente ou reçoit des tâches d’un ordonnanceur, ce cas d’usage est probablement pertinent.
Mais qui sommes-nous pour juger, quand un cas d’usage similaire a été présenté en direct lors de Google I/O 2017 ?

Piratons un conteneur Docker
J’ai commencé par importer le projet dans Snyk, qui détecte automatiquement les fichiers manifeste pris en charge ; dans mon cas, il s’agit du package.json et du Dockerfile de l’application.
Comme vous pouvez le constater, même la dernière version de l’image Node.js 6 (node:6-stretch) contient par défaut 866 vulnérabilités de sécurité. Heureusement, nous utilisons Snyk, qui nous recommande plusieurs autres images de base pouvant améliorer la sécurité de l’application de deux façons au moins :
un nombre réduit de vulnérabilités, ce qui diminue la surface d’attaque ;
des images de base dans lesquelles le runtime Node.js lui-même n’est pas vulnérable. Un avantage majeur, souvent négligé, des recommandations d’images de base.

Transformons la faille ImageTragick présente dans la version d’ImageMagick de l’image du conteneur en attaque par injection de commandes à distance.
L’exploit s’appuie sur des fichiers image spécialement conçus pour contourner la fonction d’analyse des délégués de la bibliothèque ImageMagick. Cette fonctionnalité exécute des commandes système associées aux instructions présentes dans le fichier image. En sortant du contexte d’entrée attendu, un attaquant peut injecter des commandes système.
Ce dépôt Git contient un exploit de preuve de concept permettant l’exécution de commandes à distance, avec le téléchargement de netcat pour obtenir un shell inversé sur les distributions qui n’incluent pas netcat par défaut (comme Debian wheezy).
Voici à quoi ressemble la charge utile de preuve de concept dans le fichier image rce1.jpg :
Le fichier image est ici contrôlé par l’utilisateur. Un attaquant malveillant pourrait donc créer cette charge utile, qui exécute une commande prise en charge par les systèmes d’exploitation de type UNIX pour créer un fichier vide — ici, touch rce1.
Une fois l’image du conteneur créée, nous pouvons l’exécuter :
Notre application web toute simple nous permet de téléverser un fichier :

Lorsque nous cliquons sur le bouton Resize pour traiter le fichier rce1.jpg, l’injection de commandes se déclenche.
Connectons-nous à l’application exécutée dans le conteneur Docker pour vérifier cette attaque. Comme vous pouvez le constater, un nouveau fichier nommé rce1.jpg a été créé dans le répertoire racine de l’application Node.js :

En résumé : le piratage de conteneurs
Je suis sûr que le nombre de vulnérabilités de sécurité présentes dans diverses images Docker ne vous étonne pas outre mesure. Nous non plus, puisque nous avons constaté que les 10 images Docker les plus populaires sur Docker Hub contenaient des vulnérabilités, comme le montre notre rapport State of Open Source Security.

L’attaque présentée ici contourne complètement toutes les conventions de codage sécurisé et va au-delà de la sécurité du runtime Node.js ou des dépendances des modules open source Node.js intégrées à l’application. Elle souligne à quel point il est nécessaire de sécuriser vos images Docker. C’est précisément pour cela que Snyk a été créé !
En mettant en évidence les vulnérabilités par ordre de priorité, Snyk vous propose des conseils de correction sous la forme d’autres images de base vers lesquelles vous pouvez migrer :

Si vous souhaitez reproduire l’attaque étape par étape, suivez les instructions du README dans le dépôt open source, qui explique également comment réaliser une attaque par shell inversé à distance à partir de cette vulnérabilité ImageTragick.
Et ensuite ?
Que les dépôts de votre projet d’application conteneurisée avec Docker soient open source ou privés, vous pouvez utiliser l’offre gratuite de Snyk pour détecter et corriger les vulnérabilités de sécurité connues dans vos images Docker. Profitez-en aussi pour analyser et corriger vos applications Node.js !
Notez que le Dockerfile présenté ici et dans le dépôt open source associé n’est pas recommandé, car il ne respecte pas les bonnes pratiques de sécurité. Consultez plutôt les articles de blog suivants pour découvrir des pratiques utiles de sécurité Docker :
10 bonnes pratiques pour conteneuriser des applications web Node.js avec Docker
10 bonnes pratiques pour créer un conteneur Java avec Docker
Le guide de sécurité Docker pour les développeurs, par Snyk et Docker
Docker pour les développeurs Node.js : 5 points essentiels pour ne pas compromettre votre sécurité
La sécurité des conteneurs, pensée pour les développeurs
Snyk détecte et corrige automatiquement les vulnérabilités dans les images de conteneurs et les workloads Kubernetes.



