PROJET AUTOBLOG


IT-Connect

Site original : IT-Connect

⇐ retour index

CTF Drunk Admin Hacking Challenge : solutions et explications

mercredi 14 mai 2014 à 09:00

I. Présentation

Aujourd’hui nous allons nous pencher sur un CTF qui se nomme Drunk Admin Challenge, vous pourrez le trouver sur Vulnhub comme la plupart des CTF dont je parle ici. Il s’agit d’une VM que je fait tourner sur VMware Workstation 10 et ma machine d’attaque sera une KaliLinux virtualisée.

Note : Je vous invite à ne lire cette solution uniquement si vous êtes réellement bloqué, le fait de chercher longtemps pour une solution est le meilleur moyen de comprendre ce qu’il faut faire.

II. C’est partie !

On commence par le traditionnel netdiscover, outils de scan via le protocole ARP dont j’ai déjà parlé sur ce site :

netdiscover -r 192.168.1.0/24

On repère ici plusieurs IP, en trichant un peu on voit donc ma cible qui est virtualisée donc avec une carte réseau VMware, il s’agit de l’IP 192.168.1.15 :

DrunkAdmin01
On peut ensuite faire une scan de port sur cette cible afin de voir ce qui tourne sur celle-ci, on utilise pour cela nmap :

nmap -A -T4 192.168.1.15

On ne voit pas grand chose mis à part le port SSH qui semble fermé, l’option A ne fait un scan uniquement sur les “well known port“, qui sont les ports de 0 à 1024 :

DrunkAdmin02Étendons un peu notre recherche sur les ports supérieur :

nmap -A -T4 -p 0-1000 192.168.1.15

DrunkAdmin03

On voit a présent un service HTTP qui semble tourner sur le port 8880, ce qui est peut commun. On peut essayer de s’y rendre via un navigateur pour voir ce qu’il s’y passe :

DrunkAdmin04
On remarque donc un formulaire d’upload d’image. En faisant quelque teste, on remarque que seule les images au format png, jpeg ou gif. Si le fichier uploadé n’a pas ces format pour extension, On obtient le message suivant :

DrunkAdmin05

De même , si le fichier dépasse une certain taille, on obtient un “You have exceeded the size limit !“. Ce que l’on essaye de faire généralement lorsque l’on a un formulaire d’upload de fichier, c’est d’uploader un fichier … mais de préférence un script (php) qui pourrait nous permettre d’exécuter des actions sur le serveur directement. Si l’on fait un fichier au format .php, on obitent un “Invalid file extension”, même chose avec phtml, php5, etc. Je n’ai en tête que deux méthodes pour vérifier le format d’un fichier. La première est via son nom, c’est à dire la vérification de son format via des expressions régulières (est-ce que le fichier fini par .png ?), la seconde est via le champ Content-Type qui permet de spécifier le format du fichier uploadé comme précisé dans le RFC1867.

Il existe néanmoins probablement quantité d’autres méthodes, commençons par tester celles que nous connaissons. On va essayer d’uploader un fichier au format pngABC pour voir si cela gène le formulaire, et surprise ! Ça semble fonctionner, on a pas de message d’erreur concernant l’extension de notre fichier mais notre image n’est pas affichée, ce qui n’est pas plus gênant que cela. On peut ensuite essayer d’écrire un script PHP qui se nommera panda.png.php et voir si on arrive à l’uploader, voici ce que nous allons mettre dans notre script pour commencer :

<?php echo "SUCCES"; ?>

Uploadons le fichier pour voir ce qu’il se passe. On voit que le fichier (le script) est bien uploadé, on peut alors supposer (et seulement supposer) un regex du type “\.png” qui validerais le format d’un fichier, ce qui fait qu’un champ (.png.machin) serait accepter car il n’y a pas de vérification que le nom du fichier fini par “.png”. Cependant, on ne retrouves pas notre fichier sur le serveur web et il ne semble pas exécuté lors de l’affichage de l’image. Si on tente de joindre “http://cible/panda.jpg.php”, cela ne mène à rien. Il faut donc que l’on chercher à savoir ou et comment sont stockée nos images. On revient donc en arrière en uploadant à nouveau une image valide et correcte, j’upload le fichier “image.png”  :

DrunkAdmin08

On voit donc que notre image s’upload dans le dossier “images/” et est renommée en ce qui ressemble à un hash. On va essayer de dé-hashé la chaine obtenu pour voir si on peut y retrouver une logique nous permettant d’atteindre notre précédent script. Il existe quantité de service en ligne permettant de dé-hasher a partir de rainbow table.

DrunkAdmin09

Donc nous avons bien confirmation que les images sont renommées et portent le noms de leur hash complet (nom+extension) après ce renommage. Il nous reste donc plus qu’à obtenir le hash MD5 de “script.png.php” puis d’aller sur http://cible/images/hash pour voir notre script, c’est parti !

DrunkAdmin10Note : Lorsque PHP est installée sur un serveur web, celui-ci ajoute automatiquement “.php” à la fin d’une requête sans extension.

Et voila ! On a réussi à avoir uploader un script PHP sur notre serveur. On est donc en tant que www-data sur notre cible. Voyons ce que l’on peut découvrir avec cela. On peut à tout moment changer le contenu de notre fichier panda.png.php pour mettre de nouvelle commande PHP mais le plus simple est d’avoir ce que l’on appel un shell PHP dans lequel on enverra un commande PHP et le contenu ne sera retourné. Je met donc dans mon script la ligne suivante :

<?php echo exec($_REQUEST['cmd']); ?>

On upload à nouveau notre script dans le formulaire puis on se rend sur l’URL de celui-ci. On y ajoute le contenu de notre variable “cmd” qui sera la commande que nous souhaitons passer à notre script :

DrunkAdmin11

Cela rend la navigation sur le serveur beaucoup plus simple et beaucoup plus rapide. En explorant un peu plus le serveur, j’obtiens quelque chose en envoyant la requête “ls -al ../ > ls.txt”. Je vais ensuite lire mon fichier ls.txt :

DrunkAdmin12Le fichier .proof peut être intéressant, on voit la volonté de cacher le fichier car il commence par un “.”, bien que cela soit peu malin car il se situe dans un répertoire web. Le nom “proof” ne m’évoque pas grand chose (pas comme un .htaccess..), voyons ce qu’il y a dedans. J’envoie un commande qui affichera le contenu de “.proof” dans un fichier “.txt”, puis je l’affiche (la lecture directe de /.proof semble bloquée) :

DrunkAdmin13Ça semble intéressant, on récupère quelque chose qui ressemble à une conversation entre Bob et “…” ainsi qu’un “Secret Code”. On sait maintenant que l’utilisateur “bob” existe. On peut également le vérifier en affichant le contenu du “/etc/passwd”. Allons faire un tour dans son /home en envoyant le contenu de la commande “ls -al /home/bob” dans un fichier.txt :

DrunkAdmin14Le “public_html” nous indique que le contenu de ce dossier peut être joint via ~bob. C’est une manière de mettre sur le serveur web une partie d’un home d’un utilisateur. On peut donc se rendre sur notre serveur web via http://cible:8880/~bob et voir ce qu’il s”y passe :

DrunkAdmin15

Une demande de secret.. Je saisi le “secret Code” récupéré tout à l’heure mais cela ne donne rien de lisible. Il ne s’agit ici par d’un mot de passe mais d’une clé servant à déchiffrer le message d’après (le secret..). Après avoir quelque peu chercher je me rend compte que TGglMUxecjJDSDclN1Ej ressemble fortement à un encodage Base64. Si je l’encodre j’obtiens “Lh%1L^r2CH7%7Q#“. Je rentre alors ce code en tant que secret et bingo :

DrunkAdmin16Vu le sens de la phrase, la suite de chiffre ne peut être qu’une situation géographique, je rentre ces informations sur Google Maps  :

DrunkAdmin17

Et voila notre Flag =) Mission Accomplie !