
GhostLock को एक ही आदिम तत्व तक सीमित किया गया: futex PI UAF (CVE-2026-43499) के माध्यम से Galaxy A17 (BZA5) पर SELinux बंद। न root, न cred patch, न rwforge।
GhostLock का एक न्यूनतम फोर्क जो केवल एक प्रिमिटिव रखता है: CVE-2026-43499 (futex PI UAF) के माध्यम से SELinux को बंद करना।
ghost-hoock, Mobile Hacking Lab द्वारा बनाए गए GhostLock एक्सप्लॉइट का एक छोटा किया गया फोर्क है, जिसे एक ही प्रिमिटिव तक सीमित कर दिया गया है:
futex PI UAF के माध्यम से एक सीमित राइट ->
selinux_enforcing = 0।
कोई root नहीं, कोई cred ओवरराइट नहीं, कोई rwforge चैनल नहीं, कोई UMH नहीं, कोई configfs नहीं। कमज़ोर कर्नेल पर SELinux को permissive मोड में बदलने के लिए बस न्यूनतम आवश्यक चीज़।
Samsung Galaxy A17 (SM-A175F, BZA5) पर उदाहरण आउटपुट:
[] kernel: 6.12.23-android16-5-abA175FXXS5BZD2-4k
[+] offsets matched: 6.12.23-android16-5-abA175FXXS5BZD2-4k
[] init_cred image=ffffffc082512b08 alias=ffffff8002512b08
[+] startup context pid=10331 uid=2000 euid=2000 gid=2000 egid=2000 attr=u:r:shell:s0 enforce=1
[+] startup limits pid=10331 NoNewPrivs=0 Seccomp=0 Seccomp_filters=0
[+] build config pid=10331 label=ghost-hoock
[] p0 kernel_phys_load=0000000040000000 delta=0000000000000000 core=0
[] target selinux_enforcing=ffffff800277e560
[] W1 attempt 1/20
[] === W1: SELinux === target=0xffffff800277e560 mode=1
[] prepare_kernel_page ok attempt=1
[] pselect route setup simple=0 shift=0 page=ffffff806c4f0000 fake_lock=ffffff806c4f0000 ...
[] pselect returned ret=6 errno=0 calls=1 success=1 delay=0
[] pselect route done calls=1 success=1 step=0 errno=0
[+] SELinux DISABLED (attempt 1)
फिर:
$ getenforce
Permissive
getenforce Permissive लौटाता है
यह एक्सप्लॉइट CVE-2026-43499 को लक्षित करता है — जो Linux kernel के futex PI (Priority Inheritance) rt_mutex चेन में एक use-after-free है। ghost-hoock में यह चेन चार चरणों की है:
kernel की futex hash table के विरुद्ध timing side-channel। हम user-space futexes के एक सेट पर FUTEX_WAKE_PRIVATE को बार-बार ट्रिगर करते हैं, rdtsc deltas मापते हैं, और hash-bucket collisions को सहसंबंधित करते हैं। इससे हमारे अपने mm_struct का पता प्राप्त होता है — जो उस spray page का आधार है जिसकी हमें बाद में आवश्यकता होती है।
यह KernelSnitch तकनीक है, जिसे मूल एक्सप्लॉइट से यथावत लिया गया है।
हम एक बड़ा order-3 slab page आवंटित करते हैं, फिर उसे उस fake-object layout से व्यवस्थित करते हैं जिसका उपयोग PI route करता है:
| Offset | Object | Purpose |
|---|---|---|
0x0E80 | fake_lock | नकली rt_mutex |
0x0F80 | fake_fops | नकली file_operations तालिका |
0x1180 | fake_w0 | लक्ष्य tree के रूप में उपयोग किया गया नकली rt_mutex_waiter |
0x1240 | fake_right | नकली rb-tree दायाँ नोड — यहीं से write value आती है |
0x1260 | fake_left | नकली rb-tree बायाँ नोड |
0x1280 | fake_task | नकली task_struct |
पूरा page एक AF_UNIX socket के माध्यम से sendmsg के SKB_SEND_SIZE = 2 * ORDER3_SIZE के रूप में भेजा जाता है, ताकि skb डेटा हमारे लीक हुए page पर पहुँचे। फिर हम इसे एक नियंत्रित क्रम में मुक्त करते हैं ताकि हमारा page एक per-cpu partial slab पर पहुँचे जिसे हम पुनः प्राप्त कर सकें।
तीन threads:
f_wait पर FUTEX_WAIT_REQUEUE_PI में प्रवेश करता है, जिसका लक्ष्य f_pi_target है।f_pi_target पर और फिर f_pi_chain पर FUTEX_LOCK_PI रखता है।sched_setattr(tid, SCHED_BATCH, nice=19) को कॉल करते हुए घूमता रहता है, जो rt_mutex_setprio() को ट्रिगर करता है और kernel को नकली PI tree पर चलने के लिए बाध्य करता है।मुख्य thread से एक चौथा कॉल — FUTEX_CMP_REQUEUE_PI(1, f_pi_target) — requeue को शुरू करता है। kernel के अंदर, rb_erase() हमारे नकली tree पर चलता है।
pselect() / select() उपयोगकर्ता के fd_set को kernel stack में कॉपी करता है और बाद में उस पर चलता है। हम fd_set bitmaps को इस प्रकार व्यवस्थित करते हैं कि जिन शब्दों को kernel rb-tree pointers मानता है वे fake_right और उसके parent पर पड़ें — और परिणामी rb_set_parent(child, parent) बन जाता है:
*(uint64_t *)target = value | color
mode = 1 (Write 1), target = selinux_enforcing और value = base + 0x100 के लिए, जो byte0 = 0, byte1 = 1 के रूप में एन्कोड होता है। कर्नेल selinux_enforcing[0] में 0 लिखता है — SELinux अब permissive है।
ret = 6 (डिफ़ॉल्ट 9 के बजाय) पुष्टि करता है कि लेखन सफल हुआ: consumer ने select() के दौरान लक्ष्य को हिट किया, जिससे यह जल्दी जाग गया।
यह mobilehackinglab/ghostlock-a17 (MIT) का एक फ़ोर्क है। निम्नलिखित अपस्ट्रीम एक्सप्लॉइट से 1:1 लिया गया है:
| घटक | फ़ाइल | टिप्पणियाँ |
|---|---|---|
| KernelSnitch | src/kernelsnitch/* | futex hash टाइमिंग के माध्यम से mm_struct लीक |
| Heap spray | src/spray.c | fake-object लेआउट, prepare_skb_payload, prepare_kernel_page |
| PI route + pselect | src/route.c | prepare_pselect_fdsets, do_pselect_fake_lock_route, consumer_thread, waiter_thread, owner_thread |
| BZA5 ऑफ़सेट | include/offsets_bza5.h | 6.12.23-android16-5-abA175FXXS5BZD2-4k से निकाली गई सिंबल तालिका |
| BZA5 लक्ष्य हेडर | include/target.h | एड्रेस लेआउट, पेलोड ऑफ़सेट (केवल W1-सबसेट) |
| रनटाइम स्ट्रक्चर ऑफ़सेट | include/runtime_struct_offsets.h | task_struct फ़ील्ड के लिए _RSO() मैक्रोज़ |
सहायक कोड (pr_* मैक्रोज़, SYSCHK, pin_to_core, set_limit, set_unbuffer) भी मूल से जैसा है वैसा ही रखा गया है।
मूल GhostLock A17 पर पूर्ण root प्राप्त करता है: यह एक rwforge फ़िज़िकल R/W चैनल इंस्टॉल करता है, cred / real_cred को पैच करता है, init creds के साथ एक UMH हेल्पर चलाता है, लॉग कैप्चर करता है, और बहुत कुछ। ghost-hoock में, पहले constrained write के बाद का सब कुछ हटा दिया गया है।