Post

HackTheBox Writeup - CCTV

HackTheBox Writeup - CCTV

The CCTV machine on HackTheBox is a medium-difficulty Linux box that focuses on exploiting a video surveillance stack. The attack path involves exploiting a SQL injection in ZoneMinder to gather initial information, gaining a foothold via SSH with reused credentials, and leveraging a signature bypass and command injection vulnerability in motionEye to achieve root access.

Enumeration

Initial Nmap scan revealed ports 22 (SSH) and 80 (HTTP).

Port 80 - ZoneMinder

The website hosts a ZoneMinder instance (v1.37.63). ZoneMinder is a widely used open-source CCTV software.

Vulnerability: CVE-2024-51482 (SQL Injection)

Researching ZoneMinder v1.37.x revealed a critical boolean-based SQL injection vulnerability in the tid parameter of the removetag action in web/ajax/event.php.

The vulnerable code concatenates the tid parameter directly into a SQL query:

1
2
3
$tagId = $_REQUEST['tid'];
$sql = "SELECT * FROM Events_Tags WHERE TagId = $tagId";
$rowCount = dbNumRows($sql);

While this vulnerability is authenticated, ZoneMinder often has default credentials. Testing admin:admin or admin:opensesame successfully grants access to the dashboard.

Foothold: SSH Access

Using the SQL injection, we can dump the Users table. The dump reveals hashes for users mark and superadmin.

However, testing common credential reuse, we find that the user mark uses the password opensesame, which is also used for the admin account in ZoneMinder.

1
2
ssh mark@cctv.htb
# Password: opensesame

Lateral Movement & Enumeration

Upon gaining SSH access as mark, we find that user.txt is not in his home directory. Internal enumeration reveals several local services:

  • motionEye: Running on port 8765.
  • MediaMTX: Running on port 8888 (API) and 8554 (RTSP).

Looking at the motionEye configuration in /etc/motioneye/motion.conf, we find the admin username and a SHA1 password hash:

1
2
# @admin_username admin
# @admin_password 989c5a8ee87a0e9521ec81a79187d162109282f0

Signature Bypass in motionEye

motionEye uses a signature mechanism for its API. The signature is calculated as: SHA1(METHOD:PATH:BODY:PASSWORD_HASH)

The PASSWORD_HASH is the one found in the configuration file. Since we have read access to motion.conf, we can calculate a valid _signature for any request, effectively bypassing authentication.

Privilege Escalation: Root RCE

Vulnerability: CVE-2025-60787 (Command Injection)

Researching motionEye revealed a command injection vulnerability in the image_file_name parameter. This parameter is used when motionEye saves a snapshot or records a video.

By updating the camera configuration to include a payload in image_file_name and then triggering a snapshot, we can execute arbitrary commands as the user running motionEye (which is root).

Exploitation Steps

  1. Calculate Signature: Use the admin password hash to sign a POST request to /config/1/set/.
  2. Update Configuration: Set image_file_name to a reverse shell or a command to create a SUID bash.
    1
    
    payload = '$(cp /bin/bash /tmp/rootbash; chmod +s /tmp/rootbash)'
    
  3. Trigger Execution: Use the motion control interface on port 7999 to trigger a snapshot:
    1
    
    curl http://127.0.0.1:7999/1/action/snapshot
    

Flags

Once the SUID bash is created, we gain root access:

1
2
3
/tmp/rootbash -p
cat /home/sa_mark/user.txt
cat /root/root.txt

User Flag: b22a855daffe4decc2c12377ec18c41b Root Flag: 3b226a131d5a1dea9e1bd6b5f861d4f2

This post is licensed under CC BY 4.0 by the author.