WriteUp NightHawk CTF (Training exercises) – PHP Exploit
Ce challenge d’entrainement était disponible dans l’attente du NightHawk CTF 2018.
Catégorie: Web
Points: 1300 pts
Énoncé (traduit du chinois) : Take the flag right, Just do it!!! https://shrimphp.herokuapp.com/
Lorsqu’on arrive sur le site, on est accueilli par le code source de la page php:
A première vue, à travers ce caractère d’entrée (qui est l’emoji de crevette), on doit Bypass le filtre de caractères, et exécuter une commande dans le “eval(‘die(“‘ . substr($_, 0, 16) . ‘”);’);”. La petite complexité c’est qu’on doit exécuter une commande avant que la fonction die s’exécute. Le tout doit être réalisé en moins de 16 caractères. Aïe Aïe Aïe…
Après de multiples tests en local, je me suis rendu compte que le code source nous donnait la réponse à cette partie du challenge.
Pour pouvoir exécuter du code dans le “die()”, il suffit de passer le code suivant dans le get: “.system(ls).”
Ainsi, on obtient
Cool ! Allons voir cette misterieuse page ‘lineralubalalala.php”:
Aïe ! c’est en chinois ! à partir d’ici, j’ai passé un moment à essayer de comprendre ce que je devais faire. Mais google traduction n’étant pas très au point pour les langues comme le chinois, j’ai décidé de résoudre ce challenge avec une méthode un peu plus particulière.
Je suis donc retourné sur la page précédente et j’ai réfléchi à un moyen de lire directement tous les fichiers, en espérant que le flag soit caché là, dans le code source, ou dans un fichier à coté.
Cependant j’ai uniquement 16 caractères, et la commande précédente : “.system(ls).” fait déjà 16 caractères ! On ne peut pas utiliser non plus “exec()” car elle a un nom encore trop long pour pouvoir exécuter quelque chose d’intéressant !
Tant pis, on va réfléchir à un autre moyen:
Pour pouvoir réussir ce challenge, il faut déjà savoir comment accéder à la fonction “eval()”:
- strpos():
Le fonctionnement de cette dernière est un peu spécial. Elle va chercher la première occurrence d’une petite chaîne de caractères dans une plus grande. Pour pouvoir passer le filtre il nous suffit de passer ‘ ” ‘ en premier caractère.
- die():
Cette fonction est très simple, elle va stopper l’exécution du programme, en affichant ce qu’il y a en dans son premier argument.
Une fois ces éléments pris en compte, je me rappelle soudainement qu’une syntaxe un peu particulière existe pour exécuter des commandes en PHP: les ” ` ” (accent grave -> alt gr + 7).
Faisons le test en php:
la ligne :
Est transformée en cette ligne lorsque l’utilisateur entre quelque chose:
On rajoute donc:
Et la fonction “eval()” va d’abord exécuter notre ligne “id”, et gentiment nous renvoyer l’output avec “die()”.
Parfait, testons cela:
Sur un cli Linux, on entre “php -a” pour rentrer dans le mode interractif de php. On entre notre commande et bingo ! :
Nickel! Maintenant, on a plein de caractères de dispo pour pouvoir rentrer des commandes, notre but étant de lire tous les fichiers dans notre répertoire courant, on va simplement forcer le PHP à exécuter cette ligne:
via cette URL:
https://shrimphp.herokuapp.com/?%F0%9F%8D%A4=”.`cat%20*`.”
(%F0%9F%8D%A4 étant l’emoji crevette encodé en URL).
et bingo, l’ensemble du contenu des fichiers nous est rendu ! Il nous suffit de ctrl + f “flag” pour récupérer notre flag dans la mélasse chinoise:
C’est pas récupéré en suivant le challenge, mais tant pis ! On aura cherché une autre méthode, c’est déjà ça 😉
Flag: flag{php_is_good_for_hackers!!!!}
La bise.