
Injection de commandes
Regardons l'injection de commandes en elle-même pour le moment. Nous allons principalement nous concentrer sur quelques exemples différents afin qu'il soit plus facile de voir à quoi cela ressemble en action. Pour rappel, des vulnérabilités d'injection de commandes se produisent lorsque la saisie utilisateur utilise une partie d'une commande du système d'exploitation, comme la fonction suivante :
let ip = request.params.IPAddress ;
système (« ping" + ip) ;
Si un utilisateur fournit l'adresse IP, nous utiliserons 8.8.8.8 comme exemple, la commande qui sera exécutée sera ping 8.8.8.8, qui fait exactement ce à quoi on s'attend. Cependant, si l'utilisateur fournit `8.8.8.8 && ls /etc/ `, cette commande ne serait pas simplement envoyez un ping à l'IP 8.8.8.8, mais il exécutera également `ls` dans le dossier `/etc/.
Mesures d'atténuation
Compte tenu de la gravité d'une attaque par injection de commandes, vous devez d'abord vous poser certaines questions importantes lorsque vous utilisez des commandes système :
- Avez-vous vraiment besoin d'invoquer cette commande ? La meilleure défense est de ne jamais invoquer les commandes du système
- Existe-t-il des libraires/liaisons qui vous permettent d'obtenir le même effet sans utiliser de commande système ?
- Pouvez-vous transmettre des données au processus via Standard In, au lieu de la commande elle-même ?
Si cela n'est pas possible, le paramétrage est important.
Exemples
Voici quelques exemples dans différentes langues pour vous aider à montrer à quoi cela ressemble dans la pratique.
Sans paramétrage, cela est vulnérable à l'injection de commandes.
dossier de chaînes = « /tmp/ && ifconfig » ;
string cmd = « \" ls "+ dossier +" \ "» ;
//NON SÉCURISÉ : exécute à la fois les commandes `ls` et `ifconfig`
System.Diagnostics.Process.Start (« bash », « -c » + cmd) ;
C# - sécurisé
En fournissant la commande sous forme de liste de paramètres, celle-ci est paramétrée et protégée contre l'injection de commandes.
dossier de chaînes = « /tmp/ && ifconfig » ;
<string>Arguments de liste = new List <string>() {» -c », « ls », dossier} ;
//SECURE : n'exécute pas la commande ifconfig
System.Diagnostics.Process.Start (« bash », arguments) ;
Java - Non sécurisé
Sans paramétrage, cela est vulnérable à l'injection de commandes.
dossier de chaînes = « /tmp/ && ifconfig » ;
//NON SÉCURISÉ : exécute à la fois les commandes `ls` et `ifconfig`
ProcessBuilder b = nouveau ProcessBuilder (dossier « bash -c ls" +) ;
Processus p = pb.start () ;
Java - Sécurisé
En fournissant la commande sous forme de liste de paramètres, celle-ci est paramétrée et protégée contre l'injection de commandes.
dossier de chaînes = « /tmp/ && ifconfig » ;
//SECURE : n'exécute pas la commande ifconfig
ProcessBuilder b = nouveau ProcessBuilder (« bash », « -c », « ls », dossier) ;
Processus p = pb.start () ;
Javascript - Non sécurisé
Sans paramétrage, cela est vulnérable à l'injection de commandes.
const {exec} = require (« child_process ») ;
dossier const = « /tmp/ && ifconfig » ;
//NON SÉCURISÉ : exécute à la fois les commandes `ls` et `ifconfig`
const ls = exec (« bash -c ls" + dossier, (erreur, stdout, stderr) => {
console.log (`stdout : $ {stdout} `) ;
}) ;
Javascript - Sécurisé
const {spawn} = require (« child_process ») ;
dossier const = « /tmp/ && ifconfig » ;
//SECURE : n'exécute pas la commande ifconfig
const ls = spawn (« bash », [» -c », « ls », dossier]) ;
ls.stdout.on (« données », données => {
console.log (`stdout : $ {data} `) ;
}) ;
Python - Non sécurisé
Sans paramétrage, cela est vulnérable à l'injection de commandes.
sous-processus d'importation
dossier = « /tmp/ && ifconfig »
# INSECURE : exécute à la fois les commandes `ls` et `ifconfig`
subprocess.run (dossier « bash -c ls » +, shell=True)
Python - Sécurisé
En fournissant la commande sous forme de liste de paramètres, celle-ci est paramétrée et protégée contre l'injection de commandes.
sous-processus d'importation
dossier = « /tmp/ && ifconfig »
# SECURE : n'exécute pas la commande ifconfig
subprocess.run (["bash », « -c », « ls », dossier])