
Spring Security फ्रेमवर्क में CVE-2022-22978 भेद्यता का PoC
मेरी जानकारी के अनुसार, यह Spring Security फ्रेमवर्क में RegexRequestMatcher क्लास से संबंधित एक कमजोरी है। विशेष रूप से, वे एप्लिकेशन जो RegexRequestMatcher का उपयोग करते हैं और जिनके रेगुलर एक्सप्रेशन में डॉट (.) शामिल है, उन्हें \r(%0a) और \n(%0d) वर्णों द्वारा बायपास किया जा सकता है; जिससे हमलावर बिना प्रमाणीकरण के अनधिकृत पथों तक पहुंच सकते हैं।
Spring Security फ्रेमवर्क के प्रभावित संस्करण:
5.5.x से पहले 5.5.75.6.x से पहले 5.6.4हमें इस कमजोरी का स्थैतिक विश्लेषण करने के लिए Spring Security के स्रोत कोड तक पहुंचना होगा। विशेष रूप से, मैं GitHub पर संस्करण 5.6.3 (कमजोर संस्करण) और 5.6.4 (फिक्स्ड संस्करण) के बीच कमिट की तुलना करने का उपयोग कर रहा हूँ। निम्नलिखित लिंक देखें: Comparing 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 फ्लैग का उपयोग किया जा सकता है।
हालांकि, यदि कोई जानबूझकर \n के बजाय %0d या \r के बजाय %0a का उपयोग करता है, तो उपरोक्त regex फिर भी मेल नहीं खाएगा। इसलिए, संस्करण 5.6.4 में, RegexRequestMatcherTests.java में इस मामले के लिए एक अतिरिक्त जांच जोड़ी गई है। विशेष रूप से, यह %0d और %0a को क्रमशः \n और \r में परिवर्तित करेगा और फिर regex से जांच करेगा।

चरण 1: Spring Initializr का उपयोग करके एक स्प्रिंग बूट वेब एप्लिकेशन बनाएं, जिसमें दो डिपेंडेंसी Spring Security और Spring Web शामिल हों।

चरण 2: एक कंट्रोलर बनाएं जो /admin/* पथ पर अनुरोध आने पर This is a CVE-2022-22978 demo टेक्स्ट प्रिंट करे।

चरण 3: उपयोगकर्ता द्वारा /admin/<कोई भी> पथ तक पहुंचने पर प्रमाणीकरण तंत्र सेट करें, regexMatchers("/admin/.*").authenticated() का उपयोग करके। यह वह कमजोरी है जिसका फायदा हमलावर बिना प्रमाणीकरण के /admin/<कोई भी> पृष्ठों की सामग्री देखने के लिए उठाते हैं।

चरण 4: कॉन्फ़िगरेशन फ़ाइल में, Spring Security के उस संस्करण की घोषणा करें जिसमें कमजोरी है। यहाँ मैं संस्करण 5.6.3 चुन रहा हूँ।

चरण 5: एप्लिकेशन को gradlew bootRun कमांड से चलाएं, प्रोग्राम डिफ़ॉल्ट रूप से Apache Tomcat का उपयोग करके पोर्ट 8080 पर सुनता है। हम /admin/xyz पथ पर पहुंचते हैं (कोई भी पथ /admin/ से शुरू हो सकता है)।

परिणाम 403 Forbidden कोड लौटाता है, जिसका अर्थ है कि प्रमाणीकरण के अभाव में हम पहुंच नहीं सकते।
अब, Spring Security (संस्करण 5.6.3) में regexMatchers फ़ंक्शन की कमजोरी का फायदा उठाते हुए, जो नई पंक्ति के वर्णों \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