Disco Maghreb - Catalogue
Write-up
On continue notre visite de la boutique Disco Maghreb. Cette fois, le serveur MCP ne propose pas directement le flag, mais une fonction permettant de rechercher des chansons de Raï par titre. Objectif : détourner ce moteur de recherche pour obtenir le flag caché dans la base SQLite.
1. Reconnaissance
Comme dans le challenge précédent, on peut se connecter au serveur MCP avec un client FastMCP. En listant les tools, on découvre :
| JSON | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Le serveur expose un seul tool : search_song_by_title(title: str). Il nous permet de chercher des chansons à partir du titre:
| Python | |
|---|---|
1 2 | |
| Text Only | |
|---|---|
1 2 3 4 | |
2. Exploitation - étapes du SQLi
a) Test de l'injection
On commence classiquement par injecter un simple apostrophe ' :
| Text Only | |
|---|---|
1 | |
Cela provoque une erreur, confirmant que notre entrée n'est peut-être pas nettoyée !
b) Enumération des colonnes
On tente d'ajouter un ORDER BY pour déterminer le nombre de colonnes dans le SELECT.
' ORDER BY 2 --fonctionne.' ORDER BY 3 --renvoie une erreur.
On en déduit que la requête retourne 2 colonnes. Notre UNION SELECT devra donc aussi sélectionner 2 colonnes.
c) Découverte du schéma de la base
On utilise la table interne de SQLite sqlite_master pour lister les tables présentes dans la DB:
| SQL | |
|---|---|
1 | |
| Text Only | |
|---|---|
1 2 3 4 5 6 | |
On voit deux tables: songs et secret. Et cette dernière contient une colonne flag !
d) Récupération du flag
On lance alors une union select pour extraire la colonne flag :
| SQL | |
|---|---|
1 | |
On sélectionne 2 fois flag pour avoir une union valide.
Résultat :
| Text Only | |
|---|---|
1 2 3 4 5 | |
Script complet
Flag
flag-rai_n3v3r_d135-Yj60e72N