HTTP Request Smuggling之初探

前言

ISCC2022[让我康康]这道赛题在初次接触时令我记忆犹新,之前由于学习知识其他也一直没有对HTTP请求走私进行相关学习,最近学习过后简单总结如下,希望能对正在学习HTTP请求走私的师傅有所帮助。

前置知识

Content-Length

Content-Length指的是HTTP消息长度, 它使用十进制的数字表示了消息的长度, 服务器通过它来得知后续要读取消息的长度。Content-Length首部指出报文中实体主体的字节大小. 这个大小是包含了所有内容编码的,比如,对文本文件进行了gzip压缩,那它的大小就是压缩后的大小而非之前的。

Keep-alive

这个的话就是在HTTP请求中增加一个特殊的请求头Connection: Keep-Alive,其作用是告诉服务器接受完信息后,不要关闭TCP连接,后续对相同目标服务器的请求,一律采用这个TCP连接。

pipline

其含义是新建一个TCP链接,有这个之后,客户端无需等待服务端的响应,就可以发送多次请求,单说可能不太好理解,可以结合下面这个图来进行理解

Transfer-Encoding

它的含义是传输编码。
在最新的 HTTP 规范里,只定义了一种传输编码:
分块编码(chunked)
当使用分块编码的时候,报文中的实体需要改为用一系列分块来传输。每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的CRLF(rn),也不包括分块数据结尾的CRLF。最后一个分块长度值必须为0,对应的分块数据没有内容,表示实体结束。

HTTP Request Smuggling之初探

HTTP请求走私

下方示例的靶场均来自于portswig靶场,链接如下
https://portswigger.net/web-security/all-labs

漏洞成因

一些网站为了优化用户体验,提高访问速度,采用了CDN加速服务,而最简单的加速方式是在原站点加上一个具有缓存功能的反向代理服务器,这个时候用户可以直接从代理服务器处取得资源,图示如下(图片来源于https://paper.seebug.org/1048)

HTTP Request Smuggling之初探


这个时候如果客户端传入一个恶意的请求数据,前端服务器(代理服务器)可能认为没问题,就传给了后端,而后端服务器(原站)在理解时,只认为一部分是正常请求,而另一部分请求就是走私的请求,他会对第二个请求造成影响,此时也就造成了HTTP走私攻击。

漏洞危害

HTTP请求走私的危害有以下几个方面


漏洞利用

CL!=0

现有条件如下

代理服务器允许GET请求携带请求体,而原站不允许GET请求携带请求体

此时如果我们传入携带请求体的GET请求,就会出现一种情况,就是此时它会直接忽略掉GET请求中的Content-Length头,不进行处理。这就有可能导致请求走私。

我们构造请求如下


此时代理服务器收到请求,认为这个是正常的,传给后端服务器,而后端服务器不对这个Content-Length进行处理,此时因为存在pipline,他就会认为是两个单独的请求。
第一个


第二个


此时就出现了请求走私。

CL-CL

按照RFC7230中的规定,当服务器遇见一个请求中包含两个Content-Length时,应该返回400错误,但一些服务器可能不会严格执行该规范,此时就可能出现请求走私。

假设现有场景如下

前端代理服务器和后端服务器在收到一个包含两个Content-Length的请求时,皆不返回400,且此时前端代理服务器采用的是第一个Content-Length,后端服务器采用的是第二个Content-Length

此时我们构造请求如下


前端代理服务器:接收的是Content-Length: 8rn,他检查的时候,看的是六七行(第五行是POST传数据需要空一行,不计算其长度),12345+n+a=8,此时正好八个字符,所以他认为这个请求没有问题,传向后端服务器。

后端服务器:接收的是Content-Length: 7rn,他检查的时候,看的同样也是五六七行,此时因为出现了8个字符,而他只接收7个,所以a还停留在缓冲区,后端服务器会认为他是下一个请求的一部分。

若此时有一个请求


基于前端服务器和后端服务器是重用TCP连接的,此时a就会和请求相结合,组成一个新的请求


此时客户就会收到aGET request method not found的错误回显,这就实现了一次请求走私攻击,并对正常客户造成了影响。

CL-TE

所指情况如下

前端采用的是Content-Length
后端采用的是
Transfer-Encoding

现有请求如下


前端服务器:接收的是Content-Length: 6rn,看代码的7-9行,0+n+n+a=6,此时前端认为没有问题,就会传向后端服务器(第六行是POST传数据需要空出一行,所以不计算其长度)

后端服务器:接收的是Transfer-Encoding: chunkedrn,他在处理第七行(结束标志)时,值是0,他会认为是接收内容结束,此时其后的a还停留在缓冲区。

若此时有一请求


CL-CL相似,此时a会与这一请求相结合变成一个新的请求


此时客户端就会收到Unrecognized method aPOST的错误回显信息,这个时候就造成了请求走私攻击。

靶场演示

靶场链接https://portswigger.net/web-security/request-smuggling/lab-basic-cl-te
打开环境后抓包

HTTP Request Smuggling之初探


接下来右键修改请求方法为POST

HTTP Request Smuggling之初探


然后添加我们添加恶意代码


HTTP Request Smuggling之初探


此时第一次发包,回显正常,这是因为它是正常CL阶段,读取6个字符,
0+n+n+a=6,所以回显正常,接下来再发一次包

HTTP Request Smuggling之初探


此时由于
TE读取到0就终止了,未读取GG还在缓冲区,又来了一个请求,G就与这个请求相组合,变成了GPOST请求方式,此时就会报错,HTTP请求走私成功。

HTTP Request Smuggling之初探

TE-CL

所指情况如下

前端代理服务器采用的是Transfer-Encoding
后端服务器采用的是
Content-Length

现有请求如下


前端服务器:接收的是Transfer-Encoding: chunkedrn,当读取到第九行(第五块)时,读取到0前端服务器认为接收内容结束,没有什么问题,然后传给后端服务器

后端服务器:接收的是Content-Length: 4rn,此时因为接收长度限定为4,12+n=4,所以它在读取完五六行后就不再读取。

此时后面还有一些代码,即


此时再来一个请求,他就会报错,客户端收到Unrecognized method aPOST类似的错误回显信息,请求走私攻击成功。

靶场演示

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

开启环境后抓包,抓包后修改请求方式

HTTP Request Smuggling之初探


接下来添加我们的恶意代码


HTTP Request Smuggling之初探


第一次发包后回显正常,这个是因为
TE在读取到0后休止,认为之前的数据也没什么问题,此时就会传入给后端服务器,后端服务器接收4个长度,这里的话也就是12+n=4,后面的因为存在pipline,所以会被认为是另一个独立的请求

HTTP Request Smuggling之初探


此时再来一个新的请求,就会报错,请求走私攻击成功

HTTP Request Smuggling之初探

TE-TE

所指情况如下

前端代理服务器和后端服务器所采用的都是Transfer-Encoding,但是在容错性上表现不同,例如当我们添加一个Transfer-encoding时,引起混淆,此时可能其中一个服务器会不采用Transfer-Encoding,此时就会导致请求走私

现有请求如下


前端代理服务器:接收的是Transfer-Encoding: chunkedrn,此时读取到最后0处,认为请求没有问题,将请求传输个后端服务器

后端服务器:此时因为存在Transfer-encodingTransfer-Encoding,对服务器起到了混淆作用,服务器不知道该接收哪个,此时可能会接收Content-length: 4rn,然后检测第七行,5c+n=4,认为结果没问题,然后不再读取(第六行不算长度,因为第六行是POST传数据需要空一行)

此时还剩下几行代码

aPOST / HTTP/1.1rn

来源:区块软件开发

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年10月5日
下一篇 2022年10月5日

相关推荐