Skip to main content

Injection de commandes : fonctionnement, risques et moyens de prévention

Écrit par

25 novembre 2020

0 minutes de lecture

Les attaques par injection de commandes, également appelées attaques par injection de commandes du système d’exploitation, exploitent une faille de programmation pour exécuter des commandes système sans validation, échappement ni assainissement adéquats des entrées. Un attaquant malveillant peut ainsi exécuter des commandes arbitraires.

Quels sont les risques liés aux injections de commandes ?

Selon la configuration de l’application et du processus qui l’exécute, une vulnérabilité d’injection de commandes peut entraîner une élévation des privilèges du processus ou ouvrir un shell inversé à distance, permettant à un tiers malveillant d’interagir librement avec le système.

Comment fonctionnent les attaques par injection de commandes ?

Pour comprendre les failles de programmation liées aux attaques par injection de commandes du système d’exploitation, examinons différentes vulnérabilités de ce type découvertes dans des applications basées sur Node.js.

systeminformation est une bibliothèque d’informations sur le système d’exploitation (OS) qui totalise plus de 500 000 téléchargements par semaine. Elle est régulièrement maintenue (avec des commits) et bénéficie d’une communauté, comme le montre la page Snyk Advisor consacrée à l’état de santé des dépendances :

Page du package npm systeminformation affichant un score de santé de 75/100, la tendance des téléchargements hebdomadaires et un graphique de la fréquence des commits de maintenance

Cependant, toutes les versions de system information antérieures à la version 4.27.11 sont vulnérables aux injections de commandes OS, en raison de plusieurs méthodes vulnérables auxquelles la bibliothèque donne accès aux utilisateurs.

Examinons le code de la fonction vulnérable inetChecksite(). Repérez-vous la faille de sécurité qui illustre ici un exemple d’injection de commandes ?

      let urlSanitized = util.sanitizeShellString(url).toLowerCase();
      if (urlSanitized) {
        let t = Date.now();
        if (_linux || _freebsd || _openbsd || _netbsd || _darwin || _sunos) {
          let args = ' -I --connect-timeout 5 -m 5 ' + urlSanitized + ' 2>/dev/null | head -n 1 | cut -d " " -f2';
          let cmd = 'curl';
          exec(cmd + args, function (error, stdout) {
          …

Ce fragment de code permet de tirer plusieurs conclusions :

  • Un paramètre url est assaini. Peut-être puis-je contourner les fonctions d’assainissement à l’aide d’un élément que l’auteur n’avait pas prévu ?

  • Une API non sécurisée de création de processus du système d’exploitation est utilisée : exec(), qui concatène les commandes et leurs arguments en une seule commande shell à exécuter. C’est aussi pourquoi l’auteur a dû créer son propre assainissement des arguments de ligne de commande.

La variable urlSanitized est concaténée aux arguments transmis à l’interface en ligne de commande.

C’est dans ce dernier point concernant urlSanitized que se trouve la faille de sécurité. La commande elle-même, référencée par la variable cmd, est l’utilitaire réseau curl. Et si nous pouvions simplement transmettre un argument de commande à curl dans l’URL ?

On peut tenter une injection de commandes à l’aide de la preuve de concept suivante : l’URL est transmise à la fonction vulnérable comme premier argument de la fonction inetChecksite(). Voici un exemple d’injection de commandes :

 const si = require('systeminformation');
si.inetChecksite("https://snyk.io; touch /tmp/abc", (result) => console.log(result));

Cela ne fonctionne toutefois pas dans ce cas, car ce package npm assainit les entrées utilisateur dangereuses, comme le point-virgule (;).

Cependant, les arguments de ligne de commande ne nécessitent généralement pas de caractères spéciaux. Nous pourrions donc fournir en entrée une URL comme https://snyk.io -o hihi, qui contient un espace et ajoute l’argument positionnel curl -o. Celui-ci enregistre le résultat du site Web dans un fichier que nous contrôlons.

Voici un autre exemple d’injection de commandes montrant comment l’exploitation peut se produire. Il fonctionne bien avec la version vulnérable de systeminformation@4.27.10 :

const si = require('systeminformation');
si.inetChecksite("https://snyk.io -o hihi", (result) => console.log(result));

Ce commit a corrigé l’assainissement afin de limiter davantage les risques de telles vulnérabilités d’injection de commandes :

Comparaison côte à côte du code dans lib/internet.js montrant un assainissement plus poussé des URL grâce à l’ajout de remplacements de caractères.

Antisèche sur l’injection de commandes

Les autres exemples d’injection de commandes nous apprennent beaucoup. Nous avons notamment identifié des vulnérabilités de sécurité dans des packages open source et observé les mesures prises pour les corriger, par exemple dans les vulnérabilités présentées ici et ici.

Pour prévenir les attaques par injection de commandes, adoptez les bonnes pratiques suivantes :

  1. Ne transmettez aucune entrée utilisateur aux commandes exécutées par votre application.

  2. Utilisez uniquement des API sécurisées pour exécuter des commandes, comme execFile(). Contrairement à d’autres API, celle-ci accepte une commande comme premier paramètre et un tableau d’arguments de ligne de commande comme second paramètre. Ainsi, la commande elle-même doit être un programme valide, indépendant de toute entrée dangereuse.

  3. Lorsque vous utilisez execFile(), veillez à ce que l’utilisateur ne puisse pas contrôler le nom du programme. Veillez également à associer les entrées utilisateur aux arguments de commande afin qu’elles ne soient pas transmises telles quelles à l’exécution du programme.

  4. Par précaution supplémentaire, vérifiez que les entrées utilisateur respectent le format attendu. Par exemple, si un paramètre de fonction attend une URL, vérifiez que l’entrée reçue est une URL valide. Cela aurait empêché la vulnérabilité d’injection de commandes mentionnée ci-dessus dans le package npm systeminformation.

Injections de commandes et OWASP Top 10

Pour illustrer la fréquence des attaques par injection de commandes OS, j’ai consulté toutes les vulnérabilités de sécurité connues publiquement et publiées par l’équipe de sécurité de Snyk en octobre 2020, puis filtré les résultats pour l’écosystème JavaScript sur npm. Comme vous pouvez le constater, de nombreuses vulnérabilités de sécurité liées à l’Command injection ont été identifiées dans des packages npm au cours de la seule dernière semaine d’octobre.

Page de la base de données des vulnérabilités Snyk affichant une recherche de vulnérabilités, des filtres par package et une liste de vulnérabilités npm avec leur niveau de gravité et leur date de publication.

En conclusion, les vulnérabilités d’injection de commandes sont plus courantes qu’on ne le pense. Ce n’est pas un hasard si les attaques par injection figurent en bonne place parmi les 10 principaux risques de sécurité Web de l’OWASP : elles sont fréquentes et prennent de nombreuses formes, comme les attaques par injection SQL.Je vous recommande vivement de connecter vos dépôts Git à Snyk pour détecter et corriger les vulnérabilités d’injection de commandes. Snyk en trouvera peut-être d’autres. Snyk est gratuit et la configuration est rapide : vous pourrez ainsi surveiller vos projets !

Lancez-vous dans les compétitions Capture The Flag

Apprenez à résoudre des défis Capture The Flag en regardant à la demande notre atelier virtuel d’initiation.

Lire la suite

Blog

Les modèles de pointe ont trouvé les vulnérabilités. Seul l’attaquant a trouvé les chaînes d’exploitation.

L’analyse statique a détecté les failles, mais seuls des tests d’attaque en conditions réelles ont prouvé comment elles pouvaient être enchaînées pour provoquer des compromissions. Comparaison d’Evo COS, de Claude Security et de Claude Code Security.

feature insights context
Blog

Les attaques autonomes sont déjà là. La défense doit suivre leur rythme.

Les attaquants autonomes réduisent la fenêtre de défense. Découvrez comment la découverte, la correction, la validation et la prévention continues peuvent aider les équipes de sécurité à suivre le rythme.

Blog

Pourquoi les agents de codage IA créent-ils sans cesse des failles de contrôle d’accès ?

Les agents de codage IA peuvent générer une logique d’autorisation qui compile et passe la revue, tout en exposant les données d’un tenant à un autre. Découvrez pourquoi les failles de contrôle d’accès sont difficiles à détecter et comment les prévenir.