web-dev-qa-db-fra.com

Comment obtenir la sortie d'une injection SQL?

C'est juste à des fins d'apprentissage. Je veux obtenir tous les noms d'utilisateur et mots de passe d'une table dans un serveur MySQL, où les "guillemets magiques" ont été désactivés. Dans l'entrée pour le nom d'utilisateur: j'ai mis quelque chose comme:

username'; SELECT * FROM users;

Mais comment puis-je obtenir l'entrée de ma requête d'injection? J'ai fait quelques recherches et j'ai trouvé sp_makewebtask dans Microsoft SQL Server, qui peut générer un fichier .html dans un dossier de partage. Comment puis-je le faire dans MySQL? Ou existe-t-il une meilleure façon? Merci beaucoup.

10
Jack Owen

Le problème avec votre approche est que PHP ne va pas (D'accord, comme indiqué ci-dessous dans les commentaires, c'est possible, mais c'est peu probable) exécutez plusieurs requêtes simultanées et lorsque vous fermez la requête initiale avec un point-virgule, puis essayez d'en créer une nouvelle au début du SELECT. Vous devrait les UNION ou UNION ALL.

username'; SELECT * FROM users;

Devrait être similaire à:

username='admin' UNION ALL SELECT CONCAT(username, 0x3A, password) AS details FROM users LIMIT 0,1;

Lisez ce lien pour la syntaxe UNION de MySQL http://dev.mysql.com/doc/refman/5.0/en/union.html

Il existe deux principaux types d'injection SQL, ils sont aveugles et basés sur les erreurs.

L'aveugle est l'endroit où vous n'obtiendrez aucune sortie de la requête donnée, vous pouvez juste remarquer un morceau de texte ou d'image ou quelque chose d'autre manquant dans la page, et vous devez énumérer à travers diverses options pour obtenir le résultat souhaité.

En fonction des erreurs, comme son nom l'indique, le script génère une erreur et vous pouvez voir exactement ce que vous devez faire. Vous verrez le résultat de l'injection quelque part sur la page ou dans le code source de la page au moins.

Dans tous les cas, vous devriez pouvoir utiliser la syntaxe INTO OUTFILE De MySQL pour sortir les résultats de la requête dans un fichier, en supposant que vous avez les bonnes autorisations pour le faire.

http://www.tech-recipes.com/rx/1475/save-mysql-query-results-into-a-text-or-csv-file/

C'est pour la plupart des cas d'injection MySQL, cependant, il existe plus de deux types de SQLi, mais pour les besoins de cette conversation, ce sont les principaux que vous devez connaître.

Ceci est un bon tutoriel sur les injections SQL: http://www.exploit-db.com/papers/13045/

6
DarkMantis

Eh bien, il existe des outils comme SQLMap qui le feront pour vous, malheureusement je ne suis pas assez intelligent pour savoir exactement comment ils obtiennent ces données. Avec SQLMap, vous pouvez générer un certain nombre d'éléments tels que les noms de base de données, les noms de table, les colonnes de table, les données de table et plus encore.

Je peux cependant donner un exemple de la façon dont vous pouvez produire des données dans un scénario très spécifique. Vous ne parlez pas beaucoup du contexte de votre attaque par injection SQL, il est donc difficile de dire si cela s'applique à votre situation.

Disons par exemple que vous avez une page Web qui génère un petit tableau comme ci-dessous:

Product Name  | Price   
----------------------
Door knobs    | $5.00
Hammers       | $10.00
Saws          | $12.00

Selon la configuration des requêtes et de la programmation sous-jacentes, il est possible de renvoyer d'autres données qui seront ensuite affichées dans ce tableau. Supposons que vous déterminiez que le paramètre de chaîne de requête search est injectable dans l'URL ci-dessous:

http://mysite.com/store.php?search=hardware

Si vous êtes en mesure de créer une requête comme celle ci-dessous (en laissant l'attaque en texte brut à des fins de démonstration):

http://mysite.com/store.php?search=blah';SELECT username, password FROM USERS where '1'='1

Le site peut être programmé de manière à ce qu'il prenne les deux colonnes retournées et les recrache sur la table.

Encore une fois, ceci est un exemple très spécifique. La méthode SQLMap semble fonctionner malgré tout, donc je serais intéressé d'entendre si quelqu'un sait ce qu'il fait.

3
Abe Miessler

Habituellement, une valeur extraite de SQL s'affiche quelque part sur la page. Ainsi, par exemple, si la requête récupère un nom (Select name from users where id=%s), Injectez quelque chose comme 1;select top 1 columnname from (your query here);--. Selon la base de données et l'implémentation, il peut y avoir ou non un moyen de vider la table complète avec une seule commande (sinon nous pouvons toujours énumérer les lignes de la table).

Dans d'autres cas, on peut inciter l'application à afficher des erreurs SQL. Dans ce cas, vous pouvez essayer d'utiliser la requête (qui renvoie une sortie 1x1) comme nom de colonne, par exemple select (your query here) from somerandomtable;. Habituellement, cela retournera une erreur (car la colonne n'existera pas) où le nom de colonne proposé sera exposé.

3
Manishearth

Vous pouvez le faire en le déposant quelque part: SELECT ... INTO OUTFILE par exemple. ( http://dev.mysql.com/doc/refman/5.0/en/select-into.html )

Après ce point, vous pouvez remplacer un champ en utilisant load_file () qui renvoie un fichier sous la forme d'une chaîne unique et en remplissant un champ connu sur une seule ligne qui est lue et affichée par l'application.

(par exemple: "UPDATE Accounts SET bio = load_file ('/ etc/passwd') WHERE UserName = 'prettypinkponi3s';"

Vous pouvez même ignorer cette étape et utiliser une mise à jour directement dans l'injection d'origine. Et c'est en quelque sorte le point.

Si vous injectez en aveugle, vous pouvez profiter du manque de validation d'entrée de l'application de de la base de données au langage de rendu. Et vous devez trouver des valeurs qui vous permettront de conserver les données que vous essayez d'exfiler. (Images de profil, bios, champs de description, etc., etc.)

0
Ori