
Snipe-IT 的 CVE-2025-59712 和 CVE-2025-59713 PoC 漏洞利用
该 PoC 提供了一个自动化脚本,用于利用 CVE-2025-59712(User-Agent 头中的 XSS)和 CVE-2025-59713(不安全的反序列化)。
这两个漏洞是 Synacktiv 在对 Snipe-IT 软件进行漏洞研究时发现的。Snipe-IT 是一个基于 Laravel 的开源资产管理系统,旨在帮助组织跟踪和管理其物理和数字资产。
技术细节可在 Synacktiv 网站 上的专项安全公告中查看。
脚本提供三个子命令,对应三种利用模式:xss、rce 和 fullchain。
该子命令利用 CVE-2025-59712,它允许低权限用户在调用 /reports/activity 路由时,向渲染出的 HTML 页面中注入任意 JavaScript。只有管理员用户或对报表拥有显式查看权限的用户才能触发。注入之所以可能,是因为用户更新其个人资料信息时,对 User-Agent 字段的清理不当。
为此,脚本将首先以低权限用户身份登录,然后注入通过 --javascript 参数提供的文件中定义的 JavaScript 代码。
$ python3 exploit.py xss --help
Usage: exploit.py xss [OPTIONS]
Execute XSS attack only with custom JavaScript payload
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * --url -u TEXT Target Snipe-IT URL [required] │
│ * --login -l TEXT Low-privileged username [required] │
│ * --password -p TEXT Low-privileged password [required] │
│ * --new-name -n TEXT New name for low-privileged user [required] │
│ * --javascript -js TEXT Path to custom JavaScript file [required] │
│ --proxy -x TEXT HTTP proxy (http://ip:port) │
│ --verbose -v [quiet|normal|verbose] Logging verbosity [default: normal] │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
[!IMPORTANT]
在安全研究期间,测试是在一个默认显示User-Agent字段的 Snipe-IT 版本上进行的,恶意 JavaScript 正是注入到该字段中。自提交 10e5d88 起,在渲染操作日志表时,User-Agent属性默认不再显示。因此,对于该提交之后的 Snipe-IT 版本,触发 XSS 的管理员必须在视图选项中勾选User-Agent复选框。
该子命令利用 CVE-2025-59713,当已知管理员或超级管理员用户的凭据时,可实现远程代码执行。为此,会执行以下步骤:
db-dumps/mysql-snipeit.sql 文件中添加额外的 SQL 语句,这些语句会创建一个新的自定义字段,并修改最后一条操作日志,使其在恢复时包含一个带有 Laravel POP 链的 JSON 对象。[!TIP] 默认情况下,Snipe-IT 会将
.env文件包含在备份中。如果脚本检测到该文件,会显示APP_KEY值,并将.env文件保存到./output目录中(可通过--output-dir指定自定义位置)。
[!CAUTION] 恢复备份会断开所有连接到该实例的用户。
/api/v1/reports/activity 路由,从而触发反序列化并执行 Laravel POP 链。$ python3 exploit.py rce --help
Usage: exploit.py rce [OPTIONS]
Execute RCE attack only (requires existing admin account)
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * --url -u TEXT Target Snipe-IT URL [required] │
│ * --admin-user -au TEXT Admin username [required] │
│ * --admin-pass -ap TEXT Admin password [required] │
│ --output-dir -od PATH Output dir for .env file [default: /home/ninja/Téléchargements/snipe-it-advisory/exploit/output] │
│ --shell-ip -si TEXT Reverse shell IP address │
│ --shell-port -sp INTEGER Reverse shell port │
│ --command -c TEXT Custom command (overrides reverse shell) │
│ --proxy -x TEXT HTTP proxy (http://ip:port) │
│ --verbose -v [quiet|normal|verbose] Logging verbosity [default: normal] │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
fullchain 子命令旨在将 XSS 和 RCE 两个漏洞串联起来。它对应这样一种场景:你只能访问一个低权限用户,但想要实现远程代码执行。只有当访问 /reports/activity 页面的用户是管理员或超级管理员时,该模式才有效。实际上,只有这些角色才有权创建和恢复备份,而这是污染数据库并在后续触发 Laravel POP 链所必需的。
为此,脚本将:
--command 参数自定义此选项,与 RCE 模式相同)。User-Agent 字段中注入 <scr> 标签,强制受害者的浏览器加载恶意 JavaScript 模板。/reports/activity 路由时,XSS 被触发,恶意 JavaScript 会被受害者的浏览器加载并执行。此后,会执行与 RCE 模块中相同的步骤,只不过是用 JavaScript 完成。此模式利用了几个额外的 JavaScript 库,其所有功劳归各自的作者所有:
$ python3 exploit.py fullchain --help
Usage: exploit.py fullchain [OPTIONS]
Execute full attack chain: XSS -> Backup manipulation -> RCE
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * --url -u TEXT Target Snipe-IT URL [required] │
│ * --login -l TEXT Low-privileged user's username [required] │
│ * --password -p TEXT Low-privileged user's password [required] │
│ * --new-name -n TEXT New name for low-privileged user [required] │
│ --ip -i TEXT HTTP server IP address (default: auto-detect) │
│ * --port -P INTEGER HTTP server port [required] │
│ --admin-user -au TEXT Admin username to create [default: admin_rce] │
│ --admin-pass -ap TEXT Admin password to create [default: password123] │
│ --shell-ip -si TEXT Reverse shell IP address │
│ --shell-port -sp INTEGER Reverse shell port │
│ --command -c TEXT Custom command (overrides reverse shell) │
│ --proxy -x TEXT HTTP proxy (http://ip:port) │
│ --verbose -v [quiet|normal|verbose] Logging verbosity [default: normal] │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
要运行此脚本,请执行以下命令:
$ git clone https://github.com/synacktiv/CVE-2025-59712_CVE-2025-59713
$ cd CVE-2025-59712_CVE-2025-59713
$ python3 -m venv .venv && source .venv/bin/activate
$ python3 -m pip install -r requirements.txt
还提供了一个 Dockerfile,以便尝试该脚本并复现漏洞利用过程。它会拉取一个存在漏洞的 Snipe-IT 版本,使用 php artisan 配置数据库,并设置两个用户:
admin,默认密码为 AdminPassword123!lowpriv,默认密码为 LowPrivUser123!在运行容器之前,需要将 .env 和 snipe-it.conf 文件中的 URL 更新为 Snipe-IT 实例的地址:
$ sed -i 's|^APP_URL=.*|APP_URL=http://<IP>:<PORT>|' .env
$ sed -i 's|\(ServerName\s*\).*|\1http://<IP>:<PORT>|' snipe-it.conf
然后可以运行容器:
$ docker build . -t "snipe-it-cve"
$ docker run -p 80:80 --name "snipe-it-debian" snipe-it-cve:latest