HTTP请求走私
HTTP请求走私
在一次比赛中,了解到了HTTP请求走私漏洞,目前我只接触到django和Nginx一起组合,实现负载均衡,所以靠近于代理端,即前端控件的我没怎么了解过。
0x01 漏洞成因
漏洞成因是由于前端控件(一般指代理服务器)对HTTP协议的长度截取和后端服务器的截取不同导致。HTTP规范提供了两种不同的方法来指定请求的结束位置:Content-Length
标头和Transfer-Encoding
标头,若同一请求前端与后端所使用的规范不同就可能导致解析差异,从而造成请求走私。一般服务器有三种解析方式:
1 | CL.TE:前端服务器使用Content-Length标头,而后端服务器使用Transfer-Encoding标头。 |
这里的解析错误主要取决于HTTP1.1中的两个特性:keep-alive 与 pipeline
Keep-Alive:是在 HTTP 请求中增加一个特殊的请求头 Connection: Keep-Alive,告诉服务器,接收完这次 HTTP 请求后,不要关闭 TCP 链接,后面对相同目标服务器的 HTTP 请求,重用这一个 TCP 链接,这样只需要进行一次 TCP 握手的过程,可以减少服务器的开销,节约资源,还能加快访问速度。这个特性在 HTTP1.1 中是默认开启的。
Pipeline(http管线化):http管线化是一项实现了多个http请求但不需要等待响应就能够写进同一个socket的技术,仅有http1.1规范支持http管线化。在这里,客户端可以像流水线一样发送自己的HTTP请求,而不需要等待服务器的响应,服务器那边接收到请求后,需要遵循先入先出机制,将请求和响应严格对应起来,再将响应发送给客户端。
示例如下:
1 | GET / HTTP/1.1 |
在前端控件中会对监测到是一个请求,而后端则可能是认为两个请求。
前端控件认为GET能带body,后端控件认为不带body,分解成两个请求然后返回两个响应,那么第二个响应就绕过了前端的检测,造成了走私。
0x02 Gunicorn 20.0.4 请求走私
当代理使用Haproxy,服务器用的是Gunicorn并且版本高于20.0时,就有了这种新的利用方式。它是由对标头的特殊解析引起的。Sec-Websocket-Key1
同样的原理,前端控件通过Content-Length识别报文的大小,而后端通过Sec-Websocket-Key
来识别报文的长度,
在这里我们是无法访问到fl4g的,但是
https://blog.csdn.net/sycamorelg/article/details/122229190
https://blog.csdn.net/weixin_54902210/article/details/124580510