
Spring-Cloud-Spel-RCE
استنساخ كود البيئة الجاهز من GitHub.
//⚠️ ملاحظة: يجب ألا يحتوي مسار تحميل كود البيئة على أحرف صينية أو مسافات
git clone https://github.com/Ha0Liu/CVE-2022-22947.git

افتح حزمة الكود التي قمنا بتنزيلها للتو باستخدام IDEA: Open ---> مسار الملف الذي تم تنزيله للتو ---> Open.
إنشاء مشروع يدويًا وإعداد البيئة.
(1) إنشاء مشروع جديد، واضغط على "التالي" باستمرار بعد التكوين.

(2) تحليل هيكل دليل المشروع:
1. مجلد .idea يحتوي على ملفات التكوين الافتراضية لـ IntelliJ IDEA، دون استخدامات أخرى، ويمكن حذفه أو الاحتفاظ به حسب الحاجة.
2. مجلد src هو منطقة الكود الرئيسية للمشروع، ويتضمن مجلدين: java وresource. java هو منطقة كتابة كود Java في المشروع، وresource هو منطقة التكوين للمشروع بالكامل. بشكل افتراضي، يضيف مشروع Spring طريقة SpringApplication في java، وهي طريقة البدء الافتراضية لـ Spring، ويضيف application.properties في resource، وهو ملف التكوين لمشروع Spring.
3. مجلد test هو مجلد الاختبار، حيث يمكن اختبار الطرق.
4. ملف pom.xml هو ملف تكوين Maven، والذي يتضمن التبعيات والتكوينات اللازمة للمشروع.
5. ملف .iml هو تكوين حزمة تبعية Maven، ويتم إضافته افتراضيًا أيضًا.
6. مجلد External Libraries يحتوي على جميع حزم التبعية لهذا المشروع.
(3) إضافة تبعيات Maven إلى ملف pom.xml (مستودع Maven يحتوي على تفاصيل جميع التبعيات).
1. سيتم إنشاء جزء من كود XML افتراضيًا في ملف pom، التفاصيل كالتالي:

2. استيراد التبعيات المطلوبة للمشروع. نظرًا لأن هذا المشروع هو مشروع SpringBoot، يجب استيراد تبعية spring-boot-starter كبادئ للخادم. بالإضافة إلى ذلك، نظرًا لأن هذه الثغرة هي ثغرة في بوابة Gateway من Spring Cloud، والإصدار المتأثر هو أقل من 3.1.1، لذا سنستخدم الإصدار 3.1.0 الآن لإعادة إنتاج الثغرة. في نفس الوقت، نحتاج إلى واجهة actuator للمراقبة والوصول إلى البوابة، لذلك نحتاج أيضًا إلى هذه التبعية، التفاصيل كالتالي:

(4) تعديل ملف تكوين Spring (المسار: src --> main --> resources --> application.properties)، التفاصيل كالتالي:
1. server.port هو منفذ بدء تشغيل خادم Spring، المنفذ الافتراضي هو 8080، ويمكن للجميع ضبطه حسب حالتهم.
2. management.endpoint.gateway.enabled=true هو لتفعيل منفذ actuator لفحص بوابة Spring Cloud Gateway، القيمة الافتراضية هي false. نظرًا لأن هذه الثغرة تحتاج إلى مراقبة حالة البوابة وما إلى ذلك، يجب تغييرها يدويًا إلى true لتفعيل المراقبة.
3. management.endpoints.web.exposure.include=gateway هو لاختيار بوابة الخادم كبوابة Gateway، لأن هذه الثغرة هي ثغرة في بوابة Gateway، لذلك نعلن في ملف التكوين اختيار بوابة Gateway.

(5) تعديل فئة Java التي تم إنشاؤها تلقائيًا بعد إنشاء المشروع الجديد (اسم الفئة عادةً ما يكون اسم المشروع + Application، المسار: src --> main --> java --> com.xxx.xxx --> xxxApplication)، التفاصيل موضحة في الشكل أدناه:

(6) بدء تشغيل المشروع، التفاصيل موضحة في الشكل أدناه:

(7) الوصول إلى http://localhost:9000، إذا كانت الصفحة معروضة مثل لقطة الشاشة، فهذا يعني أن إعداد البيئة قد نجح.

(1) أولاً، دعنا نلقي نظرة على التصحيح الرسمي من Spring، الفرق كالتالي: https://github.com/spring-cloud/spring-cloud-gateway/commit/337cef276bfd8c59fb421bfe7377a9e19c68fe1e. قام المسؤولون في الدالة org.springframework.cloud.gateway.support.ShortcutConfigurable#getValue باستبدال StandardEvaluationContext بـ GatewayEvaluationContext لتنفيذ تعبيرات SPEL.

من الشكل أعلاه، يمكن ملاحظة أن هذا التصحيح يتم بشكل أساسي عن طريق تعديل طريقة تحليل تعبير SPEL. من السطر 66، يمكن ملاحظة أن عبارة if تتحقق مما إذا كان تعبير SPEL يبدأ بـ #{ وينتهي بـ }. وظيفة طريقة getValue هي تحليل تعبير SPEL، مما يشير إلى أن هذه الثغرة هي ثغرة RCE ناتجة عن تعبير SPEL.
(2) من خلال النقر بزر الماوس الأيسر مع الضغط على مفتاح Ctrl على حقل getValue، يمكن التتبع عكسيًا للوصول إلى تعداد org.springframework.cloud.gateway.support.ShortcutConfigurable.ShortcutType.

من الطريقة الافتراضية أعلاه، يمكن ملاحظة أنها تستدعي الطريقة DEFAULT في التعداد، تفاصيل الطريقة كالتالي:
default ShortcutType shortcutType() {
return ShortcutType.DEFAULT;
}

(3) التتبع عكسيًا للوصول إلى org.springframework.cloud.gateway.support.ConfigurationService.class#normalizeProperties().

هذه الدالة normalizeProperties() تقوم بتحليل خصائص الفلتر (filter)، حيث يتم تمرير خصائص تكوين الفلتر إلى normalize، وأخيرًا تدخل إلى getValue لتنفيذ تعبير SPEL مما يسبب حقن تعبير SPEL.
(1) وفقًا للوثائق [https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html]، يمكن للمستخدمين إنشاء وحذف المسارات (routes) في البوابة من خلال actuator. الشكل التالي يوضح البنية الأساسية للبوابة.

(2) في IDEA، يمكن استخدام وظيفة mapping الخاصة بـ actuator للعثور على واجهات وظائف إنشاء وحذف المسارات وما إلى ذلك.

(3) التتبع إلى فئة RouteDefinition، ووجد أن هذه الفئة تعلن عن محتوى هيكل المسار.

(4) التتبع إلى فئة FilterDefinition داخلها، ووجد أن Filter يحتوي على معلمتين: name و args.
(5) تتبع هذه المعلمة name، ووجد أنه في طريقة AbstractGatewayControllerEndpoint#save() يتم تصفية name. طريقة save هي واجهة إنشاء المسار، وتستدعي معلمتين: الأولى هي id للمسار (يمكن تخصيصه)، والثانية هي RouteDefinition. كما هو موضح أعلاه، فإن هذا الكائن يعلن عن محتوى هيكل المسار الذي تم إنشاؤه، وهذا يؤدي إلى تفعيل الثغرة.