[CTF] ESGI - My Name is Rookie
Write-up du challenge 'My Name is Rookie' (Web, 350 pts) du CTF HackLab ESGI 2019.
M0th3r > Quelque chose me perturbe. Comment un Androïde a pu passer le test des pirates cybernétique. Duke le premier de son genre n’a été crée par personne du gouvernement. Aujourd’hui disparu je veux retrouver son core. Si tu veux m’aider, tu dois passer le test des pirate Cybernétique. C’est le test que Duke-083 a passé haut la main. Récupère tout ce que tu sais sur Zedcorp.
http = ctf.hacklab-esgi.org:5008 \
ssh = ctf.hacklab-esgi.org:5007
Le site Web de ZedCorp
L’énoncé nous donne deux ports TCP, un service HTTP et un accès SSH. Nous pouvons donc d’ores et déjà supposer que nous trouverons de quoi nous connecter en SSH via le site Web.
En cherchant un peu sur le site, nous pouvons remarquer la présence d’un fichier robots.txt
qui nous donne des pistes à creuser, notamment le répertoire logs
.
|
|
Fort heureusement, l’auteur du challenge à été gentil et nous a laissé du Directory Listing. Nous avons donc 8 fichiers de logs :
Dans le fichier access-details.log
, nous trouvons des échanges HTTP complet, dont plusieurs tentatives d’authentification sur http://ctf.hacklab-esgi.org:5008/login.php :
|
|
Zone d’administration et monitoring des logs
Nous pouvons donc nous authentifier sur le site de ZedCorp avec le compte admin. L’interface d’administration propose de visualiser les journaux d’accès et d’erreur du serveur Web. Pour cela, une requête POST
est envoyée avec le nom du fichier de log en paramètre. Naturellement, on essaye de récupérer un autre fichier et cela fonctionne merveilleusement bien :)
|
|
|
|
Se connecter en SSH
N’oublions pas que l’énoncé comportait un port SSH (TCP/5007). Précédement, nous avons vu qu’il y a deux utilisateurs sur le serveur : test et trobin. En utilisant la LFI, nous pouvons trouver les clés RSA de l’utilisateur test dans le répertoire /home/test/.ssh
:
|
|
Hum, la clé RSA privée n’a pas l’air complète. Effectivement, pour afficher les logs (fonctionnalité d’origine de la zone d’administration, rappelez-vous …), le fichier est tronqué pour n’afficher que les 10 dernières lignes … 10 lignes … tail
? Essayons avec l’option -n 100
…
|
|
|
|
Et voilà, nous pouvons à présent nous connecter en SSH sur le port TCP/5007 avec le compte test :
host:~$ ssh -i id_rsa -p 5007 test@ctf.hacklab-esgi.org
Linux dev-server 4.9.0-6-amd64 #1 SMP Debian 4.9.88-1+deb9u1 (2018-05-07) x86_64
____ _ ___
|_ /___ __| |/ __|___ _ _ _ __
/ // -_) _` | (__/ _ \ '_| '_ \
/___\___\__,_|\___\___/_| | .__/
Dev Server |_|
[HINT] : Do you know proxychains ?
Last login: Sat Apr 6 05:45:38 2019 from 94.228.190.38
This account is currently not available.
Connection to ctf.hacklab-esgi.org closed.
SSH et Proxychains
Évidement, pour ceux qui ont suivi, le compte test ne peut pas se connecter au serveur (/usr/sbin/nologin
). Nous avons ici un indice, “Do you know proxychains ?".
host:~$ ssh -N -D 5000 -i id_rsa -p 5007 test@ctf.hacklab-esgi.org
Nous avons maintenant un proxy SOCKS5 qui donne accès au réseau interne accessible depuis le serveur de ZedCorp. Question : quelles sont les autres serveurs accessibles ?
Une solution serait de scanner le range IP comme un sagouin, mais j’ai préféré chercher plus d’informations sur le serveur Web, nottament cette histoire de tail
.
LFI to RCE
Rappelez-vous, pour obtenir la clé privée RSA, nous avions supposé que la commande tail
était utilisée et avions ajouté l’option -n 100
pour augmenter le nombre de lignes du fichier à afficher. Y aurait-il une RCE ?
Lorsque l’on essaye d’ajouter un ;
pour chaîner les commandes, le serveur refuse de l’exécuter et répond “Error : use of forbidden chars…". En continuant à creuser, on s’aperçoit que le serveur ne filtre pas le retour chariot %0A
… RCE !
Le but est de savoir quelle sont les autres serveurs voisins de celui-ci. En regardant les interfaces réseau (ip a
), nous observons deux interfaces ens192 (10.10.40.2/29
) et ens224 (10.0.0.1/16
). Notre connexion SSH est établie sur l’interface ens192.
10.0.0.1:~$ ss -t
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 10.10.40.2:ssh X.X.X.X:48040
ESTAB 0 0 10.0.0.1:55480 10.0.0.1:http
ESTAB 0 0 10.10.40.2:ssh X.X.X.X:48418
ESTAB 0 0 ::ffff:10.0.0.1:http ::ffff:10.0.0.1:55480
Le réseau interne de ZedCorp semble donc se trouver sur le range 10.0.0.0/16
. Et c’est le fichier /etc/hosts
qui nous donne la réponse que nous cherchions, à savoir les deux autres serveurs du réseau interne de ZedCorp.
|
|
Comme quoi, la RCE n’était pas forcément utile …
Scan du réseau interne
En utilisant Proxychains et Nmap, nous pouvons cartographier le réseau interne de ZedCorp :
host:~$ proxychains nmap 10.0.0.2
ProxyChains-3.1 (http://proxychains.sf.net)
Starting Nmap 7.70 ( https://nmap.org ) at 2019-04-06 00:35 CEST
Nmap scan report for 10.0.0.2
Host is up (0.0042s latency).
Not shown: 997 closed ports
PORT STATE SERVICE
22/tcp open ssh
8009/tcp open ajp13
8080/tcp open http-proxy
Nmap done: 1 IP address (1 host up) scanned in 4.74 seconds
host:~$ proxychains nmap 10.0.0.3
ProxyChains-3.1 (http://proxychains.sf.net)
Starting Nmap 7.70 ( https://nmap.org ) at 2019-04-06 00:35 CEST
Nmap scan report for 10.0.0.3
Host is up (0.0054s latency).
Not shown: 997 closed ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 4.59 seconds
Nous n’avons pas d’identifiants pour les accès SSH et FTP, le service AJP du serveur project-server (10.0.0.2
) est authentifié et les comptes par défaut ont été modifiés, et le service Web du serveur admin-server (10.0.0.3
) est protégé par une Basic-Auth.
Il ne nous reste plus que le Tomcat : http://10.0.0.2:8080/
OSINT et fausses pistes
Le serveur Tomcat nous donne accès à la TODO-list de ZedCorp :
Dans la liste des choses à faire, nous notons que le formulaire d’authentification du serveur d’administration présente un bug. En effet, la page http://10.0.0.3/index.php renvoyait, en plus de l’erreur 401, le formulaire d’authentification du site.
Après avoir testé, sans succés, les injections en tout genre, je me décide à chercher plus d’informations sur la TODO-list. Nous pouvons voir que la session CEO est en train de recevoir de nouvelles fonctionnalités. On ne sait jamais, sur un malentendu …
Hop, ceo:ceo
et nous sommes authentifié ! Mais nous obtenons le message “ERROR: CEO session is currently deactivated for maintenance”.
Autre information sur la TODO-list : il est mentionné la mise en place de backup FTP, et effectivement le compte backup existe sur le service FTP du serveur d’administration.
Après avoir passé pas mal de temps sur ce formulaire, je me décide à aller voir l’auteur du challenge qui m’informe que le comportement du formulaire d’authentification n’était pas intentionnel.
RCE Tomcat
Les pages d’erreur obtenue sur le serveur Tomcat nous divulguent sur la version : Apache Tomcat 7.0.41. Une petite recherche rapide sur Internet nous informe que cette version est vulnérable à la CVE-2017-12617 si jamais la méthode PUT est acceptée … Et elle l’est. Nous poussons donc notre Webshell JSP sur le serveur :
|
|
Le serveur nous répons avec HTTP/1.1 201 Crée
, merveilleux, nous pouvons mainteant exécuter des commandes sur le serveur via la page http://10.0.0.0:8080/rookie.jsp.
Un historique Bash mal nettoyé
Dans la TODO-list, nous avions vu le message suivant : “Some credentials was found on project-server. Please can you check your home and delete sensible informations ? Thx”.
En effet, les répertoires des utilisateurs ont été nettoyés, mais ont-ils été vraiment bien nettoyés ? Lorsque nous cherchons un peu sur le serveur, nous sommes mis sur la voie par les droits en lecture du fichier /home/dcloutier/.bash_history
(-rw-r–r–), seul fichier .bash_history
entre tous accessible en lecture. Et bingo, on y retrouve des identifiants FTP :
|
|
Connexion FTP et récupération des identifiants
Grace aux identifiants ainsi trouvés, nous pouvons utiliser le compte backup pour nous connecter au FTP sur serveur d’administration (10.0.0.3
) et récupérer le fichier credentials.tar.gz
que l’utilisateur dcloutier y a déposé :
host:~$ proxychains lftp -u 'backup,46t5r2e5t&2z!' 10.0.0.3
host:~$ openssl enc -d -aes256 -in credentials.tar.gz -out credentials.tgz --pass pass:daniel2019
host:~$ tar -xcvf credentials.tgz
host:~$ cat credentials.txt
Nous obtenons enfin tous les sésames pour le serveur d’administration !
|
|
Site d’administration ZedCorp
Une fois authentifié sur la Basic-Auth, nous pouvons tester les différents comptes :
- user : “No documents found”
- admin : “No documents found”
- ceo : “ERROR: CEO session is currently deactivated for maintenance”
Hum, tout ce chemin pour ne rien trouver sur le serveur …
En regardant attentivement, nous observons la création d’un cookie status avec une valeur en base64, qui une fois décodé nous donne ceci :
- user:
status=dXNlcg==
(user) - admin:
status=YWRtaW4=
(admin) - ceo: aucun cookie
Logiquement, le compte user possède le statut user
et le compte admin possède le statut admin
. Il nous reste le compte ceo qui ne possède pas de cookie (sûrement car il est désactivé), mais qui possède peut-être un statut …
En modifiant la valeur du cookie par ceo (status=Y2Vv
), nous obtenons une page avec plusieurs liens vers des documents PDF, dont un qui nous intéresse ici : http://10.0.0.3/273181bb39e87be4fe872ae250ec428ff55f0e0ef937999114248d1dfd4a6f74/rizone.pdf.
ESGI{W3_H0p3_t0_S33_y0u_N3xT_Y34R}
Merci à @Th1b4ud pour ce challenge :)
Share this post
Twitter
Google+
Facebook
Reddit
LinkedIn
StumbleUpon
Pinterest
Email