
CVE-2024-20154 का तकनीकी विश्लेषण, MediaTek MT6769 NB-IoT बेसबैंड फर्मवेयर में स्टैक-आधारित बफ़र ओवरफ़्लो, जिसमें रिवर्स इंजीनियरिंग और एक्सप्लॉइटेशन चेन शामिल है।
वर्गीकरण: CWE-121 — स्टैक-आधारित बफ़र ओवरफ़्लो
गंभीरता: क्रिटिकल (MediaTek बुलेटिन) · 8.8 उच्च, अटैक वेक्टर: आसन्न (CISA-ADP)
प्रकार: रिमोट कोड एक्ज़ीक्यूशन — कोई उपयोगकर्ता इंटरैक्शन नहीं, कोई पूर्व संबद्धता नहीं
प्रकटीकरण: MediaTek सुरक्षा बुलेटिन, 6 जनवरी, 2025 https://corp.mediatek.com/product-security-bulletin/January-2025
विश्लेषित लक्ष्य: Samsung Galaxy A14 SM-A145R — MT6769 परिवार (Helio G80), MediaTek की प्रभावित चिपसेट सूची के भीतर - फ़र्मवेयर को सुरक्षित परिस्थितियों में एमुलेट किया गया था।
स्थिति: पैच किया गया।
यह मेरा पहला प्रकाशित बेसबैंड शोध था। मैं एक ऐसी पृष्ठभूमि से आता हूँ जो दूर है टेलीकॉम इन्फ्रास्ट्रक्चर, लॉफुल इंटरसेप्शन मीडिएशन लेयर्स, स्टिंगरे और IMSI-कैचर विश्लेषण, और एम्बेडेड डिवाइस सुरक्षा से — मैंने पहले सेलुलर मॉडेम पर गहरा फ़र्मवेयर रिवर्स इंजीनियरिंग नहीं किया था। मैं स्वयं को यह साबित करना चाहता था कि एक संरचित विश्लेषणात्मक कार्यप्रणाली विभिन्न लक्ष्यों पर अनुकूलित होती है, और यह कि किसी विशिष्ट प्लेटफ़ॉर्म की परिचितता को कठोर चेन-ट्रेसिंग से प्रतिस्थापित किया जा सकता है। NB-IoT इसलिए अलग दिखा क्योंकि यह वास्तव में एक खतरनाक प्रतिच्छेदन पर स्थित है: प्रोटोकॉल को सीमित IoT उपकरणों के लिए डिज़ाइन किया गया है, हमले की सतह पूर्व-संबद्धता है, और मॉडेम स्टैक इसे संसाधित करता है चाहे हैंडसेट उपयोगकर्ता कुछ भी कर रहा हो।
जब पैच किए गए फ़र्मवेयर का विश्लेषण किया गया और कमजोर पैटर्न की अनुपस्थिति की पुष्टि हुई, तो विशिष्ट कार्यों को लक्षित करने से पहले फ़र्मवेयर के बड़े पैमाने पर विश्लेषण के लिए उपयोग किया गया AI सिस्टम
स्वतंत्र रूप से पुनर्निर्मित बग वर्ग, स्थितियों, और प्रभावित फ़र्मवेयर परिवार को CVE-2024-20154 के विवरण से मिलान किया।
तकनीकी निष्कर्ष विश्लेषक के स्वयं के हैं।
आपकी जेब में मौजूद फ़ोन में कम से कम दो अलग-अलग कंप्यूटर हैं। जिसके साथ आप इंटरैक्ट करते हैं वह Android चलाता है। दूसरा — बेसबैंड — पूरी तरह से स्वतंत्र रूप से चलता है, सभी रेडियो संचार को संभालता है, और इसके ऊपर के ऑपरेटिंग सिस्टम के लिए लगभग पूरी तरह से अदृश्य है। Android पूरी तरह से पैच किया गया हो सकता है। ब्राउज़र सैंडबॉक्स्ड हो सकता है। उपयोगकर्ता कभी भी किसी दुर्भावनापूर्ण लिंक पर टैप न करे। इनमें से कोई भी मायने नहीं रखता यदि कमजोर कोड उस मॉडेम फ़र्मवेयर में है जो रेडियो सिग्नल को एप्लिकेशन प्रोसेसर के शामिल होने से पहले संसाधित करता है।
CVE-2024-20154 बिल्कुल इसी प्रकार की कमजोरी है।
एक विकृत NB-IoT सिस्टम-सूचना प्रसारण MediaTek मॉडेम फ़र्मवेयर को एक हमलावर-नियंत्रित शेड्यूलिंग काउंट स्वीकार करने, उस काउंट को RRC-से-L1 कॉन्फ़िगरेशन पथ के माध्यम से बिना कभी क्लैंप किए ले जाने, और अंततः इसे NB-IoT ब्रॉडकास्ट-चैनल हैंडलर के अंदर एक स्टैक-राइटिंग लूप के लूप बाउंड के रूप में उपयोग करने का कारण बनता है। जब काउंट गंतव्य सरणियों की क्षमता से अधिक हो जाता है, तो लूप उनसे आगे लिखता है, स्टैक पर सहेजे गए रजिस्टरों तक पहुँचता है, और सहेजे गए रिटर्न एड्रेस को अधिलेखित कर देता है। फिर फ़ंक्शन भ्रष्ट मान को रिटर्न-एड्रेस रजिस्टर में पुनर्स्थापित करता है और उस पर जंप करता है।
गंभीरता को जो चीज़ यह बनाती है:
यह कमजोरी MediaTek के 6 जनवरी, 2025 सुरक्षा बुलेटिन में क्रिटिकल गंभीरता रेटिंग के साथ प्रकाशित की गई थी, जो अन्य के अलावा LR12A मॉडेम परिवार को प्रभावित करती है। Samsung ने फ़िक्स को अपनी फरवरी 2025 सुरक्षा रखरखाव रिलीज़ में शामिल किया।
यह पोस्ट कोई हथियारबंद एक्सप्लॉइट प्रकाशित नहीं करती है और यहाँ जो प्रकाशित है उससे पुनरुत्पादनीय नहीं है। लक्ष्य यह दिखाना है कि चेन कहाँ टूटती है, प्रत्येक परत इसे रोकने में क्यों विफल रही, और जब आप लाइव मॉडेम से डीबगर संलग्न नहीं कर सकते तो बेसबैंड बग को ज़िम्मेदारी से मान्य करने में क्या लगता है।
प्राथमिक लक्ष्य: Samsung Galaxy A14 (SM-A145R)। रेडियो सबसिस्टम को MT6769 चिपसेट परिवार (Helio G80) में एक MediaTek बेसबैंड प्रोसेसर द्वारा संचालित किया जाता है। MT6769 परिवार CVE-2024-20154 के लिए MediaTek की प्रभावित चिपसेट सूची में स्पष्ट रूप से सूचीबद्ध है।``` AP/CP firmware: A145RXXU1AWD1 Modem software: MOLY LR12A.R3.TC10.6M.A14.PR.SP.V1.P5 Build date: 2023-04-18
बेसबैंड फर्मवेयर Android कोड नहीं है। यह SoC के रेडियो सबसिस्टम पर एक अलग एम्बेडेड सिस्टम है, जिसका अपना CPU, अपना RTOS, और अपना मेमोरी स्पेस है, जो Android प्रोसेस सैंडबॉक्स के बाहर है।
### 2.2 मॉडेम आर्किटेक्चर
निकाले गए बाइनरी के विश्लेषण से पता चलता है कि मॉडेम प्रोसेसर MIPS32 को लिटिल-एंडियन मोड में MIPS16e2 कंप्रेस्ड इंस्ट्रक्शन्स के साथ चलाता है। MIPS16e2 एम्बेडेड कोड-साइज़ कमी के लिए एक 16-बिट एन्कोडिंग एक्सटेंशन है — जो MediaTek के Helio-जनरेशन बेसबैंड के लिए दृष्टिकोण के अनुरूप है, जिसकी पुष्टि इस SoC परिवार पर स्वतंत्र रूप से प्रकाशित बेसबैंड शोध द्वारा की गई है।
ऑपरेटिंग सिस्टम Nucleus RTOS है, जो टास्क शेड्यूलिंग, IPC मैसेज क्यूज़, और एक पूल-आधारित मेमोरी एलोकेटर प्रदान करता है। इसमें कोई कर्नेल/यूज़र प्रिविलेज सेपरेशन नहीं है, टास्क के बीच कोई मेमोरी प्रोटेक्शन यूनिट एनफोर्समेंट नहीं है, और कोई हार्डवेयर स्टैक-गार्ड मेकैनिज़्म नहीं है।
इस पोस्ट में सभी एड्रेस वर्चुअल एड्रेस हैं, जैसा कि Ghidra में बेस `0x90000000` पर लोड किए गए हैं।
### 2.3 मिटिगेशन्स (विश्लेषित बिल्ड में देखे गए)
| मिटिगेशन | स्थिति | प्रभाव |
|---|---|---|
| ASLR | अनुपस्थित | फर्मवेयर एड्रेस स्थिर और इमेज से पूर्वानुमेय हैं |
| स्टैक कैनरी | अनुपस्थित | `SAVE`/`RESTORE` कैली-सेव्ड रजिस्टर्स को बिना किसी गार्ड वैल्यू के स्टोर करता है |
| NX / W^X | अनुपस्थित | स्टैक मेमोरी एक्ज़ीक्यूटेबल है |
| CFI | अनुपस्थित | रिटर्न एड्रेस किसी भी पॉलिसी के विरुद्ध वैलिडेट नहीं किए जाते |
### 2.4 विश्लेषण दृष्टिकोण
तीन समानांतर ट्रैक:
**स्टैटिक विश्लेषण।** Samsung फर्मवेयर पैकेज → CP पार्टीशन एक्सट्रैक्शन → `md1img.img` → Ghidra (MIPS LE 32-bit, बेस `0x90000000`) के साथ MediaTek इंजीनियरिंग सिंबल्स जो NCC Group `mtk_bp` टूलसेट का उपयोग करके फर्मवेयर डीबग सेक्शन से रिकवर किए गए।
**डायनामिक वैलिडेशन।** Unicorn Engine (MIPS32 एमुलेशन) का उपयोग दो चरणों में विशिष्ट फर्मवेयर रूटीन्स को अलगाव में निष्पादित करने के लिए किया गया था। चरण 1 ने नेटिव इंस्ट्रक्शन पेयर के माध्यम से चैनल कॉन्टेक्स्ट में `si_count` की अनक्लैम्प्ड कॉपी को सिद्ध करने का प्रयास किया। चरण 2 ने वास्तविक फर्मवेयर बाइट्स पर कमज़ोर लूप को निष्पादित किया और पुष्टि की कि फर्मवेयर के स्वयं के इंस्ट्रक्शन्स सेव्ड रिटर्न एड्रेस को करप्ट कर देते हैं। जहाँ चरण 1 पूरी तरह से नेटिव रूप से नहीं चल सका — क्योंकि CPHY डिस्पैच पाथ द्वारा आवश्यक RTOS सर्विस-ऑब्जेक्ट एनवायरनमेंट का पुनर्निर्माण नहीं किया गया था — वहाँ साइड इफेक्ट को सीधे मॉडल किया गया और सभी आउटपुट में उसी रूप में लेबल किया गया।
**रेडियो-साइड वैलिडेशन।** srsRAN 4G के साथ एक ZMQ लूपबैक — केवल सॉफ़्टवेयर, कोई RF एमिशन नहीं — ने पुष्टि की कि टेस्ट पेलोड NB-IoT PHY एन्कोडिंग और ट्रांसपोर्ट-ब्लॉक डिलीवरी से बच जाता है।
---
## 3. अटैक सरफेस: NB-IoT और SIB1-NB
### 3.1 प्री-एसोसिएशन अटैक सरफेस
NB-IoT (Narrowband Internet of Things) 3GPP Release 13 है, जिसे मौजूदा लाइसेंस्ड LTE स्पेक्ट्रम का उपयोग करके सीमित IoT डिवाइसों को जोड़ने के लिए डिज़ाइन किया गया है। यह उपभोक्ता स्मार्टफोन सहित आधुनिक सेलुलर SoCs की एक विस्तृत श्रृंखला में लागू किया गया है।
RRC_IDLE में रहते हुए, किसी भी RRC कनेक्शन के स्थापित होने से पहले, सेवा की खोज करने वाला डिवाइस:
1. सेल के टाइमिंग सिग्नल्स (NPSS/NSSS) के साथ सिंक्रोनाइज़ करेगा
2. NPBCH पर Master Information Block को डिकोड करेगा (640 ms ट्रांसमिशन विंडो)
3. NPDSCH से SIB1-NB को डिकोड करेगा (2560 ms शेड्यूल)
4. SIB1-NB में शेड्यूलिंग जानकारी का उपयोग करके अतिरिक्त सिस्टम इन्फॉर्मेशन ब्लॉक्स का पता लगाएगा
चरण 3 पर, मॉडेम एक ऐसी एंटिटी से संदेश प्रोसेस करता है जिसे उसने प्रमाणित नहीं किया है, किसी भी कनेक्शन या उपयोगकर्ता इंटरैक्शन से पहले। सामान्य सेल सेलेक्शन शर्तों को पूरा करने वाला एक रोग ट्रांसमीटर प्रोसेस किया जाएगा।```
+------------------+ +---------------------+
| Rogue Base Stn | | Target UE (Modem) |
+--------+---------+ +----------+----------+
| |
| NPSS/NSSS sync |
|--------------------------------------->|
| MIB-NB (640 ms cycle) |
|--------------------------------------->|
| SIB1-NB (malformed, si_count > 8) |
|--------------------------------------->| ← vulnerability triggered
| [no RRC connection established] |
SIB1-NB को 3GPP TS 36.331 में परिभाषित किया गया है। इसका schedulingInfoList फ़ील्ड यह रखता है कि सेल कितने System Information संदेश प्रसारित करता है, जिसे स्पेक द्वारा अधिकतम 8 प्रविष्टियों तक सीमित किया गया है (1..maxSI-Message-NB-r13 = 8)। यह एक प्रोटोकॉल-लेयर बाधा है। मेमोरी-सुरक्षा बाधा — कि सूची की लंबाई गंतव्य सरणियों की क्षमता से अधिक नहीं होनी चाहिए — को फर्मवेयर द्वारा अलग से लागू किया जाना चाहिए।
यह लागू नहीं किया गया था।
फर्मवेयर एक Samsung CP पैकेज से प्राप्त किया गया था और NCC Group mtk_bp टूलसेट का उपयोग करके निकाला गया था:```
md1img.img → md1_extract.py → 000_md1rom (17.8 MB code image)
→ 017_md1_dbginfo (XZ-compressed CATI debug symbols)
CATI डीबग अनुभाग को डीकंप्रेस किया गया और `mtk_dbg_extract.py symbols` के साथ पार्स किया गया, फिर
`ImportSymbolsScript.py` के माध्यम से Ghidra में आयात किया गया। परिणामस्वरूप पूरे मॉडेम स्टैक में पूर्ण आंतरिक फ़ंक्शन
नाम प्राप्त हुए — ERRC लेयर, L1 चैनल प्रबंधन, IPC सबसिस्टम, और
NB-IoT BCCH हैंडलर श्रृंखला — जिससे सेमांटिक्स-निर्देशित श्रृंखला पुनर्निर्माण संभव हुआ।
इस पोस्ट में सभी फ़ंक्शन नाम MediaTek के स्वयं के एम्बेडेड डीबग प्रतीकों से लिए गए हैं जो
फर्मवेयर इमेज से निकाले गए थे।
---
## 5. भेद्यता
### 5.1 भेद्य लूप
`el1_ch_nbcch_resume_req` (`0x90213940`) NB-IoT ब्रॉडकास्ट-चैनल रिज़्यूम इवेंट को संभालता है।
इसका MIPS16e2 फ़ंक्शन प्रोलॉग:```asm
90213940: save 0xE8, ra, s0-s1
SAVE निर्देश sp को 0xE8 से घटाता है और callee-saved रजिस्टरों को नीचे की ओर संग्रहीत करता है:```
old_sp (= new_sp + 0xE8)
new_sp + 0xE4 saved ra ← overflow target
new_sp + 0xE0 saved s1
new_sp + 0xDC saved s0
new_sp + 0x98 si_sched_arr [34 halfwords = 68 bytes]
new_sp + 0x78 si_type_arr [32 bytes]
new_sp + 0x00 ← stack pointer after SAVE
Ghidra द्वारा वास्तविक फर्मवेयर बाइनरी के डीकंपाइल से:```c
for (uVar6 = 0; uVar6 < (byte)param_2[0x40a]; uVar6 = uVar6 + 1) {
si_type_arr[uVar6] = /* SI type byte */; // 1 byte/iter, base new_sp+0x78
si_sched_arr[uVar6] = /* SI schedule halfword */; // 2 bytes/iter, base new_sp+0x98
}
param_2[0x40a] ch_ctx[+0x40A] है — चैनल कॉन्टेक्स्ट BSS स्ट्रक्चर में एक स्थायी बाइट।
लूप बाउंड का उपयोग सीधे किया जाता है, एरे क्षमताओं के विरुद्ध किसी पूर्व तुलना के बिना।
स्ट्रीम A (हाफवर्ड sh राइट्स) new_sp+0x98 से शुरू होती है और प्रति इटरेशन 2 बाइट्स आगे बढ़ती है।
यह इटरेशन 38 पर new_sp+0xE4 पर सहेजे गए RA तक पहुँचती है:```
new_sp + 0x98 + i×2 = new_sp + 0xE4
i = (0xE4 - 0x98) / 2 = 0x4C / 2 = 38
Stream B (बाइट `sb` राइट्स) `new_sp+0x78` से शुरू होता है और RA स्लॉट तक पहुँचने के लिए पुनरावृत्ति 108 की आवश्यकता होगी:```
new_sp + 0x78 + i = new_sp + 0xE4
i = 0xE4 - 0x78 = 108
si_count = 40 के साथ (प्रदर्शक मान, जिसे 38 की ओवरफ़्लो सीमा से अधिक होने के लिए चुना गया है)
लूप 40 पुनरावृत्तियाँ चलाता है। Stream B कभी RA स्लॉट तक नहीं पहुँचता। RA भ्रष्टाचार
पूरी तरह से Stream A से आता है।
40 पुनरावृत्तियों के बाद MIPS16e2 RESTORE निर्देश स्टैक से भ्रष्ट मान को
$ra में पुनः लोड करता है, और jrc ra नियंत्रण स्थानांतरित करता है।
ch_ctx[+0x40A] को el1_ch_nbcch_start द्वारा 0x90213444 पर लिखा जाता है। दो क्रमागत MIPS
निर्देश जिनके बीच कुछ भी नहीं है:```asm
; el1_ch_nbcch_start @ 0x90213444
lbu v0, 0x99(s0) ; read IPC_msg[+0x99] = si_count from CPHY_CFG_REQ
sb v0, 0x40A(s1) ; write to ch_ctx[+0x40A] — no clamp, no mask, no compare
### 5.4 ERRC बिल्डर — लेयर A
CPHY_CFG_REQ बफ़र ERRC लेयर में डिकोड किए गए SIB1-NB से बनाया जाता है। फ़ंक्शन
`errc_chm_l1_set_bcch_si_reception` `IPC_msg[+0x99]` लिखता है:```c
// errc_chm_l1_set_bcch_si_reception — Layer A
// Loop bound: decoded schedulingInfoList entry count from SIB1-NB
while (bVar3 < *(byte *)(param_3 + 0x44) && (param_2 != 0)) {
bVar3++;
if (uVar2 != param_2) {
*param_5 = *param_5 + 1; // CPHY_CFG_REQ[+0x99]++ — no upper bound check
}
}
लूप बाउंड SIB1-NB से डिकोड किए गए एंट्री काउंट है। काउंटर प्रति डिकोड की गई एंट्री पर एक बार बढ़ता है, जितनी एंट्रियाँ डिकोड की गईं उतनी बार, बिना किसी अधिकतम गार्ड के।
एक बार CPHY_CFG_REQ बफ़र भर जाने के बाद, ERRC इसे sap_id = 0x501F के साथ रूटिंग कुंजी के रूप में L1 को भेजता है:```
el1_ch_rcv_ilm (sap 0x501F)
→ el1_chmgm_errc_cfg_req_in_idle ← stores CPHY_CFG_REQ @ L1_ctx[+0x323C]
→ el1_chmgm_nbcch_handler
→ el1_ch_nbcch_main
→ el1_ch_nbcch_cphy_cfg_req_process ← validates cell identity, no si_count check
→ el1_ch_nbcch_start @ 0x90213444 ← Layer B: lbu + sb, no clamp
### 5.6 क्लैम्पिंग की तीन-परत अनुपस्थिति
| परत | फ़ंक्शन | पता | क्लैम्प मौजूद? |
|---|---|---|---|
| A — ERRC बिल्डर | `errc_chm_l1_set_bcch_si_reception` | ERRC रेंज | **कोई नहीं** |
| B — L1 कॉपी | `el1_ch_nbcch_start` | `0x90213444` | **कोई नहीं** |
| C — L1 लूप | `el1_ch_nbcch_resume_req` | `0x90213940` | **कोई नहीं** |
किसी भी एक परत पर कोई भी एकल जाँच श्रृंखला को तोड़ देती।
### 5.7 मूल कारण
एक उल्लंघित इनवेरिएंट:
> SI शेड्यूलिंग प्रविष्टियों की संख्या कभी भी गंतव्य ऐरे की क्षमता से अधिक नहीं होनी चाहिए।
3GPP इच्छित प्रोटोकॉल बाउंड (8 प्रविष्टियाँ) प्रदान करता है। फ़र्मवेयर को प्रत्येक परत पर मेमोरी-सुरक्षा बाउंड लागू करने की आवश्यकता थी जहाँ गणना एक इंडेक्स या लूप सीमा बन जाती है। कमज़ोर बिल्ड में, गणना SIB1-NB ब्रॉडकास्ट फ़ील्ड से ERRC डिकोडर के माध्यम से, CPHY_CFG_REQ संदेश में, IPC सीमा के पार L1 टास्क में, चैनल कॉन्टेक्स्ट BSS में, और स्टैक-राइटिंग लूप में यात्रा करती थी — बिना किसी परत द्वारा इसे क्लैम्प किए।
---
## 6. कॉल चेन — यह कैसे पाया गया
### 6.1 दो-पथ की उलझन
दो संरचनात्मक रूप से समान लेकिन भिन्न पथ `el1_ch_nbcch_main` को 0x760-बाइट कॉन्फ़िगरेशन बफ़र पहुँचा सकते हैं:
| पथ | स्रोत | `[+0x99]` मान | प्रासंगिकता |
|---|---|---|---|
| पथ A (ERRC → L1 IPC) | ERRC डिकोड किए गए SIB1-NB से CPHY_CFG_REQ बनाता है | OTA से `schedulingInfoList.count` | **कमज़ोर पथ** |
| पथ B (L1 आंतरिक) | `el1_ch_scs_ind_send` आंतरिक IPC बॉडी बनाता है | हार्डकोडेड `1` | कमज़ोर नहीं |
पथ B ने संदेश प्रारूप की पुष्टि की — बाइट `+0x99` वह SI गणना है जिसे `el1_ch_nbcch_start` उपभोग करता है। चूँकि इसकी गणना हमेशा 1 पर हार्डकोडेड होती है, यह ओवरफ़्लो नहीं कर सकती। बाहरी रूप से प्रभावित पथ पथ A है।
### 6.2 राइटर खोज
ऑफ़सेट `+0x99` पर लिखने वाले किसी भी निर्देश के लिए फ़र्मवेयर को पैटर्न-सर्च करने पर शोर उत्पन्न हुआ:
T1 (प्रत्यक्ष `sb`, ~100 हिट), T2 (स्प्लिट बेस, 5 हिट), T3 (गणना किया गया ऑफ़सेट, 0), T4
(ओवरलैपिंग `sh`/`sw`, ~465)। ERRC चैनल प्रबंधन फ़ंक्शन `msg_send6` क्रॉस-रेफ़रेंस सूची से अनुपस्थित थे क्योंकि ERRC `errc_com_send_msg` का उपयोग करता है। एक एमुलेशन प्रोब ने पुष्टि की कि राइट ERRC-पक्ष था: L1 डिस्पैचर से Unicorn हार्नेस चलाना और बफ़र के `+0x99` ऑफ़सेट पर राइट्स की निगरानी करना L1 पक्ष से कुछ भी कैप्चर नहीं किया।```
[RUN] dispatcher=0x90214418 watching IPC_msg+0x99
NO writes to IPC_msg+0x99 caught from dispatcher.
Write happened before el1_ch_nbcch_main — confirmed ERRC-side.
errc_com_send_msg में sap_id = 0x501F का अनुसरण करने पर
el1_chmgm_errc_cfg_req_in_idle तक की रूटिंग की पहचान हुई, जो CPHY_CFG_REQ पॉइंटर को
L1_ctx[+0x323C] पर संग्रहीत करता है और डाउनस्ट्रीम डिस्पैच प्रारंभ करता है।
SIB1-NB schedulingInfoList.count (demonstrator: 40) │ ▼ [ERRC task] errc_chm_ch_ctrl_req_hdlr → errc_chm_call_ctrl → errc_chm_l1_main → errc_chm_l1_call_ctrl → errc_chm_l1_snd_cphy_cfg_req ← allocates 0x760-byte CPHY_CFG_REQ → errc_chm_l1_set_cphy_req_nbcch_cfg → errc_chm_l1_set_bcch_inf → errc_chm_l1_set_bcch_si_reception ← Layer A: CPHY_CFG_REQ[+0x99] = 40 → errc_com_send_msg(sap=0x501F) ← IPC to L1 │ ▼ [L1 task] el1_ch_rcv_ilm (sap 0x501F) → el1_chmgm_errc_cfg_req_in_idle ← stores CPHY_CFG_REQ @ L1_ctx[+0x323C] → el1_chmgm_nbcch_handler → el1_ch_nbcch_main → el1_ch_nbcch_cphy_cfg_req_process ← no si_count validation → el1_ch_nbcch_start @ 0x90213444 ← Layer B: lbu + sb, no clamp │ ▼ ch_ctx[0x40A] = 40 (persists in BSS) │ ▼ [state machine advances to 0x0B, event 0x2C] el1_ch_nbcch_resume_req @ 0x90213940 ← Layer C: loop bound from ch_ctx[0x40A] │ ▼ stack overflow → jrc ra → PC = attacker-controlled
---
## 7. सत्यापन
यह विशिष्ट SM-A145R मॉडल सामान्य ship-build संचालन में कमजोर NB-IoT कोड पथ का उपयोग नहीं करता प्रतीत होता है, यही कारण है कि प्रत्यक्ष हार्डवेयर पुनरुत्पादन के बजाय हाइब्रिड एमुलेशन और स्थिर विश्लेषण का उपयोग किया गया।
**स्थिर रूप से सिद्ध।** फर्मवेयर बाइनरी में कमजोर निर्देश युग्म मौजूद है। कॉल श्रृंखला को प्रतीकों, क्रॉस-रेफरेंस और डीकंपाइल किए गए फ़ंक्शन निकायों से पुनर्निर्मित किया गया है।
**एमुलेशन में मूल रूप से निष्पादित।** `el1_ch_nbcch_resume_req` के अंदर का लूप Unicorn Engine (MIPS32) में वास्तविक MediaTek फर्मवेयर बाइट्स पर चला। फर्मवेयर का स्वयं का `sh` निर्देश `0x90213B02` पर सहेजे गए रिटर्न-एड्रेस स्लॉट में लिखा। `RESTORE` निर्देश ने भ्रष्ट मान को `$ra` में लोड किया, और `jrc ra` ने नियंत्रण स्थानांतरित किया।
**स्पष्ट रूप से मॉडल किया गया।** `el1_ch_nbcch_start` में `lbu`/`sb` प्रतिलिपि पूरी तरह से मूल रूप से नहीं चलाई जा सकी क्योंकि `el1_ch_nbcch_cphy_cfg_req_process` के भीतर RTOS कॉलबैक-टेबल डिस्पैच पथ को जीवित Nucleus हीप ऑब्जेक्ट्स की आवश्यकता थी जो फ्लैट एमुलेटर ने प्रदान नहीं किए। चरण 2 में रिज्यूम हैंडलर (`el1_ch_nbcch_resume_req`) केवल BSS-निवासी चैनल संदर्भ से पढ़ता है और उसी डिस्पैच पथ को नहीं छूता, यही कारण है कि चरण 2 समान स्कैफोल्डिंग की आवश्यकता के बिना मूल रूप से चला। चरण 1 का साइड इफेक्ट — `IPC_msg[+0x99]` से एक बाइट `ch_ctx[+0x40A]` में लिखी गई — को सीधे मॉडल किया गया और `[PHASE1-MODEL]` लेबल किया गया।
**दावा नहीं किया गया।** एक पूर्ण एंड-टू-एंड ओवर-द-एयर हार्डवेयर पुनरुत्पादन।
### 7.1 एंटी-टैम्पर
हार्नेस ने एक नियम लागू किया: किसी भी हुक को सहेजे गए रिटर्न-एड्रेस स्लॉट में प्रूफ मार्कर लिखने की अनुमति नहीं थी। प्रत्येक गैर-फर्मवेयर मेमोरी लेखन को ट्रैक किया गया।```
[PROOF-W] saved_RA write: pc=0x90213b02 addr=new_sp+0xE4 value=0xbeef
[PROOF-W] saved_RA write: pc=0x90213b02 addr=new_sp+0xE6 value=0xdead
[ANTI-TAMPER] no hook wrote RA=0xDEADBEEF — firmware only
anti_tamper_fail = False
0x90213B02 लूप बॉडी के अंदर sh निर्देश है। फर्मवेयर ने इन बाइट्स को
अनुमानित स्टैक ऑफ़सेट पर रखा। लिटिल-एंडियन स्टोरेज में, new_sp+0xE4 और new_sp+0xE6 पर
हाफवर्ड्स 0xBEEF और 0xDEAD मिलकर [ef be ad de] = 0xDEADBEEF बनाते हैं।
[REGS] RA = 0xdeadbeef ← firmware wrote this; decisive proof PC = 0x00000000 ← Unicorn unmapped-fetch artifact, not a hardware exception vector
[STACK] new_sp+0xE4: [ef be ad de] ← little-endian 0xDEADBEEF
[PC-EXPLAIN] PC=0 is an unmapped-fetch artifact; decisive proof is RA=0xDEADBEEF + stack bytes [ef be ad de] + [PROOF-JRC] CONFIRMED: saved RA = 0xDEADBEEF
### 7.3 ZMQ डिलीवरी
यह पुष्टि करने के लिए कि टेस्ट पेलोड NB-IoT PHY एन्कोडिंग और ट्रांसपोर्ट-ब्लॉक डिलीवरी से बच जाता है, ZMQ लूपबैक (कोई RF उत्सर्जन नहीं) के साथ srsRAN 4G का उपयोग किया गया। पेलोड जानबूझकर एक गैर-अनुरूप वेक्टर था — `schedulingInfoList` पर ASN.1 SIZE बाधा को 40 प्रविष्टियों की अनुमति देने के लिए शिथिल किया गया था, जिसमें pycrate राउंड-ट्रिप डिकोड बाइट 14 पर काउंट फ़ील्ड की पुष्टि करता है।```
SIB1 received
SIB2 activated
exit 0
यह ट्रांसपोर्ट-लेयर डिलीवरी की पुष्टि करता है। फर्मवेयर-साइड ASN.1 व्यवहार Layer A स्टैटिक विश्लेषण द्वारा स्थापित किया गया है।
el1_ch टास्क में एक ही स्टैक है। चरण 1 और चरण 2 दो अलग-अलग IPC इवेंट हैं जिन्हें उसी टास्क द्वारा क्रमिक रूप से प्रोसेस किया जाता है, और इनके बीच स्टैक पूरी तरह से अनवाइंड हो जाता है। काउंट स्टैक पर नहीं, बल्कि चैनल कॉन्टेक्स्ट BSS में पर्सिस्ट रहता है:```
EVENT: CPHY_CFG_REQ (Phase 1)
el1_ch_nbcch_start
lbu v0, 0x99(s0)
sb v0, 0x40A(s1) ← ch_ctx[0x40A] = attacker value, written to BSS
returns — stack fully unwound
EVENT: resume (state 0x0B, msg 0x2C) (Phase 2) el1_ch_nbcch_resume_req ← frame 0xE8, reads ch_ctx[0x40A] as loop bound loop × 40 → saved RA corrupted jrc ra → attacker-controlled PC
`ch_ctx[0x40A]` BSS में रहता है और मॉडेम के रीसेट होने या बाद के चैनल कॉन्फ़िगरेशन द्वारा इसे ओवरराइट किए जाने तक हमलावर के मान को बनाए रखता है।
### 8.2 स्टैक फ़्रेम```
old_sp (= new_sp + 0xE8)
new_sp + 0xE4 saved ra
new_sp + 0xE0 saved s1
new_sp + 0xDC saved s0
new_sp + 0x98 si_sched_arr [34 halfwords = 68 bytes]
new_sp + 0x78 si_type_arr [32 bytes]
फ्रेम आकार की पुष्टि एमुलेशन माप द्वारा की गई। ऐरे स्थितियों की पुष्टि एमुलेशन
परिणाम द्वारा की गई — RA को इटरेशन 38 पर लिखा गया, जो si_sched_arr के new_sp+0x98 से
शुरू होने के अनुरूप है।
| बिल्ड | मॉडेम फ़र्मवेयर | बिल्ड दिनांक |
|---|---|---|
| कमज़ोर | A145RXXU1AWD1, MOLY LR12A...V1.P5 | 2023-04-18 |
| पैच किया गया | A145RXXUDDZC2, MOLY LR12A...V3.P8 |
बिल्ड दिनांकों की पुष्टि दोनों इमेज से md1_dbginfo मेटाडेटा निकालकर की गई। पैच ID:
MOLY00720348 · इश्यू ID: MSV-2392।
el1_ch_nbcch_start (कमज़ोर बाइनरी में 0x90213444): lbu/sb इंस्ट्रक्शन
युग्म अनुपस्थित है। IPC_msg[+0x99] का ch_ctx[+0x40A] में सीधा कॉपी होना हटा दिया गया है।
el1_ch_nbcch_resume_req (कमज़ोर बाइनरी में 0x90213940): ch_ctx[0x40A] पर
स्टैक-राइटिंग लूप अनुपस्थित है। वह आर्किटेक्चर जहाँ एक अविश्वसनीय बाइट निश्चित-आकार के
स्टैक ऐरे पर लूप बाउंड बन जाती है, अब मौजूद नहीं है। फ़ंक्शन बॉडी को एक भिन्न
डिस्पैच संरचना से बदल दिया गया है।
errc_chm_l1_set_bcch_si_reception: अनबाउंडेड काउंटर लूप को
वैलिडेशन-उन्मुख हेल्पर कॉल्स से बदल दिया गया है।
पैच की गई बाइनरी में मौजूद दो फ़ंक्शन कमज़ोर बाइनरी में अनुपस्थित हैं:``` el1_ch_nbcch_param_check el1_ch_scell_param_check
एकल-पंक्ति बाउंड्स चेक एक ही पते पर मौजूद फ़ंक्शन के अंदर कुछ जोड़े गए निर्देशों के रूप में दिखाई देगा। पैच किए गए बाइनरी में जो दिखता है वह एक आर्किटेक्चरल संशोधन है:
NBCCH शेड्यूलिंग पथ को इस तरह से पुनः डिज़ाइन किया गया था कि `si_count`-as-loop-bound पैटर्न अब पथ में कहीं भी मौजूद नहीं है।
### 10.4 CVE एट्रिब्यूशन
यहाँ वर्णित भेद्यता MediaTek द्वारा 6 जनवरी, 2025 को प्रकाशित CVE-2024-20154 से मेल खाती है। पुष्टि का आधार:
- प्रभावित फ़र्मवेयर परिवार (LR12A) MediaTek के बुलेटिन से मेल खाता है।
- भेद्यता वर्ग — स्टैक ओवरफ़्लो, अनुपस्थित बाउंड्स चेक, रोग बेस स्टेशन से RCE,
कोई उपयोगकर्ता इंटरैक्शन नहीं — CVE विवरण और NVD रिकॉर्ड से मेल खाता है।
- पैच किया गया फ़र्मवेयर उन कोड संरचनाओं को हटा देता है जिन्हें भेद्य के रूप में पहचाना गया था।
- पैच ID MOLY00720348 की पुष्टि MediaTek के बुलेटिन और Android Security Bulletin
(A-376809176) से हुई।
- AI-सहायित विश्लेषण ने मैन्युअल पुष्टि से पहले पुनर्निर्मित पैटर्न को स्वतंत्र रूप से CVE-2024-20154 से मिलान किया।
---
## 11. नैतिकता और जिम्मेदार प्रकटीकरण
### 11.1 इस पोस्ट में क्या नहीं है
कोई हथियारीकृत एक्सप्लॉइट नहीं। कोई फ़र्मवेयर बाइनरी सामग्री नहीं। कोई विकृत पेलोड बाइट्स नहीं। किसी लाइव डिवाइस के विरुद्ध भेद्यता को ट्रिगर करने की कोई चरण-दर-चरण प्रक्रिया नहीं। एक कार्यशील हमले को पुनरुत्पादित करने के लिए आवश्यक जानकारी — विशिष्ट मॉडेम डिकोडर के लिए पूर्ण पेलोड निर्माण, पूर्ण Phase 1 एमुलेशन के लिए RTOS हीप-ऑब्जेक्ट स्कैफ़ोल्डिंग, ओवर-द-एयर रेडियो कॉन्फ़िगरेशन — जानबूझकर अनुपस्थित है।
### 11.2 ZMQ लूपबैक और एमुलेशन नैतिक दृष्टिकोण क्यों हैं
ZMQ लूपबैक का अर्थ है कि कोई सिग्नल कभी भी हवा में प्रसारित नहीं किया गया। किसी वास्तविक डिवाइस को लक्षित नहीं किया गया। कोई कैरियर नेटवर्क शामिल नहीं था। प्रमाण पूरी तरह से विश्लेषक के स्वामित्व वाले हार्डवेयर पर एक संरोधित सॉफ़्टवेयर वातावरण में चलता है। यह प्री-एसोसिएशन रेडियो भेद्यता को मान्य करने के लिए सही दृष्टिकोण है — एक विकृत ब्रॉडकास्ट प्रसारित करना रेंज के भीतर किसी भी डिवाइस को प्रभावित करेगा।
Unicorn एमुलेशन प्रदर्शित करता है कि भेद्य व्यवहार फ़र्मवेयर बाइनरी में ही है, पुनरुत्पादनीय रूप से, किसी विशिष्ट डिवाइस स्थिति या रेडियो वातावरण से स्वतंत्र। यह एकल हार्डवेयर क्रैश की तुलना में तकनीकी रूप से मजबूत दावा है, और यह हवा में कुछ भी तैनात करने से बचता है।
### 11.3 MediaTek बौद्धिक संपदा
सभी विश्लेषण एक उपभोक्ता डिवाइस से वैध रूप से प्राप्त फ़र्मवेयर और Samsung के सार्वजनिक रूप से जारी फ़र्मवेयर पैकेजों पर किया गया था। कोई स्वामित्व वाला दस्तावेज़ीकरण उपयोग नहीं किया गया। आंतरिक MediaTek स्ट्रक्ट परिभाषाएँ और IPC संदेश प्रारूपों का वर्णन केवल उस सीमा तक किया गया है जो मेमोरी-सुरक्षा विफलता को समझाने के लिए आवश्यक है। उन्हें विनिर्देशों के रूप में प्रकाशित नहीं किया गया है।
---
| पुनरावृत्ति | sh यहाँ लिखता है | प्रभाव |
|---|
| 0–33 | si_sched_arr[0..33] | सीमा के भीतर |
| 34–35 | new_sp+0xDC — सहेजा गया s0 | s0 भ्रष्ट |
| 36–37 | new_sp+0xE0 — सहेजा गया s1 | s1 भ्रष्ट |
| 38 | new_sp+0xE4 — सहेजा गया ra [15:0] | RA निम्न हाफ़वर्ड |
| 39 | new_sp+0xE6 — सहेजा गया ra [31:16] | RA उच्च हाफ़वर्ड |
| गेट | शर्त | कहाँ जाँचा गया |
|---|
| NB-IoT सक्रिय पथ | cfg_type == 1 | el1_ch_nbcch_cphy_cfg_req_process |
| चैनल पूर्ण नहीं | done_flag == 0 | ch_ctx[0x438] |
स्टेट मशीन 0x0B | NBCCH रिज़्यूम स्थिति में | el1_ch_nbcch_main डिस्पैच |
| si_count शून्येतर | ch_ctx[0x40A] > 0 | लूप शर्त |
| बैंड क्लास ≤ 2 | वैध NB-IoT मोड | el1_ch_nbcch_resume_req का प्रवेश |
el1_chmgm_cell_info_get शून्येतर | सेल सेवा तालिका में | el1_ch_nbcch_start में कॉल किया गया |
| फ़ंक्शन | पता | भूमिका | क्लैंप? |
|---|
errc_chm_l1_set_bcch_si_reception | ERRC रेंज | CPHY_CFG_REQ[+0x99] लिखता है | कोई नहीं |
el1_ch_nbcch_cphy_cfg_req_process | 0x90213F80 | CPHY कॉन्फ़िग को L1 में रूट करता है | लागू नहीं — si_count नहीं पढ़ता |
el1_chmgm_cell_info_get | 0x9020E0D0 | EARFCN/PCI को मान्य करता है | लागू नहीं |
el1_ch_nbcch_start | 0x90213444 | काउंट को BSS में कॉपी करता है | कोई नहीं |
el1_ch_nbcch_resume_req | 0x90213940 | काउंट को लूप बाउंड के रूप में उपयोग करता है | कोई नहीं |
| 2025-04-23 |