
Outil d'exploitation d'injections SQL
#BBQSQL# Un outil d'exploitation d'injection SQL aveugle
L'injection SQL aveugle peut être pénible à exploiter. Lorsque les outils disponibles fonctionnent, ils fonctionnent bien, mais lorsqu'ils ne fonctionnent pas, vous devez écrire quelque chose de personnalisé. C'est long et fastidieux. BBQSQL peut vous aider à résoudre ces problèmes.
BBQSQL est un framework d'injection SQL aveugle écrit en Python. Il est extrêmement utile pour attaquer des vulnérabilités d'injection SQL délicates. BBQSQL est également un outil semi-automatique, offrant une assez grande personnalisation pour les cas d'injection SQL difficiles à déclencher. L'outil est conçu pour être indépendant de la base de données et est extrêmement polyvalent. Il dispose également d'une interface utilisateur intuitive pour faciliter la configuration des attaques. Python gevent est également implémenté, ce qui rend BBQSQL extrêmement rapide.
Nous avons essayé d'écrire l'outil de manière à ce qu'il soit très explicite lors de la configuration d'une attaque dans l'interface utilisateur. Cependant, par souci de rigueur, nous avons inclus un Readme détaillé qui devrait vous fournir des informations supplémentaires sur les spécificités de chaque option de configuration. Une chose à noter est que chaque option de configuration dans l'interface utilisateur a une description associée, donc si vous choisissez de lancer l'outil sans lire cette page, vous devriez pouvoir vous débrouiller pour mener une attaque.
Comme pour les autres outils d'injection SQL, vous devez fournir certaines informations sur la requête.
Vous devez fournir les informations habituelles :
Ensuite, spécifiez où se trouve l'injection et quelle syntaxe nous injectons. Lisez la suite pour les détails.
Cela devrait être simple, mais quoi qu'il en soit. Essayez d'exécuter :
sudo pip install bbqsql
Si cela ne fonctionne pas pour vous, vous pouvez installer à partir des sources. L'outil nécessite gevent et requests.
Dans le menu, vous verrez un emplacement pour les options de BBQSQL. Vous y spécifiez les options suivantes :
Ceci est décrit plus en détail ci-dessous dans aperçu de la syntaxe des requêtes.
Le nom d'un fichier pour sortir les résultats. Laissez ce champ vide si vous ne voulez pas de sortie dans un fichier.
BBQSQL utilise deux techniques lors de la conduite d'une attaque par injection SQL aveugle. La première et par défaut est binary_search. Voir Wikipedia pour plus d'informations.
La deuxième technique que vous pouvez utiliser est frequency_search. La recherche par fréquence est basée sur une analyse de la langue anglaise pour déterminer la fréquence à laquelle une lettre apparaît. Cette méthode de recherche est très rapide pour les données non entropiques, mais peut être lente pour les données non anglaises ou obscurcies.
Vous pouvez spécifier binary_search ou frequency_search comme valeur pour ce paramètre.
Ceci spécifie le type d'injection SQL que vous avez découvert. Vous pouvez définir ici quel attribut de la réponse http bbqsql doit examiner pour déterminer vrai/faux.
Vous pouvez spécifier : status_code, url, time, size, text, content, encoding, cookies, headers ou history
Si vous avez identifié une injection SQL qui entraîne un code de statut serveur différent, définissez 'status_code' ici. Si le cookie est différent, définissez 'cookie'. Si la taille de la réponse est différente, définissez 'size'. Vous comprenez l'idée.
La concurrence est basée sur la bibliothèque gevent en Python. Fonctionnellement, elle semble agir comme du threading mais les spécificités du fonctionnement peuvent être vues dans notre talk DefCon ici [insérer le lien ici]. Ce paramètre contrôle le niveau de concurrence pour exécuter l'attaque. Ceci est utile pour limiter le débit des requêtes et accélérer les temps d'attaque. Pour les serveurs web très performants comme nginx, nous avons pu fixer la concurrence à 75. Par défaut, elle est réglée à '30'.
Si vous rencontrez une vulnérabilité d'injection SQL qui présente des particularités étranges (comme certains caractères ne peuvent pas être inclus ou les fonctions comme ASCII/CHAR ne fonctionnent pas), vous avez probablement déjà écrit un script avec votre syntaxe d'injection personnalisée. BBQSQL supprime la partie script et vous offre un moyen de coller votre syntaxe de requête personnalisée et d'exploiter facilement.
Le champ query est l'endroit où vous construisez votre requête utilisée pour exfiltrer des informations de la base de données. L'hypothèse est que vous avez déjà identifié une injection SQL sur un paramètre vulnérable et testé une requête qui réussit.
Voici un exemple de requête que vous pouvez utiliser pour construire votre requête.
Dans cet exemple, l'attaquant cherche à sélectionner la version de la base de données :
vulnerable_parameter'; if(ASCII(SUBSTRING((SELECT @@version LIMIT 1 OFFSET ${row_index}) , ${char_index} ,1))) ${comparator:>}ASCII(${char_val}) WAITFOR DELAY '0\:0\:0${sleep}'; --
La syntaxe de la requête est basée sur des espaces réservés qui indiquent à BBQSQL comment exécuter l'attaque.
Vous devez fournir les espaces réservés suivants pour que l'attaque fonctionne. Une fois que vous les avez placés dans votre requête, bbqSQL fera le reste :
${row_index} : Ceci indique à bbqSQL d'itérer sur les lignes ici. Comme nous utilisons LIMIT, nous pouvons visualiser n lignes en fonction de la valeur de ${row_index}.
${char_index} : Ceci indique à bbqSQL quel caractère de la sous-sélection interroger.
${char_val} : Ceci indique à bbqSQL où comparer les résultats de la sous-sélection pour valider le résultat.
${comparator} : Ceci est la façon dont vous dites à BBQSQL de comparer les réponses pour déterminer si le résultat est vrai ou non. Par défaut, le symbole > est utilisé.
${sleep} : Ceci est optionnel mais indique à bbqSQL où insérer le nombre de secondes de pause lors de l'injection SQL basée sur le temps.
Tous ces espaces réservés ne sont pas obligatoires. Par exemple, si vous avez découvert une injection SQL semi-aveugle basée sur des booléens, vous pouvez omettre le paramètre ${sleep}.
BBQSQL dispose de nombreux paramètres HTTP que vous pouvez configurer lors de la configuration de votre attaque. Au minimum, vous devez fournir l'URL, l'endroit où vous voulez que la requête d'injection s'exécute, et la méthode. Les options suivantes peuvent être définies :
Vous spécifiez où vous voulez que la requête d'injection soit insérée en utilisant le modèle ${injection}. Sans le modèle d'injection, l'outil ne saura pas où insérer la requête.
Fournissez les fichiers à envoyer avec la requête. Définissez la valeur sur le chemin et BBQSQL se chargera d'ouvrir/inclure le fichier.
En-têtes HTTP à envoyer avec les requêtes. Cela peut être une chaîne ou un dictionnaire. Par exemple :
{"User-Agent":"bbqsql"}
ou
"User-Agent: bbqsql"
Un dictionnaire ou une chaîne de cookies à envoyer avec la requête. Par exemple :
{"PHPSESSIONID":"123123"}
ou
PHPSESSIONID=123123;JSESSIONID=foobar
Spécifiez une URL à laquelle les requêtes doivent être envoyées.
C'est un booléen qui détermine si les redirections http seront suivies lors de l'envoi des requêtes.
Spécifiez un proxy http à utiliser pour la requête sous forme de dictionnaire. Par exemple :
{"http": "10.10.1.10:3128","https": "10.10.1.10:1080"}
Spécifiez les données POST à envoyer avec la requête. Cela peut être une chaîne ou un dictionnaire. Par exemple :
{"input_field":"value"}
ou
input_field=value
Spécifiez la méthode pour la requête http. Les méthodes valides sont :
'get','options','head','post','put','patch','delete'
Spécifiez un tuple de nom d'utilisateur et mot de passe à utiliser pour l'authentification de base http. Par exemple :
("myusername","mypassword")
Après avoir configuré votre attaque dans l'interface utilisateur, vous pouvez exporter le fichier de configuration. Vous verrez l'option lorsque vous exécuterez l'outil. Le fichier de configuration exporté utilise ConfigParser et est facile à lire. Un exemple de fichier de configuration peut être vu ci-dessous :
`[Request Config] url = http://example.com/sqlivuln/index.php?username=user1&password=secret${injection} method = GET
[HTTP Config] query = ' and ASCII(SUBSTR((SELECT data FROM data LIMIT 1 OFFSET ${row_index:1}),${char_index:1},1))${comparator:>}${char_val:0} # technique = binary_search comparison_attr = size concurrency = 30`
Ceci est utile si vous prévoyez de reprendre une attaque ou simplement d'ajuster la requête sans avoir à reconfigurer chaque option.
Vous pouvez également importer une configuration depuis la ligne de commande ou depuis l'interface utilisateur. Pour importer une configuration depuis la ligne de commande, exécutez simplement bbqsql avec les options suivantes :
bbqsql -c config_file
Lorsque vous chargez un fichier de configuration, que ce soit via la ligne de commande ou l'interface utilisateur, les mêmes routines de validation sont exécutées sur les paramètres pour s'assurer qu'ils sont valides.
Parfois, vous devez faire quelque chose de vraiment fou. Peut-être devez-vous crypter les valeurs entrant dans un champ avant d'envoyer la requête, ou peut-être devez-vous encoder triple URL. Quoi qu'il en soit, ces situations rendent les autres outils impossibles à utiliser. BBQSQL vous permet de définir des fonctions "hook" que l'outil appellera à différents points de la requête. Par exemple, vous pouvez spécifier une fonction pre_request qui prend la requête comme argument, effectue les mutations nécessaires, et retourne la requête modifiée pour être envoyée au serveur.
Pour implémenter cela, créez un fichier Python et spécifiez les fonctions de hook. Les noms de fonctions disponibles sont listés ci-dessous. Dans votre fichier hooks, vous pouvez définir aussi peu ou autant de ces fonctions de hook que vous le souhaitez. Ensuite, dans la section bbqsql_options du menu, vous pouvez spécifier l'emplacement de votre hooks_file. BBQSQL lira ce fichier et utilisera les hooks que vous avez définis.
Il est important que les fonctions de hook que vous spécifiez aient exactement les noms spécifiés ci-dessous, sinon BBQSQL ne saura pas quel hook appeler quand. La fonction args reçoit un paramètre qui contient tous les arguments utilisés pour créer la requête HTTP. La fonction pre_request reçoit l'objet requête avant qu'il ne soit envoyé. La fonction post_request reçoit l'objet requête après qu'il ait été envoyé. La fonction response reçoit l'objet réponse avant qu'il ne soit retourné à BBQSQL.
Les hooks suivants sont mis à disposition :
args: Un dictionnaire des arguments envoyés à Request().
pre_request: L'objet Request, juste avant d'être envoyé.
post_request: L'objet Request, juste après avoir été envoyé.
response: La réponse générée à partir d'une Request.
Pour plus d'informations sur le fonctionnement de ces hooks et sur la façon dont votre dictionnaire hooks doit se présenter, consultez la documentation de la bibliothèque requests sur ses hooks
Un exemple de fichier hooks pourrait ressembler à ceci :
# file: hooks.py
import time
def pre_request(req):
"""
this hook replaces a placeholder with the current time
expecting the url to look like this:
http://www.google.com?k=v&time=PLACEHOLDER
"""
req.url = req.url.replace('PLACEHOLDER',str(time.time()))
return req
Soumettez toute correction de bug ou demande de fonctionnalité à https://github.com/Neohapsis/bbqsql/
S'il vous plaît ! Nous voyons cela comme un excellent point de départ pour construire un framework d'injection SQL pleinement fonctionnel. N'hésitez pas à forker le code et nous pourrons fusionner vos modifications si elles sont utiles.
Le BBQ est absolument délicieux et l'injection SQL aussi !