CCTV
ZoneMinder SQLi to shell, passive traffic capture for lateral movement, MotionEye RCE for root.
# table of contents
Reconnaissance
Standard nmap scan to kick things off:
┌──(root㉿kali)-[~]
└─# nmap -Pn -sC -sV 10.129.8.208
Starting Nmap 7.98 ( https://nmap.org ) at 2026-03-24 12:14 -0500
Nmap scan report for 10.129.8.208
Host is up (0.036s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.14 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 76:1d:73:98:fa:05:f7:0b:04:c2:3b:c4:7d:e6:db:4a (ECDSA)
|_ 256 e3:9b:38:08:9a:d7:e9:d1:94:11:ff:50:80:bc:f2:59 (ED25519)
80/tcp open http Apache httpd 2.4.58
|_http-title: Did not follow redirect to http://cctv.htb/
|_http-server-header: Apache/2.4.58 (Ubuntu)
Two ports — SSH and HTTP. Add cctv.htb to /etc/hosts and check the web app.
Enumeration
The site is running ZoneMinder, a CCTV management platform. The staff login accepts default credentials straight away — admin:admin gets us in.
Checking the version reveals it’s vulnerable to CVE-2024-51482, a SQL injection affecting the ZoneMinder API.
Exploitation
There’s a public PoC available at https://github.com/BridgerAlderson/CVE-2024-51482, or you can use SQLmap if you prefer the slower route. Running the exploit dumps the Users table and we get two accounts:
superadmin:$2y$10$t5z8uIT.n9uCdHCNidcLf.39T1Ui9nrlCkdXrzJMnJgkTiAvRUM6m
mark:$2y$10$prZGnazejKcuTv5bKNexXOgLyQaok0hq07LW7AJ/QNqZolbXKfFG.
Both are bcrypt hashes. superadmin doesn’t crack quickly so focus on mark — that one falls fast:
password: opensesame
Foothold
SSH in as mark with those credentials. There’s no user flag in his home directory, but there is another user — sa_mark.
Lateral Movement
Checking for interesting capabilities on the box:
mark@cctv:~$ find /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin -type f -exec getcap {} \;
/usr/bin/mtr-packet cap_net_raw=ep
/usr/bin/tcpdump cap_net_raw=eip
/usr/bin/ping cap_net_raw=ep
tcpdump has cap_net_raw=eip — on a CCTV server that’s transmitting footage around the network, this is worth abusing. Start a passive capture and let it run for ~30 seconds:
mark@cctv:~$ tcpdump -i any -A > dump.pcap
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
Pull the file back and run it through net-creds.py, or just grep for sa_mark directly in the pcap. Either way, credentials are sitting in plaintext traffic:
sa_mark:X1l9fx1ZjS7RZb
Switch users and grab the flag:
cat user.txt
afeffcb2d799fe083b71f4d748d0f1d8
Privilege Escalation
There’s a PDF in sa_mark’s home directory that hints at credential reuse between systems and references an “old” camera management platform still running internally.
Scanning open ports on the machine shows port 8765 is listening. Curling it confirms it’s MotionEye. Since it’s only bound to localhost, forward it back through the SSH tunnel:
┌──(root㉿kali)-[~]
└─# ssh -L 8765:localhost:8765 mark@cctv.htb
This creates an encrypted tunnel so traffic to your local 8765 comes out at localhost:8765 on the remote machine — you can now hit MotionEye in a browser at http://localhost:8765.
The running version is vulnerable to CVE-2025-60787, an authenticated RCE. The Metasploit module covers it:
exploit/linux/http/motioneye_auth_rce_cve_2025_60787
Try sa_mark’s credentials for the auth — credential reuse pays off. Run the module and land a root shell.
Flags
| Flag | Hash |
|---|---|
| User | afeffcb2d799fe083b71f4d748d0f1d8 |
| Root | `` |