J'ai lu que différentes bases de données (mysql, sql server, ...) ont des vulnérabilités différentes et qu'elles sont vulnérables à certaines injections sql spécifiques.
Lorsqu'un attaquant tente d'effectuer une attaque de base de données contre un site Web (comme une injection SQL), il identifie tout d'abord le type de base de données, puis effectue l'attaque en pensant à la base de données détectée.
Comment cette inspection précédente est-elle effectuée par l'attaquant? Vous utilisez des requêtes spéciales? Existe-t-il des outils spécifiques? Je n'ai trouvé aucune information à ce sujet.
Disons que vous avez une requête comme celle-ci:
$q="SELECT username, joindate FROM users WHERE username LIKE '%" . $search . "%' LIMIT 20";
Imaginez maintenant que vous contrôlez $search
Via un paramètre. Nous le faisons généralement renvoyer les mots de passe utilisateur dans le champ joindate
comme ceci:
$search="' UNION SELECT username, password FROM users; -- -";
En tant que telle, la requête devient:
SELECT username, joindate FROM users WHERE username LIKE '%' UNION SELECT username, password FROM users; -- - %' LIMIT 20
La partie après le double trait d'union est un commentaire, donc elle est ignorée, et nous obtenons toutes les combinaisons de nom d'utilisateur et de mot de passe ajoutées en tant que nouveaux enregistrements à la fin de l'ensemble de données, après les enregistrements légitimes. Impressionnant!
Mais maintenant, nous voulons l'adapter afin que nous puissions trouver le nom de la base de données, pour une enquête plus approfondie de leur base de données. Sur MySQL, nous pouvons utiliser la fonction DATABASE()
:
$search="' UNION SELECT DATABASE(), 1; -- -";
L'utilisation de 1
Ici est de remplir le champ joindate
, que nous n'utilisons pas.
Sur MSSQL, nous pouvons faire exactement la même chose, mais avec DB_NAME()
:
$search="' UNION SELECT DB_NAME(), 1; -- -";
Ces deux astuces ajouteront une seule ligne à la fin de l'ensemble de résultats, contenant le nom de la base de données.
Nous pouvons ensuite développer cette astuce pour utiliser VERSION()
sur MySQL ou @@VERSION
Sur MSSQL, qui renvoie la version actuelle de la base de données. Pour Oracle et PL/SQL, vous pouvez vérifier l'existence de la table v$version
, Simplement en faisant une requête dessus et en recherchant une erreur.
En plus des autres réponses, une méthode que j'utilise pour les empreintes digitales de base de données (en particulier lorsque l'injection est aveugle et qu'aucune donnée n'est renvoyée) est la différence de syntaxe entre les moteurs de base de données. Il y a un bon échantillon sur la diapositive 34 de cette présentation que j'ai tendance à utiliser.
Un bon exemple est donc la concaténation de chaînes. MS-SQL et DB2 utilisent + tandis qu'Oracle PL/SQL et PostGRES utilisent ||, vous pouvez donc l'insérer dans des chaînes et observer le comportement de l'application. Si elle se comporte comme si la chaîne était concaténée, il s'agit peut-être d'une injection.
L'un des moyens les plus simples pour un attaquant de déterminer la base de données utilisée par une application serait de provoquer une erreur de l'application d'une manière ou d'une autre avec une requête de base de données.
Ensuite, si la gestion des erreurs n'est pas activée dans l'application (ce qui n'est souvent pas le cas), l'erreur de base de données sera affichée. Ceux-ci sont généralement assez détaillés et vous pouvez déterminer la base de données à partir de cela.
Cela vaut également la peine de considérer si vous connaissez l'une des langues suivantes dans lesquelles l'application Web est écrite, le cadre utilisé, la plate-forme utilisée, le fournisseur d'hébergement e.t.c. ils peuvent tous aider à déterminer quelle base de données est utilisée. Par exemple, s'ils utilisent asp utilisent très probablement MSSQL et s'ils utilisent PHP très probablement MySQL. Ce n'est pas toujours vrai évidemment, mais si vous deviez deviner par exemple un l'injection aveugle de sql attaque son autre façon de réduire les choses.
Il existe plusieurs méthodes pour ce faire. Cependant, notez que vous n'avez pas besoin de connaître le type de base de données pour effectuer une attaque. Le savoir peut fournir des vecteurs d'attaque supplémentaires ou alternatifs, mais n'est pas nécessaire pour l'injection SQL.
La plupart des bases de données fournissent des fonctions ou ont des contes de dictionnaire qui peuvent être utilisés pour identifier le type et la version de la base de données. Ceux-ci diffèrent selon les fournisseurs, mais à condition d'avoir trouvé un point d'injection SQL général, vous pouvez simplement essayer chacun jusqu'à ce que vous obteniez une réponse valide.
Il existe également des différences syntaxiques entre de nombreux dialectes différents de SQL. Par exemple, Oracle a la syntaxe (+) pour représenter les jointures externes. Il existe souvent des différences subtiles dans les types de données disponibles, tels que le type de texte de PostgreSQL (qui n'a pas d'Oracle) ou dans la façon dont les séquences/colonnes d'incrémentation automatique sont traitées, etc.
Parfois, vous pouvez le constater en obtenant simplement les détails du pilote de base de données ou du connecteur. Selon l'environnement, la langue, etc., cela peut être trivial ou non.