Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2024-20154 — تحليل تقني لـ CVE-2024-20154، وهو تجاوز سعة المخزن المؤقت المعتمد على المكدس في البرنامج الثابت للنطاق الأساسي MediaTek MT6769 NB-IoT، يغطي الهندسة العكسية وسلسلة الاستغلال. | Kitploit
أدوات/GitHubGitHub/harbingerse7en/cve-2024-20154
أمان الأنظمة المدمجةأمان إنترنت الأشياءتحليل الذاكرة الجنائيتحليل الثغرات الأمنيةالهندسة العكسيةأمن الجوالأمان الأجهزة وإنترنت الأشياءتحليل الملفات الثنائيةالأوراق والأبحاثالتعلم والتعليمتحليل البرامج الثابتة
منذ 3 أشهرلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة
GitHub
harbingerse7en/cve-2024-20154

CVE-2024-20154

تحليل تقني لـ CVE-2024-20154، وهو تجاوز سعة المخزن المؤقت المعتمد على المكدس في البرنامج الثابت للنطاق الأساسي MediaTek MT6769 NB-IoT، يغطي الهندسة العكسية وسلسلة الاستغلال.

عرض المستودع

CVE-2024-20154: تجاوز سعة المكدس في SIB1-NB لـ NB-IoT في نطاق MediaTek MT6769 الأساسي

التصنيف: 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 - تمت محاكاة البرنامج الثابت في ظروف آمنة. الحالة: تم الترقيع.


الخلفية والدافع

كان هذا أول بحث منشور لي في النطاق الأساسي. أنا آتي من خلفية بعيدة عن البنية التحتية للاتصالات، وطبقات الوساطة للاعتراض القانوني، وتحليل stingray و IMSI-catcher، وأمن الأجهزة المدمجة — لم أكن قد قمت سابقًا بهندسة عكسية معمّقة للبرنامج الثابت على مودم خلوي. أردت أن أثبت لنفسي أن منهجية تحليلية منظمة تتكيف عبر الأهداف المختلفة، وأن الإلمام بمنصة معينة يمكن استبداله بتتبع سلسل صارم. برز NB-IoT لأنه يقع عند تقاطع خطير حقًا: البروتوكول مصمم لأجهزة إنترنت الأشياء محدودة الموارد، وسطح الهجوم قبل الارتباط، وتعالجه حزمة المودم بغض النظر عما يفعله مستخدم الهاتف.

عند تحليل البرنامج الثابت المُرقَّع والتأكد من غياب النمط الثغرة، فإن نظام الذكاء الاصطناعي المستخدم للتحليل الشامل للبرنامج الثابت قبل استهداف وظائف محددة

طابق بشكل مستقل فئة الخطأ المُعاد بناؤها، والظروف، وعائلة البرنامج الثابت المتأثرة مع وصف CVE-2024-20154.

الاستنتاجات التقنية هي استنتاجات المحلل نفسه.


1. مقدمة

يحتوي الهاتف في جيبك على حاسوبين منفصلين على الأقل. الذي تتفاعل معه يشغّل Android. والآخر — النطاق الأساسي — يعمل بشكل مستقل تمامًا، ويتعامل مع جميع الاتصالات اللاسلكية، ويكاد يكون غير مرئي تمامًا لنظام التشغيل الذي يعلوه. قد يكون Android مُرقَّعًا بالكامل. قد يكون المتصفح معزولًا. قد لا ينقر المستخدم أبدًا على رابط ضار. لا شيء من ذلك يهم إذا كان الكود الثغرة موجودًا في البرنامج الثابت للمودم الذي يعالج الإشارات اللاسلكية قبل أن يكون معالج التطبيقات متورطًا.

CVE-2024-20154 هو بالضبط هذا النوع من الثغرات.

تسبب بث معلومات نظام NB-IoT مشوّه في قبول البرنامج الثابت لمودم MediaTek لعدد جدولة يتحكم فيه المهاجم، وتمرير هذا العدد عبر مسار تكوين RRC-to-L1 دون تقييده أبدًا، واستخدامه في النهاية كحد للحلقة لحلقة كتابة على المكدس داخل معالج قناة البث NB-IoT. عندما يتجاوز العدد سعة المصفوفات الوجهة، تكتب الحلقة خارجها، وتصل إلى السجلات المحفوظة على المكدس، وتستبدل عنوان العودة المحفوظ. ثم تستعيد الدالة القيمة التالفة في سجل عنوان العودة وتقفز إليها.

ما يجعل الخطورة على ما هي عليه:

  • يتم تنفيذ مسار الكود الثغرة أثناء المخيم على الخلية — بعد المزامنة مع خلية ولكن قبل أي اتصال RRC، وأي مصادقة، وأي تفاعل من المستخدم.
  • المدخل هو بث عبر الأثير. لا يمكن للهاتف مصادقة المصدر.
  • يعمل البرنامج الثابت للنطاق الأساسي في البناء المُحلَّل بدون ASLR، وبدون canaries للمكدس، وبدون مكدس غير قابل للتنفيذ، وبدون سلامة تدفق التحكم. تُترجم الكتابة فوق عنوان العودة المحفوظ مباشرة إلى التحكم في عداد البرنامج.

نُشرت الثغرة في نشرة MediaTek الأمنية بتاريخ 6 يناير 2025 بتصنيف خطورة حرجة، وتؤثر على عائلة مودم LR12A من بين أخرى. أدرجت Samsung الإصلاح في إصدار الصيانة الأمنية لشهر فبراير 2025.

لا ينشر هذا المنشور استغلالًا مسلحًا وليس قابلًا لإعادة الإنتاج من ما هو منشور هنا. الهدف هو إظهار أين تنكسر السلسلة، ولماذا فشلت كل طبقة في إيقافها، وما يتطلبه التحقق من خطأ النطاق الأساسي بمسؤولية عندما لا يمكنك إرفاق مصحح أخطاء بالمودم الحي.


2. الهدف والبيئة

2.1 الجهاز والبرنامج الثابت

الهدف الأساسي: Samsung Galaxy A14 (SM-A145R). يُدار النظام الفرعي اللاسلكي بواسطة معالج النطاق الأساسي من MediaTek في عائلة شرائح MT6769 (Helio G80). عائلة MT6769 مدرجة صراحةً في قائمة الشرائح المتأثرة لدى MediaTek لـ CVE-2024-20154.``` AP/CP firmware: A145RXXU1AWD1 Modem software: MOLY LR12A.R3.TC10.6M.A14.PR.SP.V1.P5 Build date: 2023-04-18

root@kitploit:~
قاعدة البرمجيات الثابتة (firmware) ليست كود Android. إنها نظام مضمّن منفصل على النظام الفرعي الراديوي في SoC، بمعالج خاص بها، ونظام تشغيل زمن حقيقي (RTOS) خاص بها، ومساحة ذاكرة خاصة بها، خارج صندوق حماية عمليات Android.

### 2.2 معمارية المودم

يُظهر تحليل الملف الثنائي المستخرج أن معالج المودم يعمل بمعمارية MIPS32 مع تعليمات MIPS16e2 المضغوطة في وضع little-endian. إن MIPS16e2 هو امتداد ترميز 16-بت لتقليل حجم الكود المضمّن — بما يتوافق مع نهج MediaTek لقواعد النطاق الأساسي من جيل Helio، وهو ما تؤكده أبحاث النطاق الأساسي المنشورة المستقلة على هذه العائلة من SoC.

نظام التشغيل هو Nucleus RTOS، الذي يوفر جدولة المهام، وقوائم انتظار رسائل IPC، ومخصّص ذاكرة قائم على التجمعات (pool-based). لا يوجد فصل صلاحيات بين النواة/المستخدم، ولا فرض لوحدة حماية الذاكرة بين المهام، ولا آلية حماية مكدس عتادية.

جميع العناوين في هذا المنشور هي عناوين افتراضية، كما تم تحميلها في Ghidra عند القاعدة `0x90000000`.

### 2.3 إجراءات التخفيف (الملاحظة في البناء المُحلَّل)

| إجراء التخفيف | الحالة | التأثير |
|---|---|---|
| ASLR | غائب | عناوين البرمجيات الثابتة ساكنة وقابلة للتنبؤ من الصورة |
| Stack canary | غائب | تخزّن `SAVE`/`RESTORE` السجلات المحفوظة من المستدعي دون قيمة حماية |
| NX / W^X | غائب | ذاكرة المكدس قابلة للتنفيذ |
| CFI | غائب | لا يتم التحقق من عناوين العودة مقابل أي سياسة |

### 2.4 منهجية التحليل

ثلاثة مسارات متوازية:

**التحليل الساكن.** حزمة برمجيات Samsung الثابتة → استخراج قسم CP → `md1img.img` → Ghidra (MIPS LE 32-بت، القاعدة `0x90000000`) مع رموز MediaTek الهندسية المستعادة من قسم تصحيح البرمجيات الثابتة باستخدام مجموعة أدوات `mtk_bp` من NCC Group.

**التحقق الديناميكي.** تم استخدام Unicorn Engine (محاكاة MIPS32) لتنفيذ روتينات محددة من البرمجيات الثابتة بمعزل عن غيرها عبر مرحلتين. حاولت المرحلة 1 إثبات النسخ غير المقيّد لـ `si_count` إلى سياق القناة عبر زوج التعليمات الأصلي. نفّذت المرحلة 2 الحلقة القابلة للاستغلال على بايتات البرمجيات الثابتة الحقيقية وأكدت أن تعليمات البرمجيات الثابتة نفسها تُفسد عنوان العودة المحفوظ. حيث لم تتمكن المرحلة 1 من العمل بشكل أصلي بالكامل — لأن بيئة كائن خدمة RTOS التي يتطلبها مسار إرسال CPHY لم تتم إعادة بنائها — تم نمذجة الأثر الجانبي مباشرةً وتسميته على هذا النحو في جميع المخرجات.

**التحقق من الجانب الراديوي.** srsRAN 4G مع ZMQ loopback — برمجي فقط، دون انبعاث RF — أكد أن حمولة الاختبار تنجو من ترميز NB-IoT PHY وتسليم كتلة النقل.

---

## 3. سطح الهجوم: NB-IoT و SIB1-NB

### 3.1 سطح الهجوم قبل الارتباط

NB-IoT (النطاق الضيق لإنترنت الأشياء) هو 3GPP الإصدار 13، مصمم لربط أجهزة إنترنت الأشياء المحدودة باستخدام طيف LTE المرخّص الموجود. وهو مُنفَّذ في مجموعة واسعة من أنظمة SoC الخلوية الحديثة بما في ذلك تلك الموجودة في الهواتف الذكية الاستهلاكية.

أثناء وجوده في RRC_IDLE، قبل إنشاء أي اتصال RRC، فإن الجهاز الذي يبحث عن خدمة سيقوم بـ:

1. المزامنة مع إشارات التوقيت الخاصة بالخلية (NPSS/NSSS)
2. فك ترميز كتلة المعلومات الرئيسية عبر NPBCH (نافذة إرسال 640 مللي ثانية)
3. فك ترميز SIB1-NB من NPDSCH (جدولة 2560 مللي ثانية)
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]      |

3.2 حقل عدد الجدولة

يُعرَّف SIB1-NB في 3GPP TS 36.331. يحمل حقل schedulingInfoList الخاص به عدد رسائل معلومات النظام التي تبثها الخلية، مقيَّدًا بالمواصفة بحد أقصى 8 مدخلات (1..maxSI-Message-NB-r13 = 8). هذا قيد على مستوى البروتوكول. أما قيد أمان الذاكرة — وهو أن طول القائمة يجب ألا يتجاوز سعة المصفوفات الوجهة — فيجب أن يُفرض بشكل منفصل بواسطة البرنامج الثابت.

ولم يحدث ذلك.


4. استخراج البرنامج الثابت واستعادة الرموز

تم الحصول على البرنامج الثابت من حزمة Samsung CP واستخراجه باستخدام مجموعة أدوات mtk_bp من NCC Group:``` md1img.img → md1_extract.py → 000_md1rom (17.8 MB code image) → 017_md1_dbginfo (XZ-compressed CATI debug symbols)

root@kitploit:~
تم فك ضغط قسم تصحيح CATI وتحليله باستخدام `mtk_dbg_extract.py symbols`، ثم
استُورد إلى Ghidra عبر `ImportSymbolsScript.py`. كانت النتيجة أسماء دوال داخلية كاملة
في جميع أنحاء حزمة المودم — طبقة 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

root@kitploit:~
من Ghidra decompile للـ firmware binary الفعلي:```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 الخاصة بسياق القناة. يُستخدم حد الحلقة مباشرةً، دون مقارنة مسبقة مع سعات المصفوفة.

5.2 حساب التجاوز الحسابي

يبدأ التدفق A (كتابات sh للنصف كلمة) عند new_sp+0x98 ويتقدم بمقدار بايتين في كل تكرار. يصل إلى RA المحفوظ عند new_sp+0xE4 عند التكرار 38:``` new_sp + 0x98 + i×2 = new_sp + 0xE4 i = (0xE4 - 0x98) / 2 = 0x4C / 2 = 38

root@kitploit:~
يبدأ Stream B (كتابة البايت `sb`) عند `new_sp+0x78` وسيتطلب التكرار 108 للوصول
إلى خانة RA:```
new_sp + 0x78 + i = new_sp + 0xE4
i = 0xE4 - 0x78 = 108

مع si_count = 40 (قيمة العرض التوضيحي، المختارة لتتجاوز عتبة التجاوز البالغة 38) تنفذ الحلقة 40 تكرارًا. لا يصل Stream B أبدًا إلى فتحة RA. يأتي تلف RA بالكامل من Stream A.

بعد 40 تكرارًا، تعيد تعليمة RESTORE الخاصة بـ MIPS16e2 تحميل القيمة المتلفة من المكدس إلى $ra، وينقل jrc ra التحكم.

5.3 النسخة غير المقيدة — الطبقة B

يُكتب 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

root@kitploit:~
### 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. يزداد العداد مرة واحدة لكل مدخل مفكوك، لعدد المدخلات التي تم فكها، دون حارس أقصى.

5.5 مسار IPC

بمجرد أن يتم ملء المخزن المؤقت CPHY_CFG_REQ، يرسله ERRC إلى L1 باستخدام sap_id = 0x501F كمفتاح التوجيه:``` 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

root@kitploit:~
### 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 الالتباس بين المسارين

يمكن لمسارين متشابهين بنيويًا لكن متمايزين توصيل مخزن تهيئة بحجم 0x760 بايت إلى
`el1_ch_nbcch_main`:

| المسار | المصدر | قيمة `[+0x99]` | الصلة |
|---|---|---|---|
| المسار A (ERRC → L1 IPC) | يبني ERRC رسالة CPHY_CFG_REQ من SIB1-NB المُفكَّك | `schedulingInfoList.count` من OTA | **المسار المصاب** |
| المسار 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: تشغيل أداة Unicorn من مُوزِّع L1
ومراقبة الكتابات إلى إزاحة `+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.

6.3 الحل عبر مفتاح توجيه IPC

أدى تتبع sap_id = 0x501F في errc_com_send_msg إلى تحديد التوجيه نحو el1_chmgm_errc_cfg_req_in_idle، الذي يخزّن مؤشر CPHY_CFG_REQ عند L1_ctx[+0x323C] ويبدأ الإرسال في المسار النازل.

6.4 سلسلة الاستدعاء المؤكدة```

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

root@kitploit:~
---

## 7. التحقق

لا يبدو أن طراز SM-A145R المحدد هذا يستخدم
مسار كود NB-IoT القابل للاستغلال في عملية البناء العادية، ولهذا تم استخدام المحاكاة الهجينة
والتحليل الساكن بدلاً من إعادة الإنتاج المباشر على العتاد.

**مُثبت بشكل ساكن.** يحتوي ملف البرنامج الثابت على زوج التعليمات القابل للاستغلال. تم
إعادة بناء سلسلة الاستدعاء من الرموز والإحالات المرجعية وأجسام الدوال المفككة.

**نُفّذ أصلياً في المحاكاة.** حلقة `el1_ch_nbcch_resume_req` الداخلية عملت على بايتات
برنامج ثابت MediaTek حقيقية في Unicorn Engine (MIPS32). كتبت تعليمة `sh` الخاصة بالبرنامج
الثابت عند `0x90213B02` إلى خانة عنوان العودة المحفوظ. حمّلت تعليمة `RESTORE` القيمة
التالفة إلى `$ra`، ونقلت `jrc ra` التحكم.

**مُنمذج بشكل صريح.** لم يكن من الممكن تشغيل نسخة `lbu`/`sb` في `el1_ch_nbcch_start`
بشكل أصلي بالكامل لأن مسار إرسال جدول الاستدعاءات في RTOS ضمن `el1_ch_nbcch_cphy_cfg_req_
process` كان يتوقع كائنات كومة Nucleus حية لم يوفرها المحاكي المسطح. معالج الاستئناف
(`el1_ch_nbcch_resume_req`) في المرحلة 2 يقرأ فقط من سياق القناة المقيم في 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 داخل جسم الحلقة. وضعت البرامج الثابتة هذه البايتات عند إزاحة المكدس المتوقعة. في التخزين little-endian، تتحد الأنصاف 0xBEEF و0xDEAD عند new_sp+0xE4 وnew_sp+0xE6 لتكوّن [ef be ad de] = 0xDEADBEEF.

7.2 نتيجة المحاكاة```

[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

root@kitploit:~
### 7.3 تسليم ZMQ

لتأكيد أن حزمة الاختبار تنجو من ترميز NB-IoT PHY وتسليم كتلة النقل، تم استخدام srsRAN 4G مع حلقة ZMQ (بدون انبعاث RF). كانت الحزمة عبارة عن متجه غير مطابق بشكل متعمد — تم تخفيف قيد ASN.1 SIZE على `schedulingInfoList` للسماح بـ 40 مدخلاً، مع تأكيد فك ترميز pycrate ذهابًا وإيابًا لحقل العدد عند البايت 14.```
SIB1 received
SIB2 activated
exit 0

هذا يؤكد التسليم على مستوى طبقة النقل. يتم إثبات سلوك ASN.1 من جانب البرنامج الثابت بواسطة التحليل الساكن للطبقة A.


8. آليات تدفق التحكم

8.1 مرحلتان، مهمة واحدة، حالة دائمة

مهمة 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

root@kitploit:~
`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.


9. الأدلة

9.1 البوابات قبل الحلقة القابلة للاستغلال

9.2 الدوال المؤكد أنها لا تُقيّد si_count


10. تحليل الترقيع

10.1 الإصدارات

البناءبرنامج المودم الثابتتاريخ البناء
قابل للاستغلالA145RXXU1AWD1، MOLY LR12A...V1.P52023-04-18
مُرقَّعA145RXXUDDZC2، MOLY

تم تأكيد تواريخ البناء عن طريق استخراج بيانات md1_dbginfo الوصفية من كلا الصورتين. معرّف الترقيع: MOLY00720348 · معرّف المشكلة: MSV-2392.

10.2 ما الذي تغيّر

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: تم استبدال حلقة العدّاد غير المحدودة باستدعاءات دوال مساعدة موجهة نحو التحقق.

10.3 دوال التحقق الجديدة

دالتان موجودتان في الثنائي المُرقَّع وغائبتان من الثنائي القابل للاستغلال:``` el1_ch_nbcch_param_check el1_ch_scell_param_check

root@kitploit:~
فحص الحدود أحادي السطر سيظهر كتعليمات قليلة مضافة داخل دالة موجودة
عند نفس العنوان. ما يُظهره الملف الثنائي المُرقَّع هو مراجعة معمارية:
أُعيد تصميم مسار جدولة NBCCH بحيث لم يعد نمط `si_count`-كحد-حلقة
موجودًا في أي مكان في المسار.

### 10.4 إسناد CVE

تتوافق الثغرة الموصوفة هنا مع CVE-2024-20154 كما نشرتها MediaTek في 6 يناير
2025. أساس التأكيد:

- عائلة البرنامج الثابت المتأثرة (LR12A) تتطابق مع نشرة MediaTek.
- فئة الثغرة — تجاوز سعة المكدس، غياب فحص الحدود، تنفيذ كود عن بُعد من محطة قاعدة
  خبيثة، دون تفاعل المستخدم — تتطابق مع وصف CVE وسجل NVD.
- يزيل البرنامج الثابت المُرقَّع بالضبط بنى الكود المُحدَّدة كضعيفة.
- معرّف التصحيح MOLY00720348 مؤكَّد من نشرة MediaTek ونشرة أمان Android
  (A-376809176).
- طابقت التحليلات المدعومة بالذكاء الاصطناعي بشكل مستقل النمط المُعاد بناؤه مع CVE-2024-20154
  قبل التأكيد اليدوي.

---

## 11. الأخلاقيات والإفصاح المسؤول

### 11.1 ما لا تحتويه هذه التدوينة

لا يوجد استغلال مُسلَّح. لا يوجد محتوى ثنائي للبرنامج الثابت. لا توجد بايتات حِمل مشوَّهة. لا
يوجد إجراء خطوة بخطوة لتفعيل الثغرة ضد جهاز حي. المعلومات اللازمة لإعادة إنتاج هجوم فعّال —
بناء الحِمل الكامل لفاكّ ترميز المودم المحدد، سقالات كائنات كومة RTOS لمحاكاة المرحلة 1 الكاملة،
تكوين الراديو عبر الأثير — غائبة عن قصد.

### 11.2 لماذا ZMQ loopback والمحاكاة هما النهج الأخلاقي

ZMQ loopback يعني أنه لم تُرسَل أي إشارة عبر الأثير قط. لم يُستهدف أي جهاز حقيقي.
لم تكن أي شبكة مشغّل متورطة. يعمل الإثبات بالكامل في بيئة برمجية محتواة
على أجهزة يملكها المحلل. هذا هو النهج الصحيح للتحقق من ثغرة راديو
قبل الارتباط — فإرسال بث مشوَّه سيؤثر على أي جهاز ضمن النطاق.

تُظهر محاكاة Unicorn أن السلوك الضعيف موجود في الملف الثنائي للبرنامج الثابت نفسه،
بشكل قابل للتكرار، بمعزل عن أي حالة جهاز محددة أو بيئة راديو. هذا ادعاء
أقوى تقنيًا من انهيار جهاز واحد، ويتجنب نشر أي شيء
عبر الأثير.

### 11.3 الملكية الفكرية لـ MediaTek

أُجري كل التحليل على برنامج ثابت تم الحصول عليه بشكل مشروع من جهاز استهلاكي ومن
حزم البرامج الثابتة التي أصدرتها Samsung علنًا. لم تُستخدم أي وثائق
خاصة. تُوصَف تعريفات البنى الداخلية لـ MediaTek وتنسيقات رسائل IPC فقط بالقدر
الضروري لشرح فشل أمان الذاكرة. وهي غير منشورة كمواصفات.

---
تنزيل الأداة
التكرارsh يكتب إلىالتأثير
0–33si_sched_arr[0..33]داخل الحدود
34–35new_sp+0xDC — s0 المحفوظتلف s0
36–37new_sp+0xE0 — s1 المحفوظتلف s1
38new_sp+0xE4 — ra المحفوظ [15:0]النصف السفلي من RA
39new_sp+0xE6 — ra المحفوظ [31:16]النصف العلوي من RA
البوابةالشرطمكان التحقق
مسار NB-IoT النشطcfg_type == 1el1_ch_nbcch_cphy_cfg_req_process
القناة غير مكتملةdone_flag == 0ch_ctx[0x438]
آلة الحالة 0x0BNBCCH في حالة الاستئنافإرسال 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_process0x90213F80يوجّه إعداد CPHY إلى L1لا ينطبق — لا يقرأ si_count
el1_chmgm_cell_info_get0x9020E0D0يتحقق من EARFCN/PCIلا ينطبق
el1_ch_nbcch_start0x90213444ينسخ العدد إلى BSSلا يوجد
el1_ch_nbcch_resume_req0x90213940يستخدم العدد كحد للحلقةلا يوجد
LR12A...V3.P8
2025-04-23