
استغلال PoC لـ Snipe-IT للثغرتين CVE-2025-59712 و CVE-2025-59713
يوفر إثبات المفهوم هذا سكربتًا آليًا لاستغلال CVE-2025-59712 (XSS في ترويسة User-Agent) وCVE-2025-59713 (إلغاء التسلسل غير الآمن).
تم اكتشاف هاتين الثغرتين بواسطة Synacktiv أثناء بحث في ثغرات برنامج Snipe-IT. Snipe-IT هو نظام مفتوح المصدر لإدارة الأصول مبني على Laravel ومصمم لمساعدة المؤسسات على تتبع وإدارة أصولها المادية والرقمية.
يمكن العثور على تقرير تقني في النشرة الأمنية المخصصة على موقع Synacktiv.
يوفر هذا السكربت ثلاثة أوامر فرعية، تتوافق مع أوضاع الاستغلال: xss وrce وfullchain.
يستغل هذا الأمر الفرعي CVE-2025-59712، والذي يسمح لمستخدم بصلاحيات منخفضة بحقن كود JavaScript تعسفي في صفحة HTML المعروضة عند استدعاء المسار /reports/activity. لا يمكن القيام بذلك إلا بواسطة مستخدم admin، أو مستخدم لديه صلاحيات عرض صريحة للتقارير. يكون الحقن ممكنًا بسبب عدم تعقيم حقل بشكل صحيح عندما يقوم المستخدم بتحديث معلومات ملفه الشخصي.
User-Agentللقيام بذلك، سيقوم أولاً بتسجيل الدخول كمستخدم بصلاحيات منخفضة، ثم يحقن كود JavaScript المحدد في الملف المقدم عبر الخيار --javascript.
$ python3 exploit.py xss --help
Usage: exploit.py xss [OPTIONS]
Execute XSS attack only with custom JavaScript payload
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * --url -u TEXT Target Snipe-IT URL [required] │
│ * --login -l TEXT Low-privileged username [required] │
│ * --password -p TEXT Low-privileged password [required] │
│ * --new-name -n TEXT New name for low-privileged user [required] │
│ * --javascript -js TEXT Path to custom JavaScript file [required] │
│ --proxy -x TEXT HTTP proxy (http://ip:port) │
│ --verbose -v [quiet|normal|verbose] Logging verbosity [default: normal] │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
[!IMPORTANT]
أثناء البحث الأمني، أُجريت الاختبارات على إصدار من Snipe-IT يعرض افتراضيًا حقلUser-Agentالذي يُحقن فيه JavaScript الضار. منذ commit 10e5d88، لم يعد يتم عرض خاصيةUser-Agentافتراضيًا عند عرض جدول سجل الإجراءات. لذلك، يجب على المسؤول الذي سيشغّل XSS أن يكون قد حدد خانةUser-Agentفي خيارات العرض لإصدارات Snipe-IT اللاحقة لهذا الالتزام.
يستغل هذا الأمر الفرعي CVE-2025-59713، والذي يسمح بتنفيذ الأوامر عن بُعد (RCE) عند معرفة بيانات اعتماد مستخدم admin أو superadmin. وللقيام بذلك، يتم تنفيذ الخطوات التالية:
db-dumps/mysql-snipeit.sql، والتي تنشئ حقلًا مخصصًا جديدًا وتعدّل آخر سجل إجراءات بكائن JSON يحتوي على سلسلة Laravel pop عند الاستعادة.[!TIP] افتراضيًا، يتضمن Snipe-IT ملف
.envفي النسخة الاحتياطية. إذا اكتشف السكربت هذا الملف، يتم عرض قيمةAPP_KEYوحفظ ملف.envفي دليل./output(ويمكن تحديد موقع مخصص لهذا الملف باستخدام--output-dir).
[!CAUTION] استعادة نسخة احتياطية تؤدي إلى فصل جميع المستخدمين المتصلين بالمثيل.
/api/v1/reports/activity، مما يؤدي إلى تشغيل إلغاء التسلسل وتنفيذ سلسلة Laravel pop.$ python3 exploit.py rce --help
Usage: exploit.py rce [OPTIONS]
Execute RCE attack only (requires existing admin account)
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * --url -u TEXT Target Snipe-IT URL [required] │
│ * --admin-user -au TEXT Admin username [required] │
│ * --admin-pass -ap TEXT Admin password [required] │
│ --output-dir -od PATH Output dir for .env file [default: /home/ninja/Téléchargements/snipe-it-advisory/exploit/output] │
│ --shell-ip -si TEXT Reverse shell IP address │
│ --shell-port -sp INTEGER Reverse shell port │
│ --command -c TEXT Custom command (overrides reverse shell) │
│ --proxy -x TEXT HTTP proxy (http://ip:port) │
│ --verbose -v [quiet|normal|verbose] Logging verbosity [default: normal] │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
يهدف الأمر الفرعي fullchain إلى ربط ثغرتي XSS وRCE معًا. وهو يتوافق مع سيناريو لا تملك فيه سوى الوصول إلى مستخدم بصلاحيات منخفضة وتريد تحقيق تنفيذ الأوامر عن بُعد. لن يعمل هذا إلا إذا كان المستخدم الذي يزور صفحة /reports/activity هو admin أو superadmin. في الواقع، فقط هذه الأدوار لديها الحق في إنشاء واستعادة نسخة احتياطية، وهو أمر ضروري لتسميم قاعدة البيانات وتشغيل سلسلة Laravel pop لاحقًا.
وللقيام بذلك، سيقوم السكربت بما يلي:
--command، كما في وضع RCE).User-Agent بوسم <scr> لإجبار متصفح الضحية على جلب قالب JavaScript الخبيث./reports/activity، يتم تشغيل XSS ويتم تحميل JavaScript الخبيث وتنفيذه بواسطة متصفح الضحية. ومنذ تلك اللحظة، يتم تنفيذ نفس الخطوات المنفذة في وحدة RCE، ولكن بلغة JavaScript.يستخدم هذا الوضع عدة مكتبات JavaScript إضافية، ويعود الفضل كله إلى مؤلفيها:
$ python3 exploit.py fullchain --help
Usage: exploit.py fullchain [OPTIONS]
Execute full attack chain: XSS -> Backup manipulation -> RCE
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * --url -u TEXT Target Snipe-IT URL [required] │
│ * --login -l TEXT Low-privileged user's username [required] │
│ * --password -p TEXT Low-privileged user's password [required] │
│ * --new-name -n TEXT New name for low-privileged user [required] │
│ --ip -i TEXT HTTP server IP address (default: auto-detect) │
│ * --port -P INTEGER HTTP server port [required] │
│ --admin-user -au TEXT Admin username to create [default: admin_rce] │
│ --admin-pass -ap TEXT Admin password to create [default: password123] │
│ --shell-ip -si TEXT Reverse shell IP address │
│ --shell-port -sp INTEGER Reverse shell port │
│ --command -c TEXT Custom command (overrides reverse shell) │
│ --proxy -x TEXT HTTP proxy (http://ip:port) │
│ --verbose -v [quiet|normal|verbose] Logging verbosity [default: normal] │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
لتشغيل هذا السكربت، نفّذ الأوامر التالية:
$ git clone https://github.com/synacktiv/CVE-2025-59712_CVE-2025-59713
$ cd CVE-2025-59712_CVE-2025-59713
$ python3 -m venv .venv && source .venv/bin/activate
$ python3 -m pip install -r requirements.txt
يتم أيضًا توفير ملف Dockerfile من أجل تجربة السكربت وإعادة إنتاج استغلال الثغرة. يقوم بسحب إصدار ضعيف (قابل للاستغلال) من Snipe-IT، ويضبط قاعدة البيانات باستخدام php artisan، وينشئ مستخدمين اثنين:
admin بكلمة مرور افتراضية AdminPassword123!lowpriv بكلمة مرور افتراضية LowPrivUser123!قبل تشغيل الحاوية، يجب تحديث ملفي .env وsnipe-it.conf بعنوان URL لمثيل Snipe-IT:
$ sed -i 's|^APP_URL=.*|APP_URL=http://<IP>:<PORT>|' .env
$ sed -i 's|\(ServerName\s*\).*|\1http://<IP>:<PORT>|' snipe-it.conf
يمكن بعد ذلك تشغيل الحاوية:
$ docker build . -t "snipe-it-cve"
$ docker run -p 80:80 --name "snipe-it-debian" snipe-it-cve:latest