
CVE-2026-43499 Google TV वाले Chromecast (sabrina) के लिए GhostLock रूट एक्सप्लॉइट
Chromecast with Google TV (sabrina) के लिए CVE-2026-43499 के माध्यम से रूट एक्सप्लॉइट -- Linux kernel के futex PI (priority inheritance) सबसिस्टम में एक use-after-free।
Android 14 चलाने वाले और kernel 5.15.170 (PGO+BOLT+LTO, clang 17) वाले लॉक्ड बूटलोडर डिवाइस पर रूट प्राप्त करता है।
GhostLock rt_mutex_start_proxy_lock() में -EDEADLK रोलबैक पाथ से कॉल किए जाने वाले remove_waiter() में एक बग का शोषण करता है। यह फ़ंक्शन वेटर टास्क के बजाय current->pi_blocked_on (रीक्व्यूअर का, जो पहले से NULL है) को साफ़ करता है। वेटर का pi_blocked_on कभी साफ़ नहीं होता, जिससे kernel स्टैक पर एक मुक्त किए गए rt_mutex_waiter के लिए एक डैंगलिंग पॉइंटर बचा रह जाता है।
इसके बाद का sched_setattr rt_mutex_adjust_pi -> rt_mutex_adjust_prio_chain को ट्रिगर करता है, जो डैंगलिंग पॉइंटर का अनुसरण करता है और एक पुनःप्राप्त heap पेज पर हमलावर-नियंत्रित डेटा पर PI चेन को वॉक करता है -- जिससे rb_erase के माध्यम से एक मनमाना राइट प्रिमिटिव मिलता है।
| चरण | तकनीक |
|---|---|
| KASLR लीक | perf_event_open के साथ PERF_SAMPLE_IP (TID-गेटेड) — न्यूनतम kernel IP .entry.text (+0x10000) में है, _text 2MB-संरेखित है और KASLR स्लाइड 2MB का गुणज है, इसलिए min_ip & ~0x1fffff रनटाइम _text को ठीक-ठीक पुनःप्राप्त करता है |
| टास्क स्ट्रक्चर लीक | perf_event_open के साथ PERF_SAMPLE_REGS_INTR (TID-गेटेड, लीनियर-मैप पतों का मोड) |
| सिंबल-टेबल सत्यापन | setpriority(-20) स्टॉर्म के दौरान security_capable() के रजिस्टर आर्ग्युमेंट्स से perf-samples &init_user_ns निकालता है और इसे kaslr_base + off_init_user_ns से मिलाता है — किसी भी ब्लाइंड राइट से पहले सिद्ध करता है कि चल रहे kernel का .data/.bss लेआउट ऑफ़सेट टेबल से मेल खाता है |
| mm_struct लीक | KernelSnitch -- futex हैश कोलिज़न टाइमिंग साइड-चैनल |
| Heap स्प्रे | SLUB डिस्कार्ड कोरियोग्राफी (memfd-close, CPU-पार्शियल ओवरफ़्लो) + io_uring_setup(256) ऑर्डर-2 पेज रिक्लेम |
| स्टैक ओवरले | AF_UNIX SOCK_SEQPACKET sendmsg -- move_addr_to_kernel 128-बाइट sockaddr को kernel स्टैक पर कॉपी करता है, जो डैंगलिंग वेटर के task/lock/prio फ़ील्ड्स को ओवरले करता है |
| वॉक ट्रिगर | मोनोटोनिक nice लैडर (7 -> 14 -> 19) के साथ sched_setattr PI चेन वॉक को फ़ायर करता है, प्रत्येक ओवरले राउंड के लिए एक |
| राइट प्रिमिटिव | rb_erase केस 1: `{pc=(TARGET-8) |
| SELinux बंद (वॉक 0) | selinux_state पर 8-बाइट शून्य enforcing, checkreqprot, initialized और policycap[0..4] को साफ़ करता है — avc_denied() कभी मना नहीं करता (enforcing=0) और security_compute_av() शॉर्ट-सर्किट होकर allow-all (!initialized) हो जाता है, इसलिए स्वैप के बाद का kernel-SID (u:r:kernel) मायने रखना बंद कर देता है |
| Cred स्वैप (वॉक 1+2) | task->cred = fake_cred और task->real_cred = fake_cred (uid=0, caps FULL, स्प्रे पेज पर स्व-निहित नकली user_namespace; दोनों राइट आवश्यक — exec पर commit_creds() BUG_ON करता है जब तक cred == real_cred न हो) |
| रूट बैटरी | केवल raw-syscall जाँच (uid/SELinux//proc/1//dev/kmsg/wifi/packages//data/data/kallsyms) /data/local/tmp/.ghostlock_out में |
| रूट शेल | execve("/system/bin/sh") — exec पाथ में commit_creds fake_cred को एक साफ़ slab credential में कॉपी करता है; यह इस शर्त पर निर्भर है कि सभी नियोजित erases लागू हो चुके हों |
rb_right = 0 के साथ rb_erase प्रिमिटिव एक मनमाने कर्नेल पते पर एक साफ़ 8-बाइट शून्य स्टोर करता है (कोई साइड स्टोर नहीं, कोई वाइल्ड डीरेफ़रेंस नहीं); selinux_state के पहले qword को शून्य करने से डबल परमिसिव मिलता है (enforcing=0 + !initialized → allow-all), जो कर्नेल SID के बावजूद सभी पोस्ट-रूट फ़ाइल I/O को अनब्लॉक करता हैsecurity_capable() पथ से &init_user_ns को perf-लीक करता है और जब तक यह kaslr_base + off_init_user_ns से मेल नहीं खाता, तब तक cred-only फ़्लो पर निरस्त हो जाता हैucounts = NULL है -- cap_capable पहले पुनरावृत्ति पर मेल खाता है और inc_rlimit_ucounts एक लूप के बाद समाप्त हो जाता है, जिससे &init_user_ns को लीक करने की आवश्यकता समाप्त हो जाती हैPERF_SAMPLE_TID फ़िल्टर सुनिश्चित करते हैं कि केवल कॉलिंग थ्रेड के रजिस्टर स्नैपशॉट गिने जाएं, जिससे हॉट सिस्टम सेवाओं को मोड-वोट पर हावी होने से रोका जा सके5.15.170-android14-11-gf4a1f03072af (aarch64, PGO+BOLT+LTO, clang 17.0.2)CONFIG_FUTEX_PI=y, CONFIG_IO_URING=y, perf_event_paranoid=-1, SELinux enforcing, panic_on_oops=1, कोई उपयोगकर्ता नेमस्पेस नहींexport ANDROID_NDK_HOME=/path/to/android-ndk
make -j$(nproc)
Android NDK की आवश्यकता है (r27 के साथ परीक्षण किया गया)। एक स्थिर रूप से लिंक किया गया aarch64 बाइनरी उत्पन्न करता है।
adb push ghostlock /data/local/tmp/
adb shell "cd /data/local/tmp && ./ghostlock --cred"
एक्सप्लॉइट में लगभग 25 सेकंड लगते हैं (KASLR/task/layout लीक + heap spray + KernelSnitch ब्रूटफोर्स + तीन 3-सेकंड ओवरले राउंड)। सफल होने पर यह रूट बैटरी को /data/local/tmp/.ghostlock_out में लिखता है, मार्कर को /data/local/tmp/.ghostlock_root में लिखता है, और एक अनुमतिकारी कर्नेल के अंतर्गत uid=0 के साथ /system/bin/sh को exec करता है।
पर्यावरण नॉब्स:
GHOST_SELINUX=0 — SELinux लेखन छोड़ें, सिद्ध cred-only मार्ग (मोड 6) चलाएँGHOST_SELINUX_FORCE=1 — डिवाइस सिंबल-लेआउट सत्यापन विफल होने पर भी SELinux लेखन को सक्रिय करेंGHOST_EXEC=0 — बैटरी लिखें और शेल exec करने के बजाय exit(99) करेंCRED_ATTEMPTS=n — जब कोई रन reclaim चूक जाए तो पूर्ण-स्प्रे पुनःप्रयास (डिफ़ॉल्ट 3)यह एक्सप्लॉइट Claude Opus 4.6 (Anthropic) द्वारा GLM-5.3 (Z.ai) के साथ कर्नेल एक्सप्लॉइटेशन सलाहकार के रूप में पोर्ट और विकसित किया गया था।
kernel/futex/, kernel/locking/rtmutex.c, lib/rbtree.cयह एक्सप्लॉइट सुरक्षा अनुसंधान और शैक्षिक उद्देश्यों के लिए प्रकाशित किया गया है। यह शोधकर्ता के स्वामित्व वाले डिवाइस को लक्षित करता है। इसका उपयोग उन डिवाइसों पर न करें जो आपके स्वामित्व में नहीं हैं या बिना प्राधिकरण के।
MIT