什么是HTTP请求夹带(smuggling)攻击
HTTP请求走私是一种干扰网站处理从一个或多个用户接收的HTTP请求序列的方式的技术。
请求夹带漏洞危害,允许攻击者绕过安全控制,获取对敏感数据的未授权访问,并直接危及其他应用程序用户。
HTTP请求夹带攻击是怎么发生的?
今天的Web应用程序经常在用户和最终应用程序逻辑之间使用HTTP服务器链。
用户将请求发送到前端服务器(有时称为负载平衡器或反向代理),此服务器将请求转发给一个或多个后端服务器。
在现代基于云的应用程序中,这种类型的体系结构越来越常见,并且在某些情况下是不可避免的。
当前端服务器将HTTP请求转发到后端服务器时,它通常通过相同的后端网络连接发送多个请求,因为这样做效率更高,性能更高。
协议非常简单:HTTP请求一个接一个地发送,接收服务器解析HTTP请求标头以确定一个请求结束的位置和下一个请求的开始:
在这种情况下,前端和后端系统就请求之间的界限达成一致至关重要。否则,攻击者可能会发送一个模糊的请求,前端和后端系统会对其进行不同的解释:
在这里,攻击者将后端服务器的部分前端请求解释为下一个请求的开始。它有效地预先附加到下一个请求,因此可能会干扰应用程序处理请求的方式。这是一次请求夹带攻击,它可能会造成严重的后果。
如何构造 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之后包含尾随序列
前端服务器处理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[ ]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
https://portswigger.net/web-security/request-smuggling/lab-basic-te-cl
https://portswigger.net/web-security/request-smuggling/lab-ofuscating-te-header
参考
https://portswigger.net/web-security/request-smuggling