Sploitus

Exploit for CVE-2026-46215-POC

kitploit · 2026-08-25

Exploit Code

MARKDOWN143 lines
## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-0XCYBERSTAN-CVE-2026-46215-POC
# CVE-2026-46215: استخدام بعد التحرير في `change_handle` بجيم درم (تصعيد صلاحيات محلي غير مميز)

تصعيد صلاحيات محلي عبر استخدام بعد التحرير في ioctl الأساسي لـ DRM `DRM_IOCTL_GEM_CHANGE_HANDLE` (`drm_gem_change_handle_ioctl`, رقم ioctl 0xD2). يمكن الوصول إليه من قبل أي مستخدم لديه إمكانية الوصول إلى عقدة العرض (`/dev/dri/renderD*`، والتي تُمنح للجلسة النشطة بواسطة systemd-logind على جميع توزيعات سطح المكتب الرئيسية). تأخذ السلسلة في هذا المستودع ثغرة الاستخدام بعد التحرير UAF إلى جذر بدون كلمة مرور من مستخدم غير مميز.

  * **CVE:** CVE-2026-46215 (عالي، 7.8، `AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H`)
  * **مُقدَّم:** v6.18-rc1، الالتزام `53096728b891` ("drm: إضافة واجهة DRM الأساسية لإعادة تعيين معالج GEM"، David Francis / AMD)، تمت إضافته لعمل CRIU من AMD
  * **تم الإصلاح في:** 6.18.32, 7.0.9, 7.1-rc3 (المصدر الرئيسي `5e28b7b94408`). يتم أيضًا تعطيل ioctl في المصدر الرئيسي في 7.1 بسبب هذه الثغرة والسباقات ذات الصلة.
  * **المتأثرة:** من v6.18-rc1 حتى الإصدارات المصلحة أعلاه



## الإسناد

تم الإبلاغ عن هذه الثغرة لأول مرة بواسطة Puttimet Thammasaeng، الذي يحمل إسناد `Reported-by` في الإصلاح الرسمي. لقد اكتشفتها وأبلغت عنها بشكل مستقل إلى some-email@example.com في 2026-04-12. تم الاعتراف بتقريري وإعادة توجيهه إلى المشرفين، لكن التقرير السابق هو المعتمد في المصدر الرئيسي. يحتوي هذا المستودع على تحليلي واستغلالي الخاص.

الشرح: https://cyberstan.co.uk

## حالة الإفصاح

الإصلاح موجود في نوى مستقرة تم إصدارها (6.18.32 و 7.0.9 فصاعدًا). تم نشر هذا المستودع بعد أن أصبحت الإصلاحات متاحة على نطاق واسع.

## الثغرة

تنقل الدالة `drm_gem_change_handle_ioctl()` كائن GEM من معالج إلى آخر ولكنها لا تقوم أبدًا بضبط `obj->handle_count`. كما أنها تتجاوز `drm_vma_node_allow/revoke` وردود الاتصال الخاصة بفتح/إغلاق المشغل. نظرًا لأن `handle_count` يبقى عند 1، فإن `GEM_CLOSE` المتزامن على المعالج القديم يخفضه إلى 0 ويحرر الكائن بينما لا يزال المعالج الجديد يشير إليه في IDR. هذا المعالج المعلق هو الاستخدام بعد التحرير، والذي يتم الوصول إليه لاحقًا في `drm_gem_object_release_handle()`.

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

  1. سباق `GEM_CHANGE_HANDLE` ضد `GEM_CLOSE` للحصول على معالج معلق.
  2. استعادة فتحة slab للكائن المحرر باستخدام مصفوفة `pipe_buffer` مرشوشة (msg_msg feng shui لتكييف kmalloc-512، ثم أنابيب مليئة بـ splice).
  3. تسريب `pipe_buf_ops` عبر ioctl معلومات المشغل: `obj->size` (الإزاحة 216) يتداخل مع `pipe_buf[5].ops`، مما يعطي مؤشر نواة وأساس KASLR.
  4. ربط المعالج المعلق عبر FLINK بحيث يقع `obj->name` (الإزاحة 224) على `pipe_buf[5].flags` ويضبط `PIPE_BUF_FLAG_CAN_MERGE` (name = 16 = 0x10).
  5. الكتابة إلى الأنابيب للدمج في ذاكرة التخزين المؤقت للصفحات والكتابة فوق ملف للقراءة فقط (على غرار DirtyPipe). الهدف هو `/etc/passwd`، يصبح الجذر بدون كلمة مرور.



تم التحقق من الإزاحات عبر `pahole` وهي خاصة بالتخطيط عبر 6.18 إلى 7.0. قم بتجاوز تعريفات `GEM_*` / `PIPEBUF_*` للنوى الأخرى.

## الملفات

  * `poc.c` \- الاستغلال. بناء ثابت مع `-lpthread`.
  * `run_exploit.sh` \- يبني إثبات المفهوم PoC ونظام initramfs بسيط، ويقلعه في QEMU.



## المتطلبات الأساسية للمضيف

`qemu-system-x86_64`، `gcc`، `busybox` (ثابت)، `fakeroot`، `cpio`، `gzip`. يُوصى باستخدام KVM (`/dev/kvm`)؛ السباق أكثر موثوقية بكثير معه.

## بناء نواة اختبارية

يحتاج الاستغلال إلى هدف ضعيف مبني بخيارات محددة:

  * يجب أن يكون `CONFIG_KASAN` مغلقًا. يقوم KASAN بعزل slabs المحررة ويمنع استعادة رش الأنابيب، لذا لن يعمل الاستغلال ضد بناء KASAN.
  * مشغل DRM يعرض حقول الحجم/الاسم عند الإزاحات المتوقعة: `virtio_gpu` (المستخدم في العرض التوضيحي) أو `nouveau`.
  * `CONFIG_DRM=y`, `CONFIG_DRM_VIRTIO_GPU=y`, `CONFIG_DEVTMPFS=y`, `CONFIG_BLK_DEV_INITRD=y`.



الخطوات:

  1. سحب شجرة مصدر من 6.18 إلى 7.0 (أو أي شجرة تفشل في الفحص المصلح أدناه).
  2. تعيين خيارات التهيئة أعلاه وتأكد من عدم تعيين `CONFIG_KASAN`.
  3. `make -j"$(nproc)" bzImage`, producing `arch/x86/boot/bzImage`.



يقلع العرض التوضيحي مع `nokaslr` بحيث يكون المؤشر المسرب حتميًا. التسريب يهزم KASLR بمفرده، لذا فإن تشغيل KASLR يعمل أيضًا، فقط العنوان يختلف لكل إقلاع.

## التحقق مما إذا كانت الشجرة قابلة للثغرة أم مصلحة

انظر إلى `drivers/gpu/drm/drm_gem.c`، الدالة `drm_gem_change_handle_ioctl()`.

الفحص السريع:

root@kitploit:~
    
    
    awk '/^int drm_gem_change_handle_ioctl/,/^}/' \
        drivers/gpu/drm/drm_gem.c | grep -c handle_count
    

  * `0` يعني قابل للثغرة (لا يوجد معالجة للعداد المرجعي).
  * غير صفري يعني مصلح.



حسب البنية:

  * قابل للثغرة: يأخذ `file_priv->prime.lock`، ثم `idr_alloc(&file_priv->object_idr, obj, ...)` واحدة، ثم `idr_remove()` على المعالج القديم. لا يوجد `drm_gem_object_handle_get`.
  * مصلح: إدخال على مرحلتين (`idr_alloc` ثم `idr_replace(NULL)` لفصل المعالج القديم)، مع استبدال الكائن الحقيقي فقط بمجرد نجاح عمليات prime.



## تشغيل الاستغلال

root@kitploit:~
    
    
    ./run_exploit.sh /path/to/bzImage
    

يبني `poc.c`، ويغلّفه في initramfs، ويقلع QEMU مع `-device virtio-gpu-pci` و `nokaslr`. يتم تشغيل إثبات المفهوم PoC كـ uid 1000 (غير مميز)، ثم يطبع السكربت `/etc/passwd` قبل وبعد ويهبط بك إلى شل. اترك الجهاز الافتراضي باستخدام `poweroff -f` أو `Ctrl-A X`.

## المخرجات المتوقعة

root@kitploit:~
    
    
    [!] Race won (iter 977): handle=132049
    [!] KASLR: pipe_buf_ops = 0xffffffff82428400
    [!] EXPLOIT SUCCESSFUL
    [!] FLINK: 16 = 0x10
    [*] /etc/passwd:
        root::0:0:pwned:/root:/bin/sh
    [!] LPE CONFIRMED
    [!] root account is now passwordless
    

يتم الكتابة فوق ملف `/etc/passwd` للقراءة فقط (chmod 444) المملوك للجذر بواسطة عملية غير مميزة. يفقد سطر `root:` حقل كلمة المرور الخاصة به.

## الموثوقية

  * حوالي 99% لكل إقلاع في الاختبارات (99/100 على 100 إقلاع جديد، بالإضافة إلى 53/53 في تشغيلات سابقة). يقوم إثبات المفهوم بإعادة المحاولة داخليًا: عند تسريب سيء، يعيد السباق للحصول على كائن معلق جديد بدلاً من إعادة رش شق ميت، حتى 200 جولة، كل جولة بضع عشرات من الميلي ثانية. معظم عمليات الإقلاع تفوز في السباق الأول؛ الأسوأ الذي لوحظ استخدم 11 من أصل 200 جولة.
  * وضع فشل نادر (حوالي 1%): تداخل سباق خاسر يفسد حالة النواة ويعلق الجهاز الافتراضي (تعلق صامت، لا تتم طباعة حكم). هذا متأصل في سباق نواة من نوع UAF. إذا لم تطبع عملية تشغيل حكمًا خلال 30 ثانية تقريبًا، قم بإعادة التشغيل ثم التشغيل مرة أخرى.



## تأكيد الإصلاح

أعد البناء ضد شجرة مصلحة (6.18.32, 7.0.9, 7.1-rc3 أو أحدث، أو أي شجرة تجتاز الفحص المصلح أعلاه) وأعد التشغيل:

root@kitploit:~
    
    
    ./run_exploit.sh /path/to/patched-bzImage
    

ضد النواة المصلحة، لا يجب أن يصل الاستغلال أبدًا إلى "EXPLOIT SUCCESSFUL": السباق لم يعد يحرر الكائن من تحت المعالج الجديد، لذا لا يعيد التسريب مؤشر نواة صالحًا.

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

نُشر لأغراض البحث والدفاع بعد شحن الإصلاحات الرسمية. يُقدم كما هو. قم بتشغيله فقط ضد أجهزة افتراضية تتحكم بها.