
# GhostLock (CVE-2026-43499) استغلال نواة لأجهزة أندرويد ذات مُحمّل إقلاع مقفل
استغلال للنواة على أجهزة أندرويد ذات محمّل إقلاع مقفل. يحقق صلاحيات جذر مؤقتة + تثبيت KernelSU دون فتح محمّل الإقلاع أو تعديل صورة الإقلاع. كشف تلقائي لإصدار النواة أثناء التشغيل مع جدول إزاحات متعدد الأجهزة.
CVE-2026-43499 — استخدام بعد التحرير (Use-After-Free) في Futex PI (وراثة الأولوية)
يؤثر على نواة لينكس 5.7 ~ 7.1. تم إصلاحه في الإصدارات المستقرة 6.1.175، 6.6.140، 6.12.86. تبقى معظم أجهزة أندرويد دون ترقيع حتى سبتمبر 2026.
يُنسخ استدعاء النظام pselect6 بيانات fd_set إلى مكدس النواة. عند دمجه مع آلية منتظر futex PI، يمكن استعادة إطار مكدس محرَّر كبنية rt_mutex_waiter. عندها تكتب إعادة موازنة شجرة rb-tree أثناء اجتياز سلسلة PI قيمًا متحكَّمًا بها إلى عناوين نواة عشوائية.
| الجهاز | SoC | النواة | فرع GKI | SHIFT |
|---|---|---|---|---|
| OnePlus Ace 6T (PLR110) | SM8845 | 6.12.38 | android16-5 | 0 |
| OnePlus 15 (CPH2745/2747/2749) | SM8850 | 6.12.23 | android16-5 | 0 |
| OnePlus 15 (PLK110) | SM8850 | 6.12.58 | android16-6 | 0 |
| Xiaomi 17 (pudding) | SM8850 | 6.12.23 / 6.12.69 | android16-5 / android16-6 | 0 |
| OnePlus 13 (IN2060) | SM8750 | 6.6.89 | android15-8 | -2 |
| OPPO Pad 4 Pro | SM8750 | 6.6.89 | android15-8 | -2 |
| الجهاز | SoC | النواة | ملاحظات |
|---|---|---|---|
| OnePlus 15T (PLZ110) | SM8845 | 6.12.38 | نفس نواة Ace 6T |
| OPPO Reno10 Pro+ (CPH2521) | SM8475 | 5.10.236 | منتظر 5.10 المدمج، كلمة المنتظر=0 |
| Sony Xperia 1 IV (nagara) | SM8450 | 5.10.218 | منتظر 5.10 المدمج، كلمة المنتظر=0 |
| OPPO Find X9 Pro (PLG110) | D9400 | 6.12.23 | MediaTek، android16-5 |
| Vivo X200 Ultra (V2454A) | SM8750 | 6.6.89 | C ashmem، خطافات تقليدية |
| Vivo X Fold3 Pro (PD2337) | SM8650 | 6.1.124 | منتظر 6.1 المدمج، كلمة المنتظر=3 |
| Vivo T4 | SM8650 | 6.1.145 | منتظر 6.1 المدمج، كلمة المنتظر=3 |
يتطلب تراكب مكدس pselect أن يستقر rt_mutex_waiter المحرَّر ضمن منطقة stack_fds القابلة للتحكم من المستخدم (الكلمات 0–14). مكان استقراره تحدده ملفات تعريف PGO/LTO للمترجم، وليس إصدار النواة. انظر تخطيط المكدس.
| الجهاز | SoC | النواة | السبب الجذري |
|---|---|---|---|
| OPPO Find X9 Ultra | SM8750 | 6.12.58 | PGO يزيل do_futex → كلمة المنتظر=14 |
| OnePlus 15 (PLK110) | SM8850 | 6.12.69 | PGO يُضمّن do_futex → كلمة المنتظر=20 |
| OnePlus 12 | SM8650 | 6.1.141 | PGO يُضمّن do_futex → كلمة المنتظر=13/19 |
| OnePlus 13R / Ace 5 | SM8650 | 6.1.x | OPLUS 6.1: كلمة المنتظر=13 |
| realme RMX5070 | SM6650 | 6.1.141 | OPLUS 6.1: كلمة المنتظر=13 |
| OPPO Pad 5 (OPD2502) | MT6878 | 6.1.134 | OPLUS 6.1: كلمة المنتظر=13 |
| Motorola Edge 60 Fusion | MT6878 | 6.1.145 | غير OPLUS 6.1: نفس النتيجة |
| iQOO Neo 10 CN | SM8650 | 6.1.84 | إطار do_futex 0xD0 → كلمة المنتظر=-11 |
| OPPO PKW110 | — | 5.15.180 | إطار do_futex 0x140 → كلمة المنتظر=-29 |
| iQOO Z9 5G | — | 5.15.178 | إطار do_futex كبير جدًا |
| CPH2763 (OPPO) | — | 6.1.115 | OPLUS 6.1: PGO مُضمَّن، كلمة المنتظر=24 |
| iQOO 12 | SM8650 | 6.1.145 | 6.1: كلمة المنتظر=9، المهمة/القفل في منطقة مُصفَّرة |
ملاحظة حول جدوى 6.1: تبقى أنوية OPLUS 6.1 غير ممكنة باستمرار بسبب تضمين PGO لـ
do_futex. ومع ذلك، تحتفظ بعض أنوية 6.1 غير التابعة لـ OPLUS (vivo) بسلسلة الاستدعاء القياسية وتكون ممكنة (vivo T4، X Fold3 Pro). يجب التحقق من الجدوى لكل جهاز على حدة.
مساران للجذر، يُختاران تلقائيًا بناءً على قدرات الجهاز:
يتطلب off_ashmem_misc_fops != 0 (C ashmem مع miscdevice ثابت في BSS).
PI write (mode=4) → redirect miscdevice fops to fake fops
→ configfs r/w → pipe physrw (1-byte precise kernel r/w)
→ SELinux enforcing = 0 (single byte, no policycap corruption)
→ UMH: inject work_struct into system_unbound_wq
→ root script → ksud late-load → KSU installed
متاح على: OnePlus 13، OPPO Pad 4 Pro، أجهزة 5.10/6.1 C ashmem. غير متاح على Rust ashmem (6.12 GKI) — miscdevice مخصص من الكومة.
Write 1 (mode=1) → SELinux enforcing = 0 (8-byte write, corrupts adjacent bytes)
Write 2 (mode=2) → task->cred = init_cred (uid=0, all capabilities)
Root shell → ksud late-load → KSU → SELinux policy fix
بعد W1+W2، يقوم الاستغلال بترقيع حقل الإعدادات في ملف سياسة SELinux الثنائي (|= 0xC0000000 لـ ANDROID_NETLINK_ROUTE + GETNEIGH) ويعيد التحميل عبر /sys/fs/selinux/load لاستعادة اتصال الشبكة.
App (seccomp) → Write 1 → mini-adb TCP → adb shell: full exploit → root
يُوفَّر مشغّل وقت التمهيد عبر تطبيق GhostLock Anchor المنفصل.
مع NFDS=320، تُخصِّص core_sys_select مخزنًا مؤقتًا stack_fds بحجم 256 بايت على مكدس النواة:
stack_fds: 0 5 10 14 | 15 20 25 29
├─in─┤─out─┤─ex──┤ ├res_in┤res_out┤res_ex┤
◄── USER CONTROLLED ──►│◄── KERNEL ZEROED ──►
يضع الاستغلال حقول waiter المزيفة (task، lock) في خرائط بتات إدخال fd_set. بالنسبة إلى waiter المتداخل في 6.12 (14 كلمة): أقصى كلمة waiter ممكنة = 3. بالنسبة إلى waiter المدمج في 5.10/6.1 (10 كلمات): أقصى كلمة waiter ممكنة = 7.
يعتمد موضع waiter على عمق سلسلة الاستدعاء:
| النمط | سلسلة الاستدعاء | ممكن |
|---|---|---|
| android16-5 (6.12) | sys_futex → do_futex → fwrpi | ✅ waiter word=2 |
| android16-6 (6.12.58) | sys_futex → do_futex → fwrpi | ✅ waiter word=2 |
| android16-6 (6.12.69 OPLUS) | sys_futex → fwrpi (PGO inlined) | ❌ waiter word=20 |
| android16-6 (X9 Ultra) | sys_futex → fwrpi (PGO inlined) | ❌ waiter word=14 |
| android15-8 (6.6) | sys_futex → do_futex → fwrpi | ✅ waiter word=2 (SHIFT=-2) |
| vivo 6.1 | sys_futex → do_futex → fwrpi | ✅ waiter word=3 |
| OPLUS 6.1 | sys_futex → fwrpi (PGO inlined) | ❌ waiter word=13+ |
| 5.10 OPLUS | sys_futex → do_futex → fwrpi | ✅ waiter word=0 |
تستخدم جميع عمليات الكتابة إلى النواة الاسم المستعار للخريطة الخطية. يختار محمّل الإقلاع kernel_phys_load، الذي يختلف حسب كل SoC:
| SoC | kernel_phys_load |
|---|---|
| SM8845 (Ace 6T, 15T) | 0xa8000000 |
| SM8750 (OnePlus 13, OPPO Pad 4 Pro) | 0xa8000000 |
| SM8650 (vivo T4, X Fold3 Pro) | 0xa8000000 |
| SM8850 (OnePlus 15, Xiaomi 17) | 0xc7800000 |
تؤدي القيمة الخاطئة إلى فشل صامت. اقرأها على جهاز مُروَّت:
su -c 'grep -i "Kernel code" /proc/iomem' # c7810000-... → 0xc7800000
تجاوز وقت التشغيل: KPHYS=0xc7800000 /data/local/tmp/a/e
/data/local/tmp/a/e # Default (shift=0)
PSELECT_SHIFT=-2 /data/local/tmp/a/e # OnePlus 13 (6.6)
تستخدم نوى 5.10 العنوان 0xffffffc008000000 (حيث VA_BITS=39، وهو مختلف عن القيمة الافتراضية 0xffffffc080000000 في 6.x). يُعالَج هذا تلقائيًا عبر الحقل kimage_text_base في إدخال إزاحة الجهاز.
make NDK_ROOT=/path/to/android-ndk
أو مباشرةً:
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 صلاحية root مؤقتة. يتطلب تثبيت KernelSU وجود ksud الذي يتضمن kernelsu.ko لكل إصدار KMI.