Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-43499-S26 — استغلال ثغرة في نواة Android GKI 6.12 للإصدار CVE-2026-43499، عبر تسلسل خطأ rollback في rt_mutex مع الكتابة فوق المكدس pselect للحصول على صلاحيات الجذر على أجهزة Samsung وPixel. | Kitploit
أدوات/GitHubGitHub/sammyenigma/cve-2026-43499-s26
أمان أندرويدتصعيد الامتيازاتتحليل الذاكرة الجنائيآليات الاستمراريةالاستغلالالهندسة العكسيةشيل كودما بعد الاستغلالأمن الجوال

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة
تطوير الحمولات
استغلال الملفات الثنائية
GitHubsammyenigma/cve-2026-43499-s26

CVE-2026-43499-S26

استغلال ثغرة في نواة Android GKI 6.12 للإصدار CVE-2026-43499، عبر تسلسل خطأ rollback في rt_mutex مع الكتابة فوق المكدس pselect للحصول على صلاحيات الجذر على أجهزة Samsung وPixel.

عرض المستودع
1منذ 22 أياملم تتم المراجعة بعد

CVE-2026-43499 — استغلال نواة Android GKI 6.12 عبر pselect / configfs

استغلال لنواة Linux لخط GKI 6.12 على Android (أجهزة Samsung وPixel) يستهدف CVE-2026-43499: خلل في التراجع remove_waiter() داخل rt_mutex_start_proxy_lock() يستخدم current بدلاً من waiter::task، تاركاً pi_blocked_on الخاص بالمنتظر مشيراً إلى rt_mutex_waiter على مكدس النواة الخاص به (الذي يُفرَّغ لاحقاً). بالاقتران مع الكتابة فوق مكدس fd_set عبر pselect() ومسير rb_tree المزيف المدفوع بـ sched_setattr من مستهلك، ينتج عن ذلك بدائية كتابة حتمية في النواة وصلاحيات root كاملة.

يعمل الاستغلال كمكتبة مشتركة LD_PRELOAD (preload.so) ويثبّت خادم su بصلاحيات root بالإضافة إلى خلفية الشاشة كمخلفات ما بعد الحصول على root.

الحالة: تطوير نشط. هدف m1q (ZF1) هو محور التشغيل الأولي. bootstrap الخاص بـ pipei tmp_page-uname هو المسار النشط حالياً: المسير مُثبت نظيفاً على الجهاز (build #33: مناطق rt_mutex مزروعة لكل طفل) والمسح الكامل لـ 168 مرشحاً قيد التنفيذ. مسار configfs CFI طريق مسدود على m1q (Rust ashmem — لا يوجد فتحة fops قابلة للحقن) ويبقى المسار لأهداف C-ashmem. تختلف الإزاحات لكل هدف حسب الجهاز — تحقق منها مقابل ثنائي النواة الفعلي قبل الوثوق بها.

البدائية القابلة للاستغلال (CVE-2026-43499)

عندما تعيد FUTEX_CMP_REQUEUE_PI إدراج منتظر وتعيد سلسلة كشف الجمود -EDEADLK، يتراجع __rt_mutex_start_proxy_lock() عبر remove_waiter() (rtmutex.c:1535). يقوم التراجع بشكل صحيح بإزالة المنتظر من شجرة الانتظار لكنه يمسح pi_blocked_on الخاص بـ مستدعي إعادة الإدراج بدلاً من waiter->task->pi_blocked_on. يبقى pi_blocked_on الخاص بالمنتظر معلقاً عند rt_mutex_waiter على مكدسه، والذي يُفرَّغ بمجرد انتهاء مهلة futex.

بعد انتهاء المهلة، يُعاد استخدام منطقة مكدس النواة الخاصة بالمنتظر: ينسخ core_sys_select() مجموعات fd الثلاث إلى مخزن المكدس هذا (مسار المكدس nfds < 344 على ZF1). تعيد مصفوفة كلمات fd_set المصممة بعناية تشكيل rt_mutex_waiter مزيف / مهمة مزيفة / rt_mutex مزيف (بجذر rb_tree مؤشراته مُتحكَّم بها). ثم يستدعي خيط مستهلك sched_setattr_tid(waiter) → rt_mutex_adjust_pi() → rb_erase_cached، مما ينتج كتابة عنوان عشوائي بقيمة مُتحكَّم بها.

تتطلب البدائية بأكملها دورة سلسلة PI: المالك يحمل f_pi_target ويحجب أيضاً على f_pi_chain (الذي يحمله المنتظر)، لذا تصطدم سلسلة المسير بـ owner → chain → waiter → target → owner وتفشل بـ -EDEADLK. إزالة الدورة تجعل إعادة الإدراج تعود بالنجاح مع تأثير صفري على النواة.

سلسلة الاستغلال

  1. Slide (KASLR) — تسريب قاعدة النواة. مساران:
    • tracefs sched_blocked_reason (m1q الأساسي، مُثبت على الجهاز): يُقرأ PC العودة المحفوظ لعامل kworker محجوب (stack_trace_save_tsk) من المخزن الحلقي ويُقارن بإزاحة worker_thread المُضمَّنة في البناء. يعمل قبل استخدام أي كلمات من مسار boot_id حتى تبقى أهداف كتابة data-alias (data_addr() = p0 alias + slide_p0_offset) صحيحة عند slide غير صفري.
    • مسار boot_id pselect (احتياطي، مستقل عن slide): كتابة pselect تزرع SLIDE_LOGGERS_0_1 في بيانات sysctl الخاصة بـ boot_id عبر alias للخريطة الخطية؛ القيمة المسرَّبة تعيد بناء stext. مُعلَّق على m1q: هدف W1 الخاص به (SLIDE_RANDOM_BOOT_ID_DATA_OFF، ذاكرة فيزيائية منخفضة) له قابلية كتابة تعتمد على الصفحة — يحرّك slide الهدف عبر حدود الصفحات في كل إقلاع، لذا تفشل ~6/7 من التشغيلات. يُستخدم فقط صراحةً عبر SLIDE_FORCE_BOOTID (اختبار آلية) مع إعادة توجيه tree_pc/tree_left إلى الصفحة المرشوشة.
  2. KernelSnitch — رشّ كائنات بحجم mm_struct واستخدم تصادم futex-hash لتحديد موقع على الكومة، مما يسرّب عنوان صفحة كومة النواة المستخدم كقاعدة رشّ الكائنات المزيفة. يُفصل المنتظرون (لا يُضمّون) عند التنظيف لتجنب OOM مكدس النواة الذي أسقط البناءات قبل #26.

شكل المسير (m1q، مُثبت على الجهاز)

تعيد كلمات fd_set الخاصة بـ pselect تشكيل rt_mutex_waiter مزيف على مكدس النواة الخاص بالمنتظر؛ يستدعي sched_setattr_tid(waiter) من خيط مستهلك المسير عبر rt_mutex_adjust_pi(). خريطة كلمات ZF1 (مُتحقق منها بالتفكيك): PSELECT_WAITER_WORD_SHIFT = 0، الكلمة 12 = task (@+0x50)، الكلمة 13 = lock (@+0x58)، الكلمة 14 = wake_state (@+0x60 = 3). مع rt_mutex مزيف مزروع يكتمل المسير بنظافة: rb_erase W1 *(tree_left)=tree_pc / W2 *(tree_pc&~3+8)=tree_left الخاصة بـ [7] هما كتابتا النواة الوحيدتان؛ [11] (setprio / dequeue_pi) و[9] wake كلاهما متخطى (المنتظر المزيف المحلي عند أولوية 100 يبقي عقدة المكدس خارج top-waiter). كل اكتمال دخل المسير منذ build #19 ينجو على الجهاز؛ الأعطال الحتمية قبل ذلك كانت خطأ في وضع حمولة 8 بايت (SKB_DATA_DELTA)، وليس عطلاً في جسم المسير.

المرحلة 3 (جسر pgd-swap، ثابت/بناء فقط)

مرحلة اختيارية STAGE3=1 تفرّخ طفل جسر، تبدّل mm->pgd الخاص به إلى جدول صفحات مزيف مُجهَّز (3 مستويات: PGD→L1→L2، ورقة RX loop + ورقة RW stack)، وتدع الطفل يشغّل كتلة تجميع سجلات فقط تعدّل cred الخاص به عبر نافذة مسح فيزيائي 2MB — قراءة/كتابة فيزيائية لكل الذاكرة دون بدائيات configfs/ pipe. موصولة حالياً فقط بهدف m1q ولم تُشغَّل على الجهاز.

الأهداف المدعومة

41 هدفاً في src/targets/<codename>-<build>/، كل منها يتطلب على الأقل target.h (إزاحات رموز النواة، KIMAGE_TEXT_BASE، قاعدة الخريطة المباشرة، إزاحات البنى). أهداف Pixel (comet، tokay، tegu، caiman، komodo، frankel، mustang، rango، stallion، blazer) تتجاوز المصادر المشتركة؛ أهداف Samsung (m1q-*) تضيف منطقاً خاصاً بالجهاز.

root@kitploit:~
make list-projects   # full list

تختلف تخطيطات بنى النواة حسب الجهاز — يجب التحقق من الإزاحات مقابل ثنائي النواة الفعلي / kallsyms لكل هدف.

البناء

المخرجات: build/<PROJECT>/bin/preload.so (مكتبة مشتركة تُحمَّل عبر LD_PRELOAD).

root@kitploit:~
# Default project
CC=clang make

# Specific device target (default: blazer-CP2A.260605.012)
CC=clang make PROJECT=m1q-BP4A.251205.006

# Without CC=clang: uses NDK if found ($NDK_ROOT / $ANDROID_NDK_HOME /
# $ANDROID_NDK_ROOT), otherwise host clang + Android sysroot
make PROJECT=m1q-BP4A.251205.006

# Show build configuration
make info

# Clean
make clean

يضمّن البناء ثنائي su_daemon بصيغة PIE (src/su_daemon.c، يُبنى إلى build/embed/su_daemon_aarch64_pie) وassets/wallpaper.webp في preload.so عبر src/su_blob.S / src/wallpaper_blob.S.

التشغيل على الجهاز

ادفع مخرجات البناء إلى /data/local/tmp، ثم شغّل الاستغلال تحت LD_PRELOAD. شغّله بدون tee على هدف تشغيل أولي حي — tee يخزّن stdio الخاص به ويفقد ذيل السجل عند panic النواة (stdout الخاص بالاستغلال غير مخزّن، لذا إعادة التوجيه مباشرة إلى ملف تحفظ كل سطر):

root@kitploit:~
adb push build/m1q-BP4A.251205.006/bin/preload.so /data/local/tmp/preload.so
adb push build/embed/su_daemon_aarch64_pie /data/local/tmp/su_daemon_aarch64_pie
adb shell "chmod 755 /data/local/tmp/preload.so /data/local/tmp/su_daemon_aarch64_pie"

adb shell "LD_PRELOAD=/data/local/tmp/preload.so \
  /data/local/tmp/su_daemon_aarch64_pie \
  > /data/local/tmp/output.log 2>&1"

عند النجاح يستمع الخادم على /data/local/tmp/temp_su.sock ويُثبَّت su تحت /apex/com.android.virt/bin.

مسح m1q pipei (التشغيل الأولي الحالي)

يدفع tools/run_pipei.sh الثنائي، ويتحقق من sha256 على الجهاز (ملف preload.so قديم ينتج أحكاماً غير قابلة للقراءة بصمت — شغّل السلم مرة بناءً < #22 يختلف تنسيق سجله)، ثم يشغّل المسح الكامل لـ 168 مرشحاً مقسّماً 3x56 بحيث يفقد panic قطعة واحدة على الأكثر (~10 دقائق). يتدفق stdout الخاص بالاستغلال مباشرة عبر adb (لا إعادة توجيه على الجهاز — tee على جانب الجهاز يفقد الذيل عند panic)؛ تُحفظ نسخة على جانب المضيف من كل قطعة في /tmp/m1q_pipei_chunk{1..3}_stream.log:

root@kitploit:~
sh tools/run_pipei.sh

PASS = أي قطعة تُظهر tmp_page uname changed + after uname='CatOS. يجب ضبط PIPEI_CHILD_REGIONS على الأقل بحجم القطعة وإلا تبقى مناطق rt_mutex لكل طفل غير مزروعة ويموت المسح عند المرشح 0. تتطلب التغطية الكاملة أيضاً TMP_UNAME_PIPEI_SPLIT_ORDER_PAGES=1 — بدونها تُمسح صفحة واحدة فقط من كتلة mm المحررة ذات 8 صفحات. run_pipei_slim.sh هو المتغير التشخيصي لمرشح واحد؛ run_m1q_ladder.sh هو بطارية المسير/العزل (B16-2 oracle، آلية slide، خطوات المسح).

إعدادات وقت التشغيل (متغيرات البيئة)

تخطيط المشروع

root@kitploit:~
exploit/
  Makefile
  assets/                     # wallpaper.webp (embedded post-root artifact)
  src/
    main.c                    # run_exploit() entry point (shared)
    preload.c                 # LD_PRELOAD constructor, su/wallpaper install
    util.c                    # addr translation, page prep, configfs helpers
    pipe.c                    # pipe-based physical read/write
    root.c                    # cred patching / task walk
    slide.c                   # KASLR slide (tracefs + boot_id routes)
    fops.c                    # pselect corruption + fops manipulation
    faketables.c              # stage-3 fake page-table builders (3-level)
    stage3.c                  # pgd-swap bridge child (no-op unless configured)
    stage3_loop.S, stage3_poll.S  # bridge blob + enter trampoline
    su_daemon.c               # root daemon (compiled as separate PIE)
    su_blob.S, wallpaper_blob.S   # embedded binaries
    offset.h                  # pulls per-target target.h via -DTARGET_CONFIG_H
    kernelsnitch/             # mm_struct futex-hash leak library
    targets/<codename>-<build>/    # per-device target.h + optional overrides
poc/poc.c                     # standalone POC (separate from the exploit)

تتجاوز الأهداف المصادر المشتركة عبر آلية pick_src في Makefile: إذا وُجد src/targets/<PROJECT>/<file>.c يُستخدم بدلاً من src/<file>.c المشترك؛ وإلا تُستخدم النسخة المشتركة.

ملاحظات ومزالق

  • لا تُزل دورة سلسلة PI أبداً. تعتمد بدائية الكتابة على فشل إعادة الإدراج بـ -EDEADLK (errno 35). الدورة المفقودة تظهر كـ success=1 مع تأثير صفري على النواة.
  • يجب أن يحمل المنتظر قفل سلسلة PI عبر pselect. تحريره أولاً يسمح للمالك بالاستيقاظ والتسابق مع مسير rb_tree المزيف → panic.
  • m1q: يجب أن يكون PSELECT_WAITER_WORD_SHIFT = 0 (أعماق مكدس ZF1 مُتحقق منها من ELF). لا تزال الأهداف الأخرى افتراضياً على 1 — تحقق لكل جهاز قبل الوثوق بها.
  • p0_data_alias() يستخدم DIRECT_MAP_BASE (الخريطة الخطية)، والذي يختلف عن P0_PAGE_OFFSET على ZF1. يجب أن تستخدم data aliases للكائنات المُشار إليها في النواة الخريطة الخطية.
  • pr_error() قاتل (exit(-1))، بخلاف ماكرو التحذير/المعلومات.
  • إعادة بناء slide تستخدم SLIDE_LOGGERS_0_1، وليس SLIDE_NFULNL_LOGGER؛ الكلمة هي alias للخريطة الخطية غير عشوائي، لذا مسار boot_id مستقل عن slide (استخدمه فقط عند slide=0 — شغّل تسريب tracefs أولاً).
  • (مُقاس على الجهاز، build #19) — رأس شظية skb الحقيقي أقل بـ 8 بايت من -0xe80 المستنبط من التفكيك؛ خطأ الـ 8 بايت هذا تسبب في كل عطل pselect حتمي من البناءات #6-18 (دخل المسير → إشارة عشوائية). قيمة مشتركة في GKI 6.12؛ نسخ util.c لكل هدف تحمل مفتاح A/B بيئي . لا تُكدّس فوق الثابت المُضمَّن.

إخلاء المسؤولية

هذا كود استغلال لأجهزة Android ومخصص لأبحاث الأمن، واختبار الثغرات المصرح به، وأعمال الدفاع على أجهزة تملكها أو لديك إذن صريح باختبارها. إساءة الاستخدام على أجهزة لا تملكها غير قانونية. المؤلف غير مسؤول عن الأجهزة المعطوبة، أو النوى المعطوبة، أو الضمانات الملغاة.

تنزيل الأداة
mm_struct
  • المسار الرئيسي — bootstrap الخاص بـ pipei tmp_page (m1q، التركيز الحالي) — مسار configfs CFI الأصلي طريق مسدود على m1q: لا يملك Rust ashmem فتحة write_iter ثابتة قابلة للحقن وكائن كومة ASHMEM_SET_NAME هو KVec لا يتوافق تخطيطه مع private_data الخاص بـ configfs_bin_write_iter. يتحول m1q إلى كتابة kmalloc بدلاً من ذلك: استعادة كتلة mm المسرَّبة من الرتبة 3 ككائنات pipe_inode_info واستخدام كتابة pselect W1 (*(tree_left) = tree_pc) للكتابة فوق فتحة tmp_page الخاصة بمرشح (+0x90) بصفحة UTS namespace (init_uts_ns). كتابة fanout تزرع اسم علامة عند إزاحة sysname ويُبلّغ uname() عن "CatOS" — كتابة نواة قابلة للتحقق دون اعتماد على كائن ثابت. تحتفظ أهداف C-ashmem بمسار configfs.
  • Pipe physrw — تزوير صفحات مخزن pipe في صفحة النواة المرشوشة للقراءة/ الكتابة الفيزيائية: تعديل cred، تعطيل SELinux، والتلاعب المباشر بذاكرة النواة.
  • Root — تعديل cred الخاص بالطفل الجذر (uid/gid/caps/SELinux SID)، ثم يثبّت preload.c خادم su المُضمَّن (مُثبَّت عبر tmpfs في /apex/com.android.virt/bin، بالإضافة إلى متغيرات adbd-namespace والمتغيرات المحلية) ويبدّل خلفية الشاشة.
  • VariableDefaultPurpose
    PSELECT_ROUTE_SHIFTcompile-timeA/B fd_set word shift for the main route (m1q)
    SLIDE_SHIFTcompile-timeA/B fd_set word shift for the slide route
    PSELECT_ROUTE_DELAY_USEC50000Consumer delay before sched_setattr (must be > 0)
    SLIDE_CONSUME_USEC, SLIDE_ENTER_DELAY_USEC, SLIDE_CONSUMER_CORE—Slide route timing/pinning
    SKIP_SLIDE0Use direct-map fallback (slide = 0)
    SLIDE_ONLY0Run only the KASLR slide and exit
    SLIDE_P0_OFFSET, SLIDE_BOOTID_OFF—Override slide p0-alias / boot_id offsets
    SLIDE_FORCE_BOOTID0Force the boot_id pselect route after the tracefs slide (mechanism test)
    KSNITCH_COLLISIONS4KernelSnitch collision count
    STAGE30Enable the pgd-swap bridge child phase (m1q)
    STAGE3_DRYRUN0Stage/verify tables then abort before the swap
    PAGE_RECLAIM_SENDS, PSELECT_SIMPLE_LAYOUT—Spray/fd-set layout tweaks
    TMP_PAGE_UNAME0Run the m1q pipei tmp_page-uname bootstrap
    TMP_UNAME_PIPEI_SWEEP, TMP_UNAME_PIPEI_ALIGN_ORDER, TMP_UNAME_PIPEI_SPLIT_ORDER_PAGES—Sweep mode; split_order sweeps all 8 pages of the freed mm block
    TMP_UNAME_PIPEI_SLOT, TMP_UNAME_PIPEI_SLOT_CANDIDATES—Sweep range (chunk start / count)
    PIPEI_CHILD_REGIONS0Per-child seeded rt_mutex regions; MUST be >= sweep chunk or unseeded regions panic at candidate 0
    PIPEI_RECLAIM_COUNT, PIPEI_DRAIN_COUNT—Reclaim/drain pipe pairs; raise on a reclaim miss
    PIPEI_SPONGE_MB3072Order-0 flood sponge held across the reclaim (build #29)
    PSELECT_W0_PRIO_OVERRIDE130Top-waiter prio; inert with seeded regions (legacy stale-tree guard, A/B only)
    PSELECT_SKB_DELTA_OVERRIDE0A/B payload intra-page offset (only if a device differs from -0xe78)
    TMP_UNAME_NAME, TMP_UNAME_HOLD_SEC"CatOS", 5Marker name / hold time after success
    SKB_DATA_DELTA هو -0xe78
    SKB_DATA_DELTA
    PSELECT_SKB_DELTA_OVERRIDE
  • جسم المسير نظيف؛ الوضع كان الخلل. مع الحمولة المزروعة عند الإزاحات المُنمذجة يكتمل مسير السلسلة دون أخطاء على الجهاز. عطل دخل المسير يعني أن الذاكرة عند عناوين كلمات fd ليست الحمولة (تسابق استعادة/وضع)، وليس خطأ في النموذج.
  • m1q: مسار configfs CFI طريق مسدود (Rust ashmem) — لا فتحة fops ثابتة قابلة للحقن ومغلف KVec الخاص بـ ASHMEM_SET_NAME لا يتوافق مع configfs_bin_write_iter. استخدم bootstrap الخاص بـ pipei tmp_page. حراس PSELECT_WRITE_RIGHT_SPRAYED / PSELECT_PI_TOP_TASK_SELF في target.h الخاص بـ m1q تعيد توجيه كتابات [11] للمسير بعيداً عن fops الثابتة للقراءة فقط.
  • مناطق rt_mutex لكل طفل (build #33): كل طفل مسح يعيد توجيه كلمة fd w13 إلى منطقته المزروعة الخاصة (payload+0x6000 + idx*0x40) داخل الصفحة المستعادة. مسحات fake_lock المشتركة أُصيبت بـ panic عند المرشح ~9-12 (عقد مكدس نواة قديمة أُعيد تدويرها)، ومناطق build #32 الفارغة أُصيبت بـ panic عند المرشح 0 ([9] owner==NULL wake على fake_task المملوء بـ 0x41). يجب ضبط PIPEI_CHILD_REGIONS وإلا تبقى المناطق غير مزروعة.
  • slide boot_id pselect على m1q مُعلَّق — هدف W1 الخاص به ذاكرة منخفضة تختلف قابلية كتابة صفحاتها حسب الإقلاع؛ tracefs هو الأساسي ويقيس slide في كل تشغيل.