
إثبات مفهوم يوضح تجاوز التفويض في RegexRequestMatcher الخاص بـ Spring Security (CVE-2022-22978) باستخدام حقن CRLF، مع خطوات التحليل والتخفيف.
وفقًا للمعلومات التي توصلت إليها، هذه ثغرة تتعلق بالصنف RegexRequestMatcher في إطار عمل Spring Security. على وجه التحديد، التطبيقات التي تستخدم RegexRequestMatcher والتي تحتوي تعبيراتها العادية على نقطة (.) يمكن تجاوزها باستخدام الأحرف \r(%0a) و \n(%0d)؛ وبالتالي، يمكن للمهاجمين الوصول إلى المسارات غير المصرح بها دون الحاجة إلى المصادقة.
إصدارات إطار عمل Spring Security المتأثرة بالثغرة:
5.5.x قبل 5.5.75.6.x قبل 5.6.4نحتاج إلى الوصول إلى الكود المصدري لـ Spring Security لتحليل الثغرة بشكل ثابت. على وجه التحديد، استخدمت ميزة مقارنة الالتزامات بين الإصدارين 5.6.3 (الإصدار المتأثر) و5.6.4 (الإصدار المُصحح) على Github. انظر الرابط التالي: مقارنة 5.6.3...5.6.4 · spring-projects/spring-security (github.com)

قمت بفحص التغييرات في الصنف RegexRequestMatcher. يمكن ملاحظة أنه في الإصدار 5.6.4، يستخدم هذا الصنف Pattern.DOTALL بدلاً من استخدام . الافتراضي كما في الإصدار 5.6.3.
حيث:
Pattern : هو أحد الصنوف الثلاثة في الحزمة java.util.regex، وظيفته معالجة التعبيرات العادية.Pattern.DOTALL : عند استخدام هذه العلامة، فإن "." في التعبير العادي ستطابق جميع الأحرف، بما في ذلك أحرف السطر الجديد مثل \n , \r.Pattern.CASE_INSENSITIVE: لا تفرق بين الأحرف الكبيرة والصغيرة.
افتراضيًا، تطابق النقطة . في التعبير العادي جميع الأحرف باستثناء أحرف السطر الجديد مثل \n, \r. وبالتالي، إذا كانت هناك دالة regex للتحقق من نمط سلسلة ما، فإن دالة regex تلك لن تطابق إذا كانت السلسلة تحتوي على أحرف سطر جديد. لتجنب ذلك، يمكن استخدام العلامة Pattern.DOTALL.
ومع ذلك، إذا قام شخص ما عمدًا باستخدام %0d بدلاً من \n أو %0a بدلاً من \r، فإن regex أعلاه لن يطابق. وبالتالي، في الإصدار 5.6.4، تمت إضافة فحص إضافي لهذه الحالة في RegexRequestMatcherTests.java. تحديدًا، يقوم بتحويل %0d و %0a إلى \n و \r على التوالي ثم يقوم بالتحقق باستخدام regex.

الخطوة 1: إنشاء تطبيق ويب Spring Boot باستخدام Spring Initializr مع تبعيتين: Spring Security و Spring Web.

الخطوة 2: إنشاء Controller يطبع النص This is a CVE-2022-22978 demo عند وجود طلب إلى المسار /admin/*

الخطوة 3: إعداد آلية المصادقة في كل مرة يصل فيها المستخدم إلى المسار /admin/<أي> باستخدام regexMatchers("/admin/.*").authenticated(). هذه هي الثغرة التي يستغلها المهاجمون لعرض محتوى صفحات /admin/<أي> دون مصادقة.

الخطوة 4: في ملف التكوين، قم بتعريف إصدار Spring Security الذي يحتوي على الثغرة. هنا اخترت الإصدار 5.6.3.

الخطوة 5: تشغيل التطبيق باستخدام الأمر gradlew bootRun، البرنامج يستخدم Apache Tomcat افتراضيًا للإصغاء على المنفذ 8080. نصل إلى المسار /admin/xyz (أي مسار طالما يبدأ بـ /admin/).

النتيجة تعيد رمز 403 Forbidden مما يعني أنني لا أستطيع الوصول بسبب عدم المصادقة.
عند هذه النقطة، نستغل ثغرة دالة regexMatchers في Spring Security (الإصدار 5.6.3) حيث لا تطابق أحرف السطر الجديد مثل \r(%0d) و \n(%0a) → يمكنني الوصول إلى المسار أعلاه دون مصادقة باستخدام الحمولة /admin/%0dxyz

وبالمثل مع الحمولة /admin/%0axyz

وهكذا تمكنا من استغلال ثغرة CVE-2022-22978 بنجاح باستخدام حمولة بسيطة للغاية.
5.7.1
محاولة مهاجمة الويب باستخدام نفس الحمولة أعلاه: /admin/%0dxyz

عند هذه النقطة، لم يعد التطبيق يعيد الرد كما يريد المهاجم.
git clone https://github.com/ducluongtran9121/CVE-2022-22978-PoC.git
cd CVE-2022-22978-PoC
gradlew bootRun
Java 18
Gradle 7.4.1