
MT6985 MediaTek Dimensity 9300 (vivo PD2241) के लिए CVE-2026-43499 exploit अडैप्टर
निष्कर्ष: 68M टोकन खर्च किए, root नहीं मिला।
कारण: MTK Dimensity 9200 पर KernelSnitch टाइमिंग अटैक अविश्वसनीय है,CONFIG_PANIC_ON_OOPS=yपरीक्षण-और-त्रुटि के लिए जगह नहीं देता।
यह लेख पूरी गलती-सीखने की प्रक्रिया दर्ज करता है, ताकि भविष्य के लोग इन गड्ढों से बच सकें।
| परियोजना | मान |
|---|
| डिवाइस | vivo PD2241 (Dimensity 9200 / MT6985), Android 15 |
| फर्मवेयर | PD2241_A_15.2.10.2.W10.V000L1 |
| कर्नेल | 5.15.178-android13-8-gfb31f5bdd612-dirty |
| बूटलोडर | लॉक (ro.boot.flash.locked=1) |
| SELinux | Enforcing |
| panic_on_oops | चालू → कोई भी कर्नेल OOPS = तुरंत रिबूट |
| एक्सप्लॉइट | CyberMeowfia — CVE-2026-43499 (IonStack) |
| सोर्स ट्री | android_15.0_kernel_MT6985 (5.15.178) — डिवाइस संस्करण से मेल नहीं खाता (सोर्स android15 GKI है, डिवाइस android13 GKI चलाता है) |
arch/arm64/include/asm/memory.h + include/linux/fs.h + android/abi_gki_aarch64.xml से निकाला गया:
KIMAGE_TEXT_BASE = 0xffffffc008000000, VA_BITS=39, DIRECT_MAP=256GBlayout-offset-in-bits)iopoll नहीं (android13 GKI), IOCTL=0x48, open=0x68atomic_t usage = 4 बाइट, uid=0x04slab_cache=0x18मुख्य खोज: सोर्स android15 GKI है, डिवाइस android13 GKI है — task_struct ऑफसेट 0x40~0x88 बाइट तक भिन्न हैं, सोर्स को सीधे कॉपी नहीं किया जा सकता।
OTA zip (8.3GB)
→ payload.bin (8.2GB)
→ payload_dumper → boot.img (96MB, v4 header)
→ LZ4 डीकंप्रेस → Image (50MB ARM64)
→ kallsyms-finder → 187810 सिंबल
दो फर्मवेयर संस्करणों (15.2.7.6 / 15.2.10.2) से सिंबल निकाले गए — एक ही सिंबल दो संस्करणों के बीच 10KB~200KB तक भिन्न है, सही संस्करण का उपयोग करना अनिवार्य है।
# rt_mutex_adjust_pi में:
LDR x21, [x19, #0x8b0] → pi_blocked_on = 0x8b0 (android15 मान, frankel नहीं)
इससे पुष्टि हुई कि task_struct लेआउट android15 शाखा का है, frankel के android13 का नहीं।
NDK r29, make PROJECT=android_15.0_kernel_MT6985 → preload.so (150KB)।
[+] preload starting pid=25414
[+] p0 profile ... सभी सिंबल सही ढंग से लोड हुए
[-] KernelSnitch mm_struct leak failed ← कभी-कभी यह लाइन नहीं आती (कभी-कभी सफल)
[+] slide child context route=pselect ← slide KASLR leak चाइल्ड प्रोसेस शुरू
[कर्नेल panic] ← rt_mutex_adjust_prio_chain+0x1b0
क्रैश इंस्ट्रक्शन (capstone):
ldar w8, [x27] ; x27 = waiter->lock ([x28, #0x38] से लोड किया गया)
; x27 मान कचरा है → पेज टेबल में कोई मैपिंग नहीं → translation fault
; → die() → panic → रिबूट
KernelSnitch पूरे एक्सप्लॉइट का प्रवेश द्वार है — यह futex हैश बकेट के टाइमिंग अंतर के माध्यम से mm_struct पता लीक करता है:
MT6985 में CONFIG_KASAN_HW_TAGS=y है → कर्नेल slab आवंटन को MTE टैग से चिह्नित करता है
mm_struct का पॉइंटर KASAN टैग के साथ है → futex_hash tagged pointer पर आधारित गणना करता है
लेकिन bruteforce direct map (untagged पता) स्कैन करता है → गणना किया गया hash मेल नहीं खाता
भले ही MTE टैग ट्रैवर्सल जोड़ा जाए (0-14 कुल 15 प्रकार), VA_BITS=39 वाले सिस्टम पर
टैग बिट्स (bit56-59) साइन-एक्सटेंशन बिट्स से ओवरलैप होते हैं → कुछ टैग संयोजन अमान्य पता बनाते हैं → मिस डिटेक्शन
Pixel डिवाइस में KASAN_HW_TAGS नहीं है, यह तंत्र वहाँ काम करता है। MTK पर नहीं।
CONFIG_PANIC_ON_OOPS घातक हैPixel: कर्नेल OOPS → dump_stack → चलता रहता है → एक्सप्लॉइट पुनः प्रयास कर सकता है
MT6985: कर्नेल OOPS → die() → panic() → तुरंत रिबूट → परीक्षण-और-त्रुटि की कोई गुंजाइश नहीं
π चेन में थोड़ी सी भी गड़बड़ी पूरी तरह क्रैश कर देती है, Pixel पर गड़बड़ी का मतलब सिर्फ "इस बार सफल नहीं, दूसरे पते के सेट से फिर कोशिश करो" होता है।
और बूटलोडर लॉक है (flash.locked=1) → इस विकल्प को हटाने के लिए कस्टम कर्नेल फ्लैश नहीं किया जा सकता।
सोर्स ट्री: 5.15.178 android15 GKI
डिवाइस: 5.15.178-android13 (vivo vendor)
हालाँकि मुख्य संस्करण संख्या दोनों 5.15.178 है, GKI शाखा अलग है (android13 बनाम android15), task_struct/cred जैसे महत्वपूर्ण स्ट्रक्चर का लेआउट असंगत है। frankel/android15 दोनों ऑफसेट सेट के बीच बार-बार स्विच करने के बाद, अंततः डिसअसेंबली से ही सही ऑफसेट लॉक हुआ।
| बदलाव | उद्देश्य | परिणाम |
|---|---|---|
THRESHOLD_MULT 10→5→3 | कोलिजन डिटेक्शन थ्रेशोल्ड कम करना | <5 पर बहुत अधिक फॉल्स पॉज़िटिव |
APPENDED_FUTEXES 4096→8192 | हैश चेन अंतर बढ़ाना | कोई प्रभाव नहीं |
REPEAT_MEASUREMENT/AVERAGE | सैंपलिंग सटीकता बढ़ाना | कोई प्रभाव नहीं |
MTE=1 | bruteforce को टैग ट्रैवर्स करने देना | धीमा, क्रैश कम हुए |
MM_STRUCT_SZ 0x500→0x400 | mm_struct स्टेप साइज़ सुधारना | आवश्यक, ABI वास्तव में 992 बाइट |
IDENTITY_END 64GB→256GB | स्कैन रेंज बढ़ाना | बहुत धीमा (MTE ट्रैवर्सल), फिर भी मेल नहीं खाता |
| TASK ऑफसेट: android15↔frankel | सही ऑफसेट लॉक करना | डिसअसेंबली से android15 की पुष्टि |
| FOPS ऑफसेट: android15↔frankel | android13 में iopoll नहीं है | frankel का उपयोग किया |
exploit/targets/android_15.0_kernel_MT6985/target.h में:
| श्रेणी | विश्वसनीयता | सत्यापन विधि |
|---|---|---|
| मेमोरी लेआउट | सही | memory.h गणना + kallsyms _text सत्यापन |
| सिंबल ऑफसेट (22) | सही | 15.2.10.2 boot.img से निकाले गए |
| task_struct ऑफसेट | सही | ABI XML + capstone डिसअसेंबली (pi_blocked_on=0x8b0) |
| FOPS ऑफसेट | गलत (2026-07-31 को सुधारा गया) | मूल मान frankel से कॉपी किए गए (android13 में iopoll नहीं); सोर्स ट्री ABI में वास्तव में iopoll@0x30, ioctl=0x50, open=0x70 है — देखें VERIFICATION.md |
| CRED ऑफसेट | सही (सत्यापित) | ABI XML: uid=0x04, securebits=0x24, caps=0x28, security=0x78 |
असेंबली पास हो जाती है, चल जाता है, बस आखिरी मील में हार गए।
CONFIG_PANIC_ON_OOPS हटाएँ — या तो कस्टम कर्नेल फ्लैश करें (बूटलोडर अनलॉक चाहिए), या ऐसा MT6985 डिवाइस खोजें जिसमें यह विकल्प डिफ़ॉल्ट रूप से बंद हो/proc/self/pagemap — इस डिवाइस पर प्रतिबंधित है (सभी शून्य लौटाता है)/proc/mtk_*) — मौजूद हैं लेकिन आगे विश्लेषण की आवश्यकता हैsymbols/kallsyms_PD2241_15.2.10.2.txt — पूर्ण 15.2.10.2 सिंबल टेबल, भविष्य के लोग सीधे उपयोग कर सकते हैंdevice_config.txt — डिवाइस का वास्तविक कर्नेल कॉन्फ़िगरेशन, देख सकते हैं कि vendor ने क्या बदलाexploit/targets/android_15.0_kernel_MT6985/target.h — स्ट्रक्चर ऑफसेट सत्यापित हैंscripts/server_compile.py — स्वचालित कंपाइलेशन, पैरामीटर बदलकर जल्दी रीकंपाइल कर सकते हैंtar -xf विफल हो सकता है, Python zipfile का उपयोग करें या पहले मैन्युअल रूप से अनज़िप करेंupdate_metadata_pb2.py को protobuf 5.x चाहिए, runtime_version इम्पोर्ट लाइन को मैन्युअल रूप से हटाना होगा./preload.so चलाने पर segfault: /system/bin/linker64 /data/local/tmp/preload.so का उपयोग करना अनिवार्य हैlayout-offset-in-bits कंपाइलर द्वारा गणना किया गया है, 5000 बाइट मैन्युअल गिनने से 100 गुना अधिक सटीकCONFIG_ANDROID_VENDOR_OEM_DATA=y, CONFIG_SCHED_INFO=y, CONFIG_RSC_* → मानक GKI से विचलनboot.img → kernel.bin → LZ4 डीकंप्रेस → Image → kallsyms-finder → सिंबल टेबल07/28 CyberMeowfia रिपॉजिटरी + MT6985 सोर्स डाउनलोड
07/29 सोर्स विश्लेषण (memory.h, fs.h, ABI XML, विभिन्न struct)
फर्मवेयर अनपैक (payload.bin → boot.img → Image)
सिंबल निष्कर्षण (kallsyms-finder → 187810 सिंबल)
कई राउंड कंपाइलेशन + कई राउंड क्रैश + डिसअसेंबली सत्यापन
5 बार स्वचालित पुनः प्रयास → सभी विफल
यह लेख लिखा गया
-------------------------------------------
कुल: ~68M टोकन, 0 root शेल
2026-07-29, कहानी सुनाने के लिए जीवित बचे
android_15.0_kernel_MT6985.tar.gz (5.15.178 सोर्स ट्री + ABI XML) मिलने के बाद
पूर्ण क्रॉस-सत्यापन किया गया, विवरण के लिए देखें VERIFICATION.md। सारांश:
target.h सुधारा गया, और एक्सप्लॉइट के साथ आने वाले
leak_kernel_base() से वास्तविक डिवाइस पर स्व-सत्यापन बैकअप के रूप में उपयोग किया गया।KSNITCH_MTE_ENABLED=1 को वास्तव में
प्रभावी बनाया गया (मूल util.c में mte=0 हार्डकोड था);rt_mutex_adjust_prio_chain+0x1b0 pselect/pi चेन चरण में है, FOPS
स्व-सत्यापन से पहले; उपरोक्त सुधारों के बाद पुनः वास्तविक डिवाइस पर परीक्षण उचित है।डिवाइस (PD2241, compiler251203103903) पर 8+ राउंड वास्तविक परीक्षण:
MM_STRUCT_SZ=0x400 (मूल 0x500 के कारण स्कैन ग्रिड
गलत था, केवल फॉल्स पॉज़िटिव आते थे) + MTE टैग 0..15 ट्रैवर्सल (डिवाइस के mm पॉइंटर टैग बदलते हैं) + नकली पते का untag।
अब वास्तविक mm_struct स्थिर रूप से मिल जाता है।rt_mutex_adjust_prio_chain+0x1b0 पर क्रैश: pselect/pi चेन टाइमिंग रेस
(नकली waiter कर्नेल स्टैक के सही ऑफसेट पर नहीं पहुँच पाता)। vivo RSC शेड्यूलर ने futex/pi पथ बदल दिया है,
संभवतः इस रेस को मूल रूप से तोड़ दिया है। slide स्टैक अलाइनमेंट को SLIDE_SHIFT एनवायरनमेंट वेरिएबल के रूप में
पैरामीटराइज़ किया गया है, स्कैन पूरा नहीं हुआ।अंतिम विकल्प: भुगतान करके बूटलोडर अनलॉक करवाना (अब इस पथ पर निर्भर नहीं)।