Récemment, mon site a été piraté par injection SQL. Le pirate a utilisé la requête suivante pour obtenir mon nom de base de données. Je ne peux pas comprendre cette requête qu'ils ont écrite.
Requete:
=-999.9%20UNION%20ALL%20SELECT%20concat(0x7e,0x27,Hex(cast(database()%20as%20char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536--
Une fois la requête exécutée, elle affiche un résultat entier, quelque chose comme "74545883
".
Pouvez-vous expliquer le fonctionnement de la requête?
Cela ressemble à une attaque par débordement . Ils UNION
- ed avec votre requête existante. en remplaçant tous vos %20
par (espace) car son code encodé en url donne:
=-999.9 UNION ALL SELECT CONCAT(0x7e,0x27,Hex(cast(database() as char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536-
décomposer:
=-999.9
termine simplement votre requête actuelle0x31303235343830303536
Est NULL
- ils correspondent simplement au nombre de colonnes de votre requête existante. Si vous aviez SELECT * FROM users
Et users
avait 4 colonnes, le UNION
doit aussi avoir 4 colonnes . Par conséquent, ils ont simplement utilisé des valeurs `NULL pour remplir ces colonnes.CONCAT()
. Ils combinent 126, 39, nom de base de données en valeur hexadécimale, 39 et 126--
Est un commentaire mysql - il ignore le reste de votre requête aprèsÀ en juger par cette attaque, je soupçonne que vous n'encapsulez pas d'entrée dans mysql_real_escape_string()
, ce qui a permis aux attaqués de sauter de votre requête et d'exécuter la leur.
Voir owasp.org pour plus d'informations.
Ce n'est pas la requête complète, en fait la personne a entré cette chaîne dans votre application web.
Maintenant, remplacez d'abord% 20 par un espace vide dans la partie union, vous obtenez:
SELECT concat(0x7e,0x27,Hex(cast(database() as char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536--
On dirait que l'utilisateur a mis la chaîne à un endroit où vous attendiez un nombre. Ainsi, vous voyez que d'abord il y a un nombre (999,9) pour terminer la condition d'origine de la requête. Ensuite, une partie UNION est ajoutée. Enfin, après la partie UNION, les caractères de commentaire sont ajoutés (-) afin que le reste de la requête (qui pourrait être ajoutée par votre système) soit contourné.
Nous pouvons formater le code pour une meilleure compréhension:
SELECT
concat
(
0x7e,
0x27,
Hex(cast(database() as char)),
0x27,
0x7e
),
0x31303235343830303536,
0x31303235343830303536,
0x31303235343830303536
Maintenant, la sous-chaîne de la première colonne du résultat contiendra la forme codée hexadécimale de votre nom de base de données. En fait, il doit être entouré de guillemets simples (0x27), puis à nouveau entouré de ~ (0x7e)
La requête a renvoyé le nom de la base de données en utilisant DATABASE () , puis il l'a converti en une valeur hexadécimale en utilisant la fonction HEx () .
Une fois qu'ils l'ont eu, ils ont pu utiliser la fonction UNHEX
Jetez un œil aux exemples UNHEX
mysql> SELECT UNHEX('4D7953514C');
-> 'MySQL'
mysql> SELECT 0x4D7953514C;
-> 'MySQL'
mysql> SELECT UNHEX(HEX('string'));
-> 'string'
mysql> SELECT HEX(UNHEX('1267'));
-> '1267'
Il est bon de savoir comment ils sont entrés, mais dans l'ensemble, vous devez corriger votre code pour éviter l'injection SQL.
-999.9 UNION ALL SELECT
CONCAT('Hex(cast(database() as char))'),
0x31303235343830303536,
0x31303235343830303536,
0x31303235343830303536
Je pense que vous devez avoir d'autres entrées dans votre journal, sinon il savait d'avance que vous avez 3 colonnes.
Ceci est un exemple d'injection utilisant Havij Les 0x7e et 0x27 correspondent à ~ et 'qui seront utilisés pour encadrer l'affichage HTML tel que id = 999999.9 + union + all + select + 0x3130323534383030353636, (select + concat (0x7e, 0x27, unhex (Hex (cast (sample_tbl.name + as + char))), 0x27,0x7e) + from + test
. Sample_tbl + Order + by + id + limit + 0,1) + - Cette requête va render ~ 'Alfred' ~ qui est la valeur de champ du nom de colonne, de la table sample_tbl dans le test de table
~ 'r3dm0v3_hvj_injection' ~ est le code de signature Havij unhex 0x7233646D3076335F68766A5F696E6A656374696F6E selon http://www.string-functions.com/hex-string.aspx
Tout d'abord, la requête semble codée en HTML. Remplace le %20
s avec des espaces et cela deviendra un peu plus lisible. Ils convertissent également une partie de la requête en une représentation hexadécimale de quelque chose. Essayez également de décoder en hexadécimal cette partie de l'instruction.
Un risque d'injection SQL est créé lorsque vous essayez de créer dynamiquement un SQL sous forme de chaîne, puis de l'envoyer au SGBD. Imaginez une chaîne comme celle-ci stockée dans votre système pour une utilisation dans une barre de recherche, etc.:
SELECT * FROM SOME_TABLE WHERE SOME_COLUMN=
Pour terminer la requête et laisser l'attaque entrer, ils devraient faire leur entrée comme ceci:
'x' or 1=1
Dans ce cas, la requête deviendra:
SELECT * FROM SOME_TABLE WHERE SOME_COLUMN='x' or 1=1
SOME_COLUMN
pourrait être n'importe quelle variable, peu importe où elle échoue, l'important est que 1=1
est TOUJOURS vrai, ce qui permet potentiellement à l'attaquant d'accéder à chaque ligne de cette table.
Maintenant que vous le savez, parcourez votre code et remplacez chaque requête créée dynamiquement par une instruction préparée. Le site OWASP dispose également de nombreuses ressources pour le codage défensif: