
नंगे PCB से root तक: अपने स्वयं के हार्डवेयर पर UART के माध्यम से ZyXEL P-870HN (BCM6368) की हार्डवेयर हैकिंग — CVE-2025-0890 + CVE-2024-40891
एक बिना लेबल वाले राउटर बोर्ड की दो फ़ोन तस्वीरें → सीरियल कंसोल → ऑथ बायपास → रूट शेल — मेरे अपने हार्डवेयर पर वास्तविक, अभी भी अनपैच्ड चेन CVE-2025-0890 (छिपा हुआ supervisor खाता) + CVE-2024-40891 (CLI कमांड इंजेक्शन) का पुनरुत्पादन।
damik0 द्वारा · 2026-08-13 · एक हार्डवेयर-हैकिंग वॉकथ्रू
📷 PCB photos ─▶ 🔬 chip recon ─▶ 🏷️ model ID ─▶ 📍 find UART (J2)
└─▶ 🔌 serial console ─▶ 🚪 hidden account ─▶ ⛓️ break out of CLI
└─▶ 🐚 root shell ─▶ 🔓 dump + crack every credential
मेरी डेस्क पर एक अनजान राउटर बोर्ड पड़ा था। न केस, न लेबल, न कोई अंदाज़ा कि यह क्या है। केवल उसकी दो तस्वीरों के साथ शुरू करके, मैंने PCB की हर चिप पढ़ी, सटीक मॉडल की पहचान की, सीरियल (UART) हेडर ढूँढा, उसमें जुड़ा, एक फ़ैक्टरी बैकडोर खाते से अंदर घुसा, लॉक-डाउन वेंडर मेनू से बाहर निकलकर रूट Linux शेल में पहुँचा, और बॉक्स से हर पासवर्ड निकाल लिया — एक सेकंड से भी कम समय में क्रैक कर दिया।
इनमें से कोई भी बग मेरा नहीं है। ये प्रलेखित ZyXEL समस्याएँ हैं जिन्हें वेंडर ने पैच नहीं करने की बात कही है। इस रेपो का विषय कैसे है — शुरू से अंत तक — और हर चरण पर तर्क।
मैंने सिल्कस्क्रीन बोर्ड नंबर 45-402-000022 और बारकोड से पहचान निकाली, और TechInfoDepot, OpenWrt की हार्डवेयर तालिका और FCC ID I88P870HN51B के साथ क्रॉस-रेफ़रेंस किया:
| मॉडल | ZyXEL P-870HN-53b — VDSL2/ADSL2+ WiFi गेटवे, MitraStar द्वारा निर्मित |
| समय-काल | ~2013 (डेट-कोड सप्ताह 21 / 2013 की ओर इशारा करते हैं); एक ISP-वितरित यूनिट |
| SoC | Broadcom BCM6368UKPBG — डुअल-कोर MIPS (BMIPS4350), ~400 MHz |
| RAM | 2× Winbond W9425G6JH-5 — 256 Mbit DDR2 ×16 प्रत्येक = 32-बिट बस पर 64 MB |
| फ़्लैश | Macronix MX29LV640EBTI-70G — 8 MB पैरेलल NOR, TSOP-48 |
| WiFi | Broadcom BCM43222 (802.11n; डुअल-बैंड सिलिकॉन, केवल 2.4 GHz से जुड़ा) |
| DSL AFE | Broadcom BCM6302 |
| फ़र्मवेयर | Linux 2.6.30 + BusyBox v1.00, Broadcom CFE बूटलोडर (निर्माण 2012-06-11) |
बोर्ड नंबर ही वह चाबी क्यों है जो सब कुछ खोलती है: इस तरह के ODM गेटवे रेफ़रेंस डिज़ाइन होते हैं। जैसे ही सिल्कस्क्रीन पार्ट नंबर किसी प्रलेखित बोर्ड से मेल खाता है, आपको किसी और का होमवर्क विरासत में मिल जाता है — सटीक फ़्लैश चिप, UART का स्थान और पिनआउट, डिफ़ॉल्ट खाते। पहचान कोई औपचारिकता नहीं है; यही अंधी जाँच को लक्षित हमले में बदल देती है।
सबसे पहले एक छोटी सी सहूलियत: मैंने एक छोटा-सा LAN फ़ोटो-अपलोडर (Python stdlib, शून्य निर्भरताएँ) जल्दी से बना लिया ताकि मैं बोर्ड की फ़ोन से तस्वीर ले सकूँ और तस्वीरें सीधे मेरी मशीन पर आ जाएँ। एक अच्छे सत्र का आधा हिस्सा इस तरह की अड़चनों को खत्म करना है।
मैंने हाई-रेज़ तस्वीरों पर चिप-दर-चिप नज़र डाली। पैकेज प्रकार आपको निशान पढ़ने से पहले ही कहानी बता देते हैं: बीच में BGA दिमाग है, TSOP-48 लगभग हमेशा पैरेलल फ़्लैश होती है, और कोएक्स पिगटेल वाला छोटा डिब्बा रेडियो है। SoC एक RF शील्ड के नीचे छिपा था (EMI के लिए और हीट स्प्रेडर के रूप में), इसलिए मैंने नीचे का निशान पढ़ने के लिए डिब्बा खोला — एक Broadcom BCM6368।

बोर्ड का नक्शा: (1) BCM6368 SoC, (2) DDR2 RAM, (3) BCM43222 WiFi, (4) DSL लाइन ट्रांसफ़ॉर्मर, (5) ईथरनेट मैग्नेटिक्स, (6) आंतरिक USB हेडर, (7)(8) बोर्ड के निशान, (9) J2 कंसोल हेडर, (10) एक अनपॉपुलेटेड JTAG फ़ुटप्रिंट।
सिल्कस्क्रीन 45-402-000022 प्रलेखित बोर्ड से बिल्कुल मेल खाती थी, और हर चिप — SoC, फ़्लैश, WiFi, 64 MB RAM — टुकड़े-दर-टुकड़े -53b वेरिएंट से मेल खाती थी। अब मैं केवल यह नहीं जानता था कि यह क्या है; मैं जानता था कि इसका UART कहाँ है और कौन-सा खाता मुझे अंदर ले जाएगा।
SoC के ठीक बगल में एक 6-पिन राइट-एंगल हेडर लगा था, जिस पर J2 सिल्कस्क्रीन किया गया था, और पिन 1 पर एक त्रिकोण निशान था। मॉडल के लिए OpenWrt के पेज से पुष्टि की:
| पिन | सिग्नल | |
|---|---|---|
| 1 | VCC 3.3V | इसे कनेक्ट न करें |
| 2 | Tx | → एडाप्टर RX |
| 3 | Rx | → एडाप्टर TX |
| 4 | GND | → एडाप्टर GND |
| 5 | NC |
115200 8N1, 3.3V TTL.

जब कोई विकी आपको पिनआउट न बताए तो UART कैसे खोजें — यह हिस्सा दिखाता है कि यह केवल एक रेसिपी का पालन नहीं है:
- GND — ग्राउंड प्लेन / शील्ड से कंटिन्यूटी (बीप), बोर्ड बिना पावर।
- VCC — एक रेल जो पावर मिलने पर स्थिर ~3.3 V पर रहती है।
- TX — ~3.3 V पर हाई आइडल (UART मार्क स्टेट) करता है और जिस क्षण डिवाइस बूट होकर अपना लॉग उगलना शुरू करता है, साफ़ तौर पर डिप/फ़्लिकर करता है। वह फ़्लिकर ही कंसोल की आवाज़ है।
- RX — आमतौर पर शांत रहता है: फ्लोटिंग या कमज़ोर पुल्ड, कोई बूट गतिविधि नहीं।
और अगर आप बॉड नहीं जानते?
115200Broadcom CFE का डिफ़ॉल्ट है, लेकिन आँख बंद करके आप या तो सामान्य दरों (9600 → 115200) को स्कैन करते जब तक कचरा ASCII में न बदल जाए, या स्कोप पर सबसे संकरी बिट अवधि मापकर1 / tकरते।
मैंने 3.3V पर जम्पर के साथ एक USB-TTL एडाप्टर (HW-597, PL2303) जोड़ा। यह महत्वपूर्ण है: BCM6368 का UART 3.3 V TTL है, न कि RS-232 (±12 V) — इसमें असली सीरियल पोर्ट या 5 V एडाप्टर लगाएँ तो पिन जल जाएगा। पहले GND, फिर RX/TX क्रॉस, VCC फ्लोटिंग छोड़ा ताकि बोर्ड को कुछ बैक-पावर न मिले। पावर देने से पहले मैंने मल्टीमीटर से GND और VCC की पुष्टि की, फिर:
screen /dev/ttyUSB0 115200
इसे पावर किया, CFE को कर्नेल को हैंडऑफ़ करते देखा, BusyBox init को आते देखा, और एक लॉगिन प्रॉम्प्ट पर पहुँचा।
लॉगिन एक छिपे हुए फ़ैक्टरी खाते के आगे झुक गया जिसे ZyXEL अंतिम उपयोगकर्ता के लिए कभी प्रलेखित नहीं करता:
user: supervisor
pass: zyad1234
पूर्ण सिस्टम विशेषाधिकार। यही CVE-2025-0890 का मूल है।
उस लॉगिन ने मुझे एक लॉक-डाउन वेंडर CLI (consoled, एक > प्रॉम्प्ट) में डाल दिया: कोई sh नहीं, कोई भी सामान्य Linux टूल नहीं — असली सिस्टम के चारों ओर लिपटी एक जेल। लेकिन इसमें एक ping डायग्नोस्टिक मौजूद था, और वह कमांड अपने आर्गुमेंट को बिना किसी सैनिटाइज़िंग के सीधे शेल स्ट्रिंग में बना देता था। इसलिए मैंने उसे एक शेल मेटाकैरेक्टर खिला दिया:
> ping 127.0.0.1; sh
…और एक रूट BusyBox शेल (#) में पहुँच गया।
एक सेमीकॉलन ही काफ़ी क्यों है: CLI हैंडलर
system("ping " + userinput)के समकक्ष काम करता है।;pingकमांड को बंद कर देता है और एक दूसरा —sh— शुरू कर देता है, जो कंसोल के stdin/stdout को इनहेरिट करता है, इसलिए आपको एक इंटरैक्टिव शेल मिलता है। खाता पहले से ही uid 0 था; CLI ही एकमात्र चीज़ थी जो मेरे और एक असली शेल के बीच खड़ी थी, और अनसैनिटाइज़्ड इनपुट ने उस दीवार को गिरा दिया। छिपे हुए खाते पर एक प्रमाणित CLI इंजेक्शन को चेन करना ठीक वही पैटर्न है जिसे CVE-2024-40891 के रूप में ट्रैक किया गया है।
रूट के साथ, मैंने सिस्टम और फ़्लैश पर नज़र डाली:
# cat /proc/version
Linux version 2.6.30 ... (Buildroot 2010.02) #1 Mon Jun 11 2012
# cat /proc/mtd
dev: size erasesize name
mtd0: 004f5000 004f5000 "Physically mapped flash" # 5,197,824 bytes = the whole firmware