HTTP 请求夹带漏洞——预防方法:使用HTTP / 2进行后端连接,为前端和后端服务器使用完全相同的Web服务器软件,后端服务器拒绝模糊请求并关闭网络连接来避免漏洞
如何构造 HTTP 请求夹带漏洞
HTTP请求夹带漏洞出现的原因是因为HTTP规范提供了两种不同的方式来指定请求的结束位置:Content-Length标头和Transfer-Encoding标头。
Content-Length标头很简单,它以字节为单位指定消息体的长度。 例如:
POST /search HTTP/1.1
Host: normal-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
q=smuggling
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
由于HTTP规范提供了两种不同的方法来指定HTTP消息的长度,因此单个消息可以同时使用这两种方法,这样它们就会相互冲突。
HTTP规范试图通过声明防止此问题,如果Content-Length和Transfer-Encoding标头都存在,则应忽略Content-Length标头。这可能足以避免在只有一台服务器正在运行时出现歧义,但在两台或多台服务器链接在一起时则不行。
在这种情况下,出现问题有两个原因:
1.某些服务器不支持请求中的Transfer-Encoding标头。
2.如果标头以某种方式进行模糊处理,则可能会导致某些支持Transfer-Encoding标头的服务器不处理它。
如果前端服务器和后端服务器与(可能模糊的)Transfer-Encoding标头的行为不同,那么他们可能不同意连续请求之间的边界,从而导致请求夹带漏洞。
如何执行HTTP请求夹带攻击
请求夹带攻击涉及将Content-Length头和Transfer-Encoding头放入单个HTTP请求并对其进行操作,以便前端和后端服务器以不同方式处理请求。完成此操作的确切方式取决于两台服务器的行为:
CL.TE:前端服务器使用Content-Length头,后端服务器使用Transfer-Encoding头。
TE.CL:前端服务器使用Transfer-Encoding标头,后端服务器使用Content-Length标头。
TE.TE:前端和后端服务器都支持Transfer-Encoding标头,但是可以通过以某种方式模糊标头来诱导其中一个服务器不处理它
CL.TE漏洞
这里前端服务器使用Content-Length头,后端服务器使用Transfer-Encoding头。我们可以执行简单的HTTP请求夹带攻击,如下所示:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 13
Transfer-Encoding: chunked
0
SMUGGLED
前端服务器处理Content-Length头并确定请求主体长度为13个字节,直到SMUGGLED结束。此请求将转发到后端服务器。
后端服务器处理Transfer-Encoding标头,因此将消息体视为使用分块编码。
它处理第一个块,它被称为零长度,因此被视为终止请求。以下字节SMUGGLED未经处理,后端服务器将这些字节视为序列中下一个请求的开始。
TE.CL漏洞
这里,前端服务器使用Transfer-Encoding标头,后端服务器使用Content-Length标头。我们可以执行简单的HTTP请求夹带攻击,如下所示:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 3
Transfer-Encoding: chunked
8
SMUGGLED
0
注意:
要使用Burp Repeater发送此请求,您首先需要转到Repeater菜单,并确保未选中“Update Content-Length”选项。
您需要在最后的0之后包含尾随序列\r\n\r\n
前端服务器处理Transfer-Encoding标头,因此将消息体视为使用分块编码。它处理第一个块,长度为8个字节,直到SMUGGLED之后的行的开头。它处理第二个块,它被称为零长度,因此被视为终止请求。此请求将转发到后端服务器。
后端服务器处理Content-Length标头并确定请求主体长度为3个字节,直到8之后的行的开头。以SMUGGLED开头的以下字节未经处理,后端服务器将这些视为序列中下一个请求的开头。
TE.TE行为:混淆TE头、
这里,前端和后端服务器都支持Transfer-Encoding标头,但是可以通过以某种方式模糊标头来诱导其中一个服务器不处理它。
有可能无休止地混淆Transfer-Encoding标头。例如:
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
这些技术中的每一种都涉及到与HTTP规范的细微偏离。实现协议规范的实际代码很少以绝对精度遵守它,并且不同的实现通常容忍规范的不同变化。要发现TE.TE漏洞,有必要找到Transfer-Encoding标头的一些变体,以便只有一个前端或后端服务器处理它,而另一个服务器忽略它。
根据是否可以诱导不处理混淆的Transfer-Encoding标头的前端服务器或后端服务器,攻击的其余部分将采用与CL.TE或TE.CL漏洞相同的形式已经描述过。
如何防止HTTP请求夹带漏洞
在前端服务器通过同一网络连接将多个请求转发到后端服务器的情况下会出现HTTP请求走私漏洞,并且用于后端连接的协议存在两个服务器不同意关于两者之间边界的风险要求。防止HTTP请求走私漏洞的一些通用方法如下:
禁用后端连接的重用,以便通过单独的网络连接发送每个后端请求。
使用HTTP / 2进行后端连接,因为此协议可防止请求之间的边界模糊不清。
为前端和后端服务器使用完全相同的Web服务器软件,以便他们就请求之间的界限达成一致。
在某些情况下,可以通过使前端服务器规范化模糊请求或使后端服务器拒绝模糊请求并关闭网络连接来避免漏洞。然而,这些方法可能比上面确定的通用缓解更容易出错。
web-security 练习
要解决实验问题,请将请求走私到后端服务器,以便后端服务器处理的下一个请求似乎使用GPOST方法。
https://portswigger.net/web-security/request-smuggling/lab-basic-cl-te