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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-40003 — استغلال لثغرة CVE-2026-40003، وهي ثغرة كتابة عشوائية في الذاكرة في BootROM الخاص بمعالج ZXIC/Sanechips ZX297520V3 SoC، مما يتيح تنفيذ التعليمات البرمجية عبر وضع التنزيل عبر USB. | Kitploit
أدوات/GitHubGitHub/rva3/cve-2026-40003
أمان الأنظمة المدمجةالاستغلالالهندسة العكسيةاختراق الأجهزةتطوير الحمولاتتحليل البرامج الثابتةاستغلال الملفات الثنائية
GitHubrva3/cve-2026-40003

CVE-2026-40003

استغلال لثغرة CVE-2026-40003، وهي ثغرة كتابة عشوائية في الذاكرة في BootROM الخاص بمعالج ZXIC/Sanechips ZX297520V3 SoC، مما يتيح تنفيذ التعليمات البرمجية عبر وضع التنزيل عبر USB.

عرض المستودع
141منذ 3 أشهرلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

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

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

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

عرض جميع الأدوات →
مشاركة
الموقع الإلكتروني

CVE-2026-40003 المعروف باسم Joselito هو ثغرة كتابة ذاكرة عشوائية تم اكتشافها في BootROM الخاص بمعالج ZXIC/Sanechips ZX297520V3 SoC.

[!CAUTION] تم نشر هذا الـ PoC لأغراض البحث فقط. يجب ألا تستخدم هذا الاستغلال لأي أغراض خبيثة. لا تستخدم الاستغلال على أجهزة لا تملكها أو دون موافقة صريحة من المالك.

الحالة

يجب أن تكون هذه الثغرة قد أُصلحت منذ مارس 2026 في إصدارات SoC الأحدث. لا توجد منتجات معروفة تستخدم رقائق مُصححة حتى الآن. جميع الأجهزة الحالية معرضة للخطر.

كيف يعمل؟

باختصار: اطّلع على كود المُحمّل.

يبدأ BootROM عند العنوان 0x4 مع مؤشر المكدس عند 0x81FF0. يقوم الكود باختيار الوضع بناءً على نقطة اختبار خاصة، أو القدرة على تحميل الصورة من الفلاش. إذا فشل BootROM في تحميل أو التحقق من الصورة على الفلاش، فسوف يتراجع إلى وضع التنزيل عبر USB.

يمكننا ملاحظة هذا السلوك هنا:

root@kitploit:~
v0 = MEMORY[0x13B004] & 7; // hardware pin
switch ( (char)v0 )
{
  case 0:
    if ( nand_init() )
      goto LABEL_12;
    parse_header((Header *)0x8A000);
    v4 = "\nMODE:NAND\n";
    goto LABEL_11;
  case 1:
    if ( !nand_init() )
    {
      parse_header((Header *)0x8A000);
      uart_puts("\nMODE:USB-N\n");
    }
    usbdl_init(0x1500000);
    v5 = "TURN TO NAND\n";
    goto LABEL_16;
/* ... */
LABEL_16:
  uart_puts(v5);
LABEL_7:
  verify_and_jump((Header *)0x8A000, 0, 1);
  break;

تقوم دالة usbdl_init بتهيئة ناقل USB والدخول في حلقة التنزيل:

root@kitploit:~
void __fastcall usbdl_init(int usb_base)
{
  char *v1; // r0

  if ( usb_base == 0x1500000 )
  {
    alt_usb_base = 0;
    usb_init();
  }
  else
  {
    alt_usb_base = 1;
    noidea();
  }
  if ( usb_setup() )
  {
    try_sync_with_host();
    v1 = "FAILED\n";
  }
  else
  {
    v1 = "\nNOLINK\n";
  }
  uart_puts(v1);
}

مخرجات المفكك:

root@kitploit:~
ROM:00001F68 ; void __fastcall usbdl_init(int usb_base)
ROM:00001F68 usbdl_init                              ; CODE XREF: entry+5E↑p
ROM:00001F68                                         ; entry+7C↑p ...
ROM:00001F68                 PUSH            {R4,LR}
ROM:00001F6A                 MOVS            R2, #0x1500000
ROM:00001F6E                 LDR             R1, =dword_8014C
ROM:00001F70                 MOV             R4, R0
ROM:00001F72                 CMP             R0, R2
ROM:00001F74                 BNE             loc_1F80
ROM:00001F76                 MOVS            R0, #0
ROM:00001F78                 STRB            R0, [R1,#(alt_usb_base - 0x8014C)]
ROM:00001F7A                 BL              usb_init
ROM:00001F7E                 B               loc_1F88
ROM:00001F80 ; ---------------------------------------------------------------------------
ROM:00001F80
ROM:00001F80 loc_1F80                                ; CODE XREF: usbdl_init+C↑j
ROM:00001F80                 MOVS            R0, #1
ROM:00001F82                 STRB            R0, [R1,#(alt_usb_base - 0x8014C)]
ROM:00001F84                 BL              noidea
ROM:00001F88
ROM:00001F88 loc_1F88                                ; CODE XREF: usbdl_init+16↑j
ROM:00001F88                 MOV             R0, R4
ROM:00001F8A                 BL              usb_setup
ROM:00001F8E                 CMP             R0, #0
ROM:00001F90                 BEQ             loc_1F9E
ROM:00001F92                 BL              try_sync_with_host
ROM:00001F96                 ADR             R0, aFailed ; "FAILED\n"
ROM:00001F98
ROM:00001F98 loc_1F98                                ; CODE XREF: usbdl_init+38↓j
ROM:00001F98                 BL              uart_puts
ROM:00001F9C                 POP             {R4,PC}
ROM:00001F9E ; ---------------------------------------------------------------------------
ROM:00001F9E
ROM:00001F9E loc_1F9E                                ; CODE XREF: usbdl_init+28↑j
ROM:00001F9E                 ADR             R0, aNolink ; "\nNOLINK\n"
ROM:00001FA0                 B               loc_1F98
ROM:00001FA0 ; End of function usbdl_init

تنتظر دالة try_sync_with_host بايت المزامنة (0x5A) وتدخل في الحلقة الرئيسية.

root@kitploit:~
void try_sync_with_host()
{
  int v0; // r4
  unsigned int i; // r0
  int v2; // r5
  int v3; // r2
  int v4; // r3
  int v5; // r2
  int v6; // r3
  int v7; // r0

  v0 = 0x805A0;
  time_to_boot = 0;
  for ( i = 0; i < 0x40; ++i )
    *(_BYTE *)(i + 0x805A0) = 0;
  g_state = 0;
  v2 = 0x200;
  if ( usb_recv(byte_805A0, 0x200, 0x5A) == 1 ) // 0x5a = ack sent by the host
  {
    uart_puts("TIMEOUT\n");
  }
  else
  {
    resp[0] = 0xA5;
    usb_send((int)resp, 1, v3, v4);
    g_state = 1;
    while ( !time_to_boot )
    {
      v7 = sub_11CA(v0, v2, v5, v6);
      handler(v0, v7);
      if ( g_state == 4 )
      {
        v2 = size;
        v0 = start_addr;
      }
      else
      {
        v0 = 0x805A0;
        v2 = 0x200;
      }
    }
    verify_and_jump(unk_80160, 0, 1);
  }
}

بعد اكتمال المصافحة، يدخل BootROM في الحلقة الرئيسية، بانتظار ثنائي المرحلة الأولى، والذي يُستخدم عادةً لاستعادة جهاز تالف. ومع ذلك، لا يتحقق BootROM من عنوان الوجهة، مما يسمح بالكتابة العشوائية عبر أمر 0x7A. حالة 0xA1 تعني أن عنوان الصورة وحجمها تم قبولهما.

root@kitploit:~
usb_send:
        resp[0] = status;
        v5 = 1;
        v6 = resp;
        return usb_send((int)v6, v5, state, v3);
      case 3u: // 0x7A
        if ( *(int *)&resp[4] >= 4 )
        {
          if ( *(int *)&resp[4] < 8 )
            *(_DWORD *)&resp[12] = (*(_DWORD *)&resp[12] << 8) | result;
        }
        else
        {
          *(_DWORD *)&resp[8] = (*(_DWORD *)&resp[8] << 8) | result;
        }
        v3 = *(_DWORD *)&resp[4] + 1;
        *(_DWORD *)&resp[4] = v3;
        if ( v3 != 8 )
          continue;
        *(_DWORD *)&resp[4] = 0;
        start_addr = *(_DWORD *)&resp[8];
        size = *(_DWORD *)&resp[12];
        g_state = 4;
        status = 0xA1;
        goto usb_send;

ستقوم دالة verify_and_jump بالتحقق من الصورة إذا كان الجهاز مدمجًا (fused).

root@kitploit:~
int __fastcall verify_and_jump(Header *a1, int zero, int must_verify)
{
  int *p_sp; // r6
  int result; // r0

  p_sp = (int *)&a1->sp;
  result = memcmp((int)a1->magic, 0x80008, 2u);
  if ( !result )
  {
    if ( !zero || (result = a1->usbdl_en, result == 0x5A) )
    {
      if ( !must_verify )
        return jump(p_sp);
      result = verify(a1);
      if ( !result )
        return jump(p_sp);
    }
  }
  return result;
}

ستستخدم دالة verify محركات MD5 وRSA الخاصة بالعتاد للتحقق من سلامة الصورة، وستقوم jump بتعيين مؤشر المكدس إلى العنوان من رأس الصورة والقفز إلى نقطة الدخول.

في اصطلاح استدعاء ARM/Thumb، تبدأ استدعاءات الدوال عادةً بـ PUSH {regs, LR} وتنتهي باستدعاء ذيل، أو BX LR أو POP {regs, PC}. لم يتم تحسين usbdl_init بواسطة المترجم كاستدعاء ذيل، لذلك يحتوي على تعليمات PUSH وPOP.

هل فهمت الفكرة بالفعل؟


نظرًا لأن BootROM لا يحتوي على علامة للتنزيل لمرة واحدة، يمكننا إرسال أي عدد نريده من الصور. يستغل الاستغلال هذه الميزة (على الرغم من أنها ليست ثغرة بحد ذاتها) مع الكتابة العشوائية للذاكرة.

  1. أرسل الحمولة إلى العنوان المحدد
  2. احسب إزاحة المكدس: 6 (دالة entry: PUSH {R3-R7,LR}) + 2 (دالة usbdl_init: PUSH {R4,LR}). اضرب ذلك في حجم السجل، أي 8 * 4 = 32
  3. أرسل عنوان القفز إلى سجل LR المحفوظ على المكدس (للبساطة، يكرر الـ PoC نفس العنوان لجميع السجلات المحفوظة)
  4. أرسل أمر القفز
  5. دع التحقق من الصورة يفشل (غياب ترويسة السحر)
  6. تعود دالة verify_and_jump إلى usbdl_init
  7. تطبع usbdl_init رسالة FAILED وتنفذ تعليمة POP {R4, PC}، مما يشغّل الحمولة

للبناء من المصدر

  • ثبّت curl وllvm-objcopy (عادةً جزء من حزمة llvm) وgcc. مثال لأوبونتو 22.04: sudo apt update && sudo apt install curl llvm gcc
  • ثبّت rustup باستخدام curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh أو مدير الحزم الخاص بالتوزيعة
  • تأكد من توفر أوامر rust: . "$HOME/.cargo/env" (bash) أو source "$HOME/.cargo/env.fish" (fish)
  • ابنِ الحمولة: cd payload && ./build.sh && cd ..
  • شغّل أداة المضيف: sudo -E cargo r -p loader -- target/thumbv6m-none-eabi/release/payload

الآن قم بتوصيل الجهاز مع تفعيل وضع التنزيل عبر USB (إما عبر نقطة اختبار خاصة أو فلاش تالف) وراقب مخرجات UART.

الجدول الزمني

  • 5 فبراير - التقرير الأولي
  • 18 مارس - التأكيد من قبل ZTE PSIRT
  • 7 مايو - الإصدار العام

الاعتمادات الخارجية

  • الكثير من الهندسة العكسية لـ SoC: Stefan Dösinger
  • الاختبار على جهاز مدمج (fused): Mio Naganohara
  • اختبار ما قبل الإصدار على جهاز مدمج آخر: exp-3

الترخيص

AGPLv3

تنزيل الأداة