Comment détecter l'injection SQL ?
Ma réponse est la suivante : en ce qui concerne la sécurité de la partie A, la détection des injections SQL est relativement facile à réaliser.
1) Détection d'erreur d'injection.
2) N'injectez pas de rapports d'erreurs booléens, car les faux positifs sont relativement élevés.
3) Effectuez une injection de temps basée sur le temps, l'exploitation et la maintenance des contacts pour créer des enregistrements de base de données de journaux lents, surveiller le sommeil et évaluer les mots clés. Vous pouvez ajouter le numéro d'identification de la tâche d'analyse à la virgule décimale du temps de sommeil pour faciliter. positionnement. (ps. Cette méthode peut trouver 99% des injections SQL)
Par conséquent, lorsque je fais une injection temporelle basée sur le temps, je limite très sévèrement l'erreur de temps. Cependant, @chengable effectue un travail lié à la sécurité sur la partie B, et l'injection de temps basée sur le temps n'est généralement pas possible. Il est entendu qu'il filtre principalement d'abord l'existence de points d'injection, puis détecte sqlmapapi.py. J'ai également utilisé sqlmap pour les tests plus tôt. Les problèmes que j'ai rencontrés étaient de nombreux faux positifs et un temps d'analyse long. Ensuite, j'ai essayé sqlmapapi.py. Le problème était que le temps d'analyse était trop long et qu'il ne prenait pas en charge l'injection au format json (détails). . Cependant, l'injection temporelle de sqlmap est relativement précise. Que faire si vous ne souhaitez pas utiliser sqlmapapi.py ? Ici, je vais supprimer la logique d'injection basée sur le temps de sqlmap.
Plaintez-vous : le code de sqlmap n'est pas standardisé, moche et volumineux. Quelqu'un m'a déjà recommandé de lire le code source de sqlmap et d'en apprendre beaucoup. Maintenant que j'y pense, j'ai abandonné très tôt.
Donc, si vous êtes paresseux et que vous ne voulez pas regarder le code source, ajoutez --technique=T -v 3 et regardez d'abord la charge utile de détection sqlmap.
Il semble que j'ai été paresseux et que j'ai trouvé quelques moyens. Vous pouvez le voir sur la capture d'écran :
Tout d'abord, sqlmap a bourré la charge utile d'injection de sommeil :
Premier sommeil bourré (5) , après avoir constaté qu'il est exécuté ; sleep(0) est inséré, et enfin sleep(5) est inséré.
Ensuite, faites une supposition. L'idée générale de la vérification est de dormir(5) d'abord, puis de dormir(0) si le deuxième délai réussit. Si aucun délai n'est trouvé, continuez sleep(5). Si le délai réussit à nouveau, un rappel qu'il peut y avoir une injection apparaîtra :
Enfin, très intelligemment, sqlmap est utilisé pour éviter les faux positifs. si la condition de jugement est utilisée pour éliminer les faux positifs. À partir de la figure ci-dessus, vous pouvez voir que sqlmap teste deux fois si l'équation est vraie et deux fois si l'équation ne tient pas, les faux positifs sont jugés en fonction du deuxième délai.
Retournez au code source et jetez un œil : sur la base de certains des mots-clés précédents, passons directement au code pour y jeter un œil. Par exemple, *apparaît être* apparaît avant la recherche. Voir le code de la première étape :
sqlmap/lib/controller/checks.py:
J'ai trouvé ici que c'est presque le. pareil à ce que j'avais deviné auparavant.
Recherchez où se trouve la charge utile, en particulier la charge utile avec la condition if. Utilisez une requête par mot-clé et trouvez-la ici :
sqlmap/xml/payloads/time_blind.xml:
Vous pouvez voir chacun si La charge utile de les conditions sont dans le champ vectoriel.
Fermer les caractères avant le point d'injection est la clé pour savoir s'il peut être injecté.
Observed tools/sqlmap/xml/boundaries.xml, nous devons donc également nous référer aux différentes situations de fermeture ici :
Référez-vous à la Lors de l'injection awvs précédente, j'ai pensé à une méthode de détection plus facile à comprendre. Prenez le temps de consommation de 6 tests normaux sans charge utile injectée et calculez la valeur moyenne comme temps de requête natif (ori_time).
Lorsque l'heure d'injection est sleep(5), soustrayez ori_time de l'heure actuelle comme sleep_time. Si sleep_time est inférieur à 4, on considère que le délai ne s'est pas produit. (Considérant que ori_time est affecté par le réseau et devient plus grand, le seuil est ajusté à quatre secondes.)
Lorsque le temps d'injection est sleep(0), soustrayez ori_time de l'heure actuelle comme sleep_time. Si sleep_time est supérieur à 2, cela signifie qu'il y a une fausse alarme dans le délai.
Regardez le code sqlmap, ils ont utilisé un problème mathématique que je ne comprends pas (détails)
Suivi : Request.queryPage --->wasLastResponseDelayed Vous pouvez voir que la logique est : Prenez le temps de consommation de 30 tests normaux sans charge utile injectée et mettez-les dans kb.responseTimes. Calculez l'écart type 30 fois sous forme d'écart et calculez le temps de réponse le plus lent en fonction de l'écart sous forme de lowerStdLimit :
Sa valeur est la moyenne de 30 fois plus TIME_STDEV_COEFF*écart type (écart). Quant à TIME_STDEV_COEFF, le régler sur 7 peut donner une précision de jugement de 99,9999999997440 %.
Enfin, jugez si le temps de consommation actuel de la requête est supérieur à lowerStdLimit. S'il est supérieur, cela signifie que le délai s'est produit, et s'il est inférieur, cela signifie qu'il n'y a pas de délai (en plus, lorsque lowerStdLimit. est inférieur à 0,5 seconde, lowerStdLimit prend 0,5 seconde).
L'émotion me dit que je devrais choisir la première méthode, et la rationalité me dit que je devrais choisir la deuxième méthode. J'ai quand même choisi la deuxième méthode et mesuré le point d'injection (détails). Une analyse très stable a trouvé des vulnérabilités d’injection.
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!