libcurl MQTT发布长度溢出漏洞深度分析

本文详细分析了libcurl MQTT PUBLISH功能中的堆缓冲区溢出漏洞,该漏洞由于未检查size_t算术运算导致,在32位系统上可被利用造成内存破坏。包含复现步骤、影响分析和修复建议。

libcurl MQTT PUBLISH长度溢出(堆溢出)漏洞报告

摘要

libcurl的MQTT PUBLISH组装函数(lib/mqtt.c::mqtt_publish)中存在基于堆的缓冲区溢出漏洞,原因是在计算MQTT"剩余长度"时未检查size_t算术运算。如果payloadlen + 2 + topiclen导致size_t溢出,libcurl会分配过小的缓冲区,然后将payloadlen字节memcpy到其中,造成堆溢出。该漏洞在客户端收到CONNACK后立即触发,不需要恶意代理。在32位目标上可利用性高;在64位构建中通常表现为大分配失败。

AI使用说明:该漏洞由SecMate检测,并使用AI助手分析代码路径、准备PoC和起草本报告。所有技术发现都在本地使用ASAN构建进行了验证。

受影响版本

来源:git master提交a7ece53e96ba(rc-8_17_0-2-43-ga7ece53e9) 用于复现的平台:Ubuntu 22.04(64位主机),构建启用MQTT和ASAN的32位libcurl 工具:GCC 11.4.0,CMake 3.22.1

用于复现的构建配置(CMake)

1
2
3
4
5
6
-DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=ON -DBUILD_CURL_EXE=OFF
-DCURL_DISABLE_MQTT=OFF -DCURL_ENABLE_SSL=OFF -DCURL_DISABLE_NTLM=ON
-DCURL_USE_LIBPSL=OFF -DUSE_LIBIDN2=OFF -DUSE_NGHTTP2=OFF
-DCURL_BROTLI=OFF -DCURL_ZSTD=OFF
-DCMAKE_C_FLAGS="-m32 -fsanitize=address -O1 -fno-omit-frame-pointer"
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address -m32" -DCMAKE_SHARED_LINKER_FLAGS="-fsanitize=address -m32"

复现步骤

  1. 安装32位工具链和ASAN(Debian/Ubuntu)
1
2
sudo dpkg --add-architecture i386 && sudo apt update
sudo apt install gcc-multilib g++-multilib libc6-dev-i386 libasan6:i386
  1. 配置和构建libcurl(从仓库根目录)
1
2
3
mkdir build-asan32 && cd build-asan32
cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=ON -DBUILD_CURL_EXE=OFF -DCURL_DISABLE_MQTT=OFF -DCURL_ENABLE_SSL=OFF -DCURL_DISABLE_NTLM=ON -DCURL_USE_LIBPSL=OFF -DUSE_LIBIDN2=OFF -DUSE_NGHTTP2=OFF -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF -DCMAKE_C_FLAGS="-m32 -fsanitize=address -O1 -fno-omit-frame-pointer" -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address -m32" -DCMAKE_SHARED_LINKER_FLAGS="-fsanitize=address -m32" ..
make -j
  1. 启动发送CONNACK的最小MQTT代理(单独shell)
1
python3 poc/fake_mqtt_broker.py 18830
  1. 构建PoC客户端
1
gcc -m32 -fsanitize=address -Iinclude -Lbuild-asan32/lib poc/mqtt_publish_overflow_poc.c -o poc/poc_mqtt -lcurl-d -Wl,-rpath,$PWD/build-asan32/lib
  1. 运行PoC
1
LD_LIBRARY_PATH=build-asan32/lib ./poc/poc_mqtt mqtt://127.0.0.1:18830/a
  1. 观察:AddressSanitizer报告在lib/mqtt.c::mqtt_publish的payload memcpy处发生堆缓冲区溢出,分配使用了溢出的长度。

关于此PoC的先决条件/限制说明

PoC故意在32位构建上将CURLOPT_POSTFIELDSIZE_LARGE设置为极端值以隔离该漏洞;该值对于行为良好的应用程序来说是不现实的,并且超过了MQTT的剩余长度限制。实际的利用通常需要"网关误用"模式,即应用程序将攻击者控制的大小转发到CURLOPT_POSTFIELDSIZE(_LARGE),而不强制执行合理的边界或MQTT限制,也不确保内存中的payload与大小匹配(或在32位上运行,剩余长度可能溢出)。在64位构建上,这通常表现为大分配失败而不是溢出。

支持材料/参考文献

支持材料/参考文献

  • 咨询文档:SEC-ADV-libcurl-MQTT-PUBLISH-length-overflow.md
  • PoC文件:
    • poc/mqtt_publish_overflow_poc.c(客户端设置大的POSTFIELDSIZE_LARGE)
    • poc/fake_mqtt_broker.py(发送CONNACK的最小代理)

ASAN崩溃摘录

1
2
3
4
ERROR: AddressSanitizer: heap-buffer-overflow
    in mqtt_publish (lib/mqtt.c:629) during memcpy(&pkt[i], payload, payloadlen)
    allocation at lib/mqtt.c:617 used wrapped length (remaininglength + 1 + encodelen)
    called from mqtt_doing (lib/mqtt.c:949)

影响

摘要

  • 技术影响:客户端中MQTT PUBLISH数据包组装期间的基于堆的缓冲区溢出。在受影响的构建上可靠的拒绝服务(崩溃);内存损坏的进一步影响取决于分配器/加固和环境。

攻击者所需能力

  • 主要:能够影响或设置应用程序作为MQTT payload长度转发到libcurl的大小(例如,通过上游不受信任的元数据如HTTP Content-Length、JSON"size"字段、CLI/配置或插件输入控制CURLOPT_POSTFIELDSIZE/CURLOPT_POSTFIELDSIZE_LARGE)。
  • 不需要代理控制;发送CONNACK的良性或伪造代理足以驱动代码路径。MITM可以加速/保证此状态,但无法自行设置长度。

平台前提条件:在32位构建上最实用(或size_t < curl_off_t的情况),常见于嵌入式/遗留系统或某些CI/容器中。在64位上,这通常表现为大分配行为而不是溢出,除非调用者严重误用API。

受影响范围:使用libcurl与mqtt://和POST的应用程序。该问题独立于TLS;它在任何PUBLISH放入网络之前发生。

时间线

  • 2025年10月23日,10:29 UTC:max_from_secmate向curl提交报告
  • 2025年10月23日,10:37 UTC:max_from_secmate邀请另一位黑客作为合作者
  • 2025年10月23日,10:38 UTC:ramtine作为合作者加入此报告
  • 2025年10月23日,10:42 UTC:bagder(curl工作人员)发表评论:“这虽然是API的(严重)误用。在32位机器上,很难指向4294967295字节的数据…”
  • 2025年10月23日,10:45 UTC:bagder(curl工作人员)发表评论:“我们不认为由API误用引起的问题是安全问题”
  • 2025年10月23日,11:22 UTC:max_from_secmate发表评论:“谢谢Daniel的回复。我们同意这个问题涉及API误用。我们最初犹豫是否报告,但觉得还是值得引起您的注意”
  • 15天前:bagder(curl工作人员)关闭报告并将状态更改为"不适用"
  • 11天前:bagder(curl工作人员)请求披露此报告
  • 10天前:bagder(curl工作人员)披露此报告

报告详情

  • 报告日期:2025年10月23日,10:28 UTC
  • 报告者:max_from_secmate
  • 报告对象:curl
  • 报告ID:#3395666
  • 严重程度:低(0.1 ~ 3.9)
  • 披露日期:2025年10月28日,7:08 UTC
  • 弱点:堆溢出
  • CVE ID:无
  • 赏金:无
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计