Avant de répondre directement à la question, il convient de noter que même si tout ce qu'un attaquant peut faire est de lire des données qu'il ne devrait pas pouvoir obtenir, c'est généralement encore vraiment mauvais. Considérez qu'en utilisant JOIN
s et SELECT
à partir des tables système (comme mysql.innodb_table_stats
), un attaquant qui commence par un SELECT
injection et aucune autre connaissance de votre base de données peut mapper votre schéma puis exfiltrer l'intégralité des données que vous avez dans MySQL. Pour la grande majorité des bases de données et des applications, cela déjà représente une faille de sécurité catastrophique.
Mais pour répondre directement à la question :je connais plusieurs façons d'injecter dans un MySQL SELECT
peut être utilisé pour modifier les données. Heureusement, ils ont tous besoin raisonnablement des circonstances inhabituelles sont possibles. Tous les exemples d'injections ci-dessous sont donnés par rapport à l'exemple de requête injectable de la question :
SELECT id, name, message FROM messages WHERE id = $_GET['q']
1. Requêtes "empilées" ou "par lots".
La technique d'injection classique consiste simplement à placer une autre déclaration entière après celle dans laquelle elle est injectée. Comme suggéré dans une autre réponse ici
, vous pouvez définir $_GET['q']
à 1; DELETE FROM users; --
de sorte que la requête forme deux instructions qui s'exécutent consécutivement, dont la seconde supprime tout dans les users
tableau.
En atténuation
La plupart des connecteurs MySQL - y compris notamment PHP (obsolète) mysql_*
et (non obsolète) mysqli_*
functions - ne prennent pas du tout en charge les requêtes empilées ou par lots, donc ce type d'attaque ne fonctionne tout simplement pas. Cependant, certains font - incluant notamment le connecteur PDO de PHP (bien que le support peut être désactivé pour augmenter la sécurité
).
2. Exploitation des fonctions définies par l'utilisateur
Les fonctions peuvent être appelées depuis un SELECT
, et peut modifier les données. Si une fonction de modification de données a été créée dans la base de données, vous pouvez faire le SELECT
appelez-le, par exemple en passant 0 OR SOME_FUNCTION_NAME()
comme valeur de $_GET['q']
.
En atténuation
La plupart des bases de données ne contiennent aucune fonction définie par l'utilisateur - et encore moins celles qui modifient les données - et n'offrent donc aucune possibilité d'effectuer ce type d'exploit.
3. Écrire dans des fichiers
Comme décrit dans l'article de Muhaimin Dzulfakar (un peu présomptueux) Exploitation avancée de MySQL
, vous pouvez utiliser INTO OUTFILE
ou INTO DUMPFILE
clauses sur une sélection MySQL pour vider le résultat dans un fichier. Depuis, en utilisant un UNION
, tout résultat arbitraire peut être SELECT
ed, cela permet d'écrire de nouveaux fichiers avec un contenu arbitraire à n'importe quel endroit où l'utilisateur exécutant mysqld
Peut accéder. En théorie, cela peut être exploité non seulement pour modifier des données dans la base de données MySQL, mais pour obtenir un accès shell au serveur sur lequel il s'exécute - par exemple, en écrivant un script PHP à la racine Web, puis en lui faisant une demande, si le Le serveur MySQL est co-hébergé avec un serveur PHP.
En atténuation
De nombreux facteurs réduisent l'exploitabilité pratique de cette attaque par ailleurs impressionnante :
- MySQL ne le fera jamais vous permet d'utiliser
INTO OUTFILE
ouINTO DUMPFILE
pour écraser un fichier existant, ni écrire dans un dossier qui n'existe pas. Cela empêche les attaques comme la création d'un.ssh
dossier avec une clé privée dans lemysql
répertoire personnel de l'utilisateur, puis en SSH, ou en écrasant lemysqld
binaire lui-même avec une version malveillante et en attente d'un redémarrage du serveur. - Tout package d'installation à moitié décent configurera un utilisateur spécial (généralement nommé
mysql
) pour exécutermysqld
, et n'accordez à cet utilisateur que des autorisations très limitées. En tant que tel, il ne devrait pas être en mesure d'écrire dans la plupart des emplacements du système de fichiers - et ne devrait certainement pas être en mesure d'effectuer des opérations telles que l'écriture dans la racine Web d'une application Web. - Les installations modernes de MySQL sont livrées avec
--secure-file-priv
défini par défaut, empêchant MySQL d'écrire ailleurs qu'un répertoire d'importation/exportation de données désigné et rendant ainsi cette attaque presque totalement impuissante... à moins que le propriétaire du serveur ne l'ait délibérément désactivé. Heureusement, personne ne désactiverait jamais complètement une fonction de sécurité comme celle-là, car ce serait évidemment - oh attendez tant pis .
4. Appel de sys_exec()
fonction de lib_mysqludf_sys
exécuter des commandes shell arbitraires
Il existe une extension MySQL appelée lib_mysqludf_sys
que - à en juger par ses étoiles sur GitHub
et une recherche rapide Stack Overflow
- compte au moins quelques centaines d'utilisateurs. Il ajoute une fonction appelée sys_exec
qui exécute des commandes shell. Comme indiqué dans #2, les fonctions peuvent être appelées depuis un SELECT
; les implications sont, je l'espère, évidentes. Pour citer la source
, cette fonction "peut être un danger pour la sécurité" .
En atténuation
La plupart des systèmes n'ont pas cette extension installée.