http走私问题本质为前端服务器 (负载均衡器/反向代理) 与后端服务器对于http请求的解析不一致,发生于 HTTP/1.1 协议中

CL与TE

HTTP规范提供了两种不同的方法来指定请求的结束位置

CL:Content-Length,指定消息体的以字节为单位的长度

POST /search HTTP/1.1
Host: normal-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 11

q=smuggling

TE:Transfer-Encoding,指定消息体的用途分块编码,每个块均由以 字节为单位的块大小(以十六进制表示)+ 换行符 + 块内容 组成

POST /search HTTP/1.1
Host: normal-website.com
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked

b
q=smuggling
0

单个消息可能会同时使用这两种方法,从而使它们彼此冲突

三种传统攻击

CL.TE

前端CL 后端TE

靶场:https://portswigger.net/web-security/request-smuggling/lab-basic-cl-te

This lab involves a front-end and back-end server, and the front-end server doesn’t support chunked encoding. The front-end server rejects requests that aren’t using the GET or POST method.

To solve the lab, smuggle a request to the back-end server, so that the next request processed by the back-end server appears to use the method GPOST.

exp:

alt

前端服务器识别CL,长度为6,将所有内容传给后端服务器,后端服务器识别TE,会把最后的G留在缓冲区,下一次http请求时会被合并

TE.CL

前端TE 后端CL

靶场:https://portswigger.net/web-security/request-smuggling/lab-basic-te-cl

This lab involves a front-end and back-end server, and the back-end server doesn’t support chunked encoding. The front-end server rejects requests that aren’t using the GET or POST method.

To solve the lab, smuggle a request to the back-end server, so that the next request processed by the back-end server appears to use the method GPOST.

exp:

alt

前端服务器识别TE,后端服务器识别CL,如果第一个CL为4,则正好将GPOST开始的body部分全部留在缓冲区,与下一次http请求合并

注意最后面的 Content-Length 必须大于 5,5正好是最后0和两个换行符的长度,如果等于5后端服务器就不会再将走私的内容与下一条http请求合并, Content-Length 最大值根据下一个http请求包而定,最大值为 5 + http数据包长度

下一个http请求包长度为704:

alt

注意要修改 Content-Length 的同时还要修改chunk大小:

alt

如果是710就会超时,因为只发送了一个http数据包,长度不足,后端服务器接收不到710长度的内容:

alt

TE.TE

前后端TE,目标是让其中一部分无法正常识别TE,从而转变为CL.TE或TE.CL

靶场:https://portswigger.net/web-security/request-smuggling/lab-obfuscating-te-header

This lab involves a front-end and back-end server, and the two servers handle duplicate HTTP request headers in different ways. The front-end server rejects requests that aren’t using the GET or POST method.

To solve the lab, smuggle a request to the back-end server, so that the next request processed by the back-end server appears to use the method GPOST.

靶场中的前端服务器对于TE的格式要求更宽松,可以处理格式错误的TE:

Transfer-Encoding: xchunked

Transfer-Encoding : chunked

Transfer-Encoding: chunked
Transfer-Encoding: x

Transfer-Encoding:[tab]chunked

[space]Transfer-Encoding: chunked

X: X[\n]Transfer-Encoding: chunked

Transfer-Encoding
: chunked

而后端服务器如果出现不符合要求TE格式则转而处理CL,因此可以转换为TE.CL

exp:

alt

本质就是一个有两个TE的TE.CL

漏洞检测

CL.TE

alt

前端服务器根据CL获取4字节内容,后端服务器识别TE,但是未识别到终止符,继续等待新的chunk,导致超时

最后的X用于区别TE.CL,因为TE只能用十六进制字符来标识内容长度,如果是TE.CL则会直接抛错:

alt

TE.CL

alt

前端服务器识别TE,未获取到任何内容,后端服务器根据CL等待6字节导致超时

参考资料:

https://portswigger.net/web-security/request-smuggling