Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
CVE-2026-40003 — CVE-2026-40003 के लिए एक्सप्लॉइट, ZXIC/Sanechips ZX297520V3 SoC BootROM में एक मनमाना मेमोरी राइट भेद्यता, जो USB डाउनलोड मोड के माध्यम से कोड निष्पादन को सक्षम करती है। | Kitploit
उपकरण/GitHubGitHub/rva3/cve-2026-40003
एम्बेडेड सिस्टम सुरक्षाशोषणरिवर्स इंजीनियरिंगहार्डवेयर हैकिंगपेलोड डेवलपमेंटफर्मवेयर विश्लेषणबाइनरी शोषण
GitHubrva3/cve-2026-40003

CVE-2026-40003

CVE-2026-40003 के लिए एक्सप्लॉइट, ZXIC/Sanechips ZX297520V3 SoC BootROM में एक मनमाना मेमोरी राइट भेद्यता, जो USB डाउनलोड मोड के माध्यम से कोड निष्पादन को सक्षम करती है।

रिपॉजिटरी देखें
1413 महीने पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें
वेबसाइट

CVE-2026-40003 उर्फ जोसेलिटो ZXIC/Sanechips ZX297520V3 SoC BootROM में पाई गई एक मनमानी मेमोरी राइट (arbitrary memory write) भेद्यता है।

[!CAUTION] यह PoC केवल शोध उद्देश्यों के लिए प्रकाशित किया गया है। आपको नहीं करना चाहिए इस एक्सप्लॉइट का उपयोग किसी दुर्भावनापूर्ण उद्देश्य के लिए। नहीं करें उन उपकरणों पर एक्सप्लॉइट का उपयोग जिनके आप मालिक नहीं हैं या मालिक की स्पष्ट सहमति के बिना।

स्थिति

यह भेद्यता मार्च 2026 से नए SoC संशोधनों में ठीक कर दी जानी चाहिए। अभी तक पैच किए गए चिप्स का उपयोग करने वाले कोई ज्ञात उत्पाद नहीं हैं। सभी मौजूदा डिवाइस असुरक्षित हैं।

यह कैसे काम करता है?

TL;DR: लोडर कोड देखें।

BootROM 0x4 पते पर स्टैक पॉइंटर 0x81FF0 के साथ शुरू होता है। कोड विशेष टेस्ट पॉइंट, या फ्लैश से इमेज लोड करने की क्षमता के आधार पर मोड चयन करता है। यदि BootROM फ्लैश पर इमेज लोड या सत्यापित करने में विफल रहता है, तो यह USB डाउनलोड मोड पर वापस आ जाता है।

हम इस व्यवहार को यहाँ देख सकते हैं:

root@kitploit:~
v0 = MEMORY[0x13B004] & 7; // हार्डवेयर पिन
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 IP को प्रारंभ करता है और डाउनलोड लूप में प्रवेश करता है:

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
  {
    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 मुख्य लूप में प्रवेश करता है, स्टेज 1 बाइनरी की प्रतीक्षा करता है, जिसका उपयोग आमतौर पर ब्रिक्ड डिवाइस को रिकवर करने के लिए किया जाता है। हालाँकि, 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 फ़ंक्शन इमेज सत्यापन करेगा यदि डिवाइस फ्यूज्ड है।

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 इंस्टॉल करें। Ubuntu 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
  • फ्यूज्ड डिवाइस पर परीक्षण: Mio Naganohara
  • दूसरे फ्यूज्ड डिवाइस पर प्री-रिलीज़ परीक्षण: exp-3

लाइसेंस

AGPLv3

टूल डाउनलोड करें