(MySQL) from SQLi to webshell

To the non-french speaker, note that you can translate the articles using the Google Trad widget situated at the bottom of all pages.


Comme vous le savez, il existe plusieurs SGBD : MySQL, SQLite3, MSSQL etc… Chacun de ces SGBD offrent des fonctionnalités différentes. Par exemple sous MSSQL on peut exécuter des commandes système à l’aide de la procédure xp_cmdshell.

Sous MySQL, il existe deux fonctions très intéressantes : LOAD_FILE() et INTO OUTFILE. La première va nous permettre de charger un fichier contenu sur le serveur (i.e : en lire le contenu). Tandis que la seconde va nous permettre d’écrire dans un fichier (toujours sur le serveur).

Pour la suite de cet article je vais utiliser les fichiers de test dont je me suis servi pour l’article sur le dump de database. La seule différence ici, c’est que je vais supprimer les sécurités que j’avais implémenté afin de faciliter l’exploitation de l’injection.

Voici donc le fichier de traitement :

11

Bon on va pas y aller par quatre chemins, la vérité c’est qu’avec la fonction load_file on peut lire n’importe quel fichier présent sur le serveur dont le /etc/passwd. La preuve avec cette requête :

1 union select 1,2 load_file("/etc/passwd");#

2.png

Alors pourquoi c’est possible ? Eh bien tout simplement parce que l’utilisateur mysql a les droits de lecture sur ces fichiers. Par contre il ne les a pas sur le fichier /etc/shadow. Ça serait problématique…

Bon c’est bien rigolo tout ça mais est ce qu’on pourrait pas faire mieux ? Sisi 😈😈 !

Avec la fonction INTO OUTFILE, on va pouvoir écrire dans des fichiers. But first, on doit vérifier que l’on a les droits d’écriture. Et pour cela il faut d’abord savoir quel utilisateur local gère la base de données. Et encore une fois, on se servira d’une fonction built-in de MySQL (enfin plutôt d’une table) : mysql.user !

En effet, dans cette table on trouve tous pleins d’infos sur les droits des utilisateurs :

3.png

Nous ce qu’on veut, c’est savoir quels sont les utilisateurs et surtout quels sont leurs droits relatifs à la création de fichier. Pour cela on entrera ceci :

1 union select 1,user,file_priv from mysql.user;#

Ce qui nous retournera ceci :

4.png

On voit donc que l’utilisateur root a les droits en écriture tout comme l’utilisateur defte (symbolisé par le Y). On va donc pouvoir créer des fichiers sur le serveur ! Et si on peut écrire du contenu dans des fichiers, qu’est ce qui nous empêche d’y déposer un webshell ?

Eheh. L’injection est simple :

1 union all select "something" INTO OUTFILE 'backdoor.php';#

Seulement voilà, il y a quand même un petit souci. Que se passerait-il si les caractères tels que  » et  » sont filtrés ? On ne pourrait plus écrire le nom du fichier à charger et/ou dans lequel écrire.

Deux options s’offrent à nous. Soit on écrit le nom de notre fichier en hexadécimal. Auquel cas notre payload pour lire le fichier /etc/passwd ressemblera à ça :

1 union select 1,2 load_file(0x2f6574632f706173737764);#

Soit on utilise la fonction CHAR que l’on a déjà vu dans cet article. Et notre payload ressemblera à ça :

1 union select 1,2 load_file(CHAR(047,101,116,099,047,1120,97,115,115,119,100));#

Dernière chose, dans les fichiers de configuration de MySQL j’ai remarqué qu’il y avait une variable appelée secure_file_priv dans laquelle se trouve un répertoire. En fait c’est dans cette variable que se trouve le répertoire dans lequel MySQL peut lire des fichiers. Si cette variable est égale à / (la racine) alors MySQL pourra lire tous les fichiers du serveur.

Pour éviter ça, vous pouvez lui attribuer la valeur NULL ou encore un répertoire spécifique selon vos besoins. Pour cela il suffit d’éditer le fichier /etc/mysql/my.cnf et d’ajouter cette ligne :

secure_file_priv=NULL
ou
secure_file_priv='votre_répertoire'

Voilà voilà ! 😁

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l'aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s