HTTP走私学习
前言
起因也是因为RoarCTF的那道http走私的题没有做出来,从而才接触到了http请求走私这个概念,因此这个时候来补补
<!--more-->
原理
其实HTTP请求走私的最基本原理便是策略的不一致,而这里是指前端后端解析HTTP请求包的策略不一致.
几个概念
有关传输信息
HTTP是运行在TCP连接上的协议,因此TCP的慢启动和三次握手四次挥手的特点,HTTP都具有,而为了提高HTTP的性能,引入了长连接的概念,其目的在于解决HTTP传输的时候,多次建立连接传输信息的情况,这个在HTTP请求包的体现为:Connection: keep-alive
,从而告诉服务器在我传输完信息之前,都不要断开TCP连接,那么问题也随之而来,我们该如何界定信息是否传输完成呢?
有关如何界定
为了解决判断长连接是否需要关闭,这边又引入了一个新的请求头Content-length
,这个时候只需要我的传输信息的长度和Content-length
长度相等,服务器便知道这时候就可以断开TCP连接了,当然理论是没问题的,我们需要考虑更为周全,因为如果Content-length
与信息长度不符时,我们仍然需要保证连接不会断开.因此在__信息长度<__Content-length
长度时,会为缺少的内容进行自动的填充(pending),而__信息长度>__Content-length
时,则会将超过的内容直接截断,这样解决看似完美了,但服务器为了计算信息内容,而将所有内容缓存下来,这并没有解决WEB应用的进一步优化.
分块编码
又为了解决Content-length
无法优化WEB性能的问题,引入了一个新的请求头Transfer-Encoding: chunked
也就是分块编码,加入了这个请求头后,报文就会使用分块的形式进行传输,这样不需要缓存所有的实体内容,只需要缓存分块即可,分块的要求是,每个分块必须包含16进制的长度值和数据,长度值独占一行,长度值不包括CRLF(\r\n
),也不包括其结尾的CRLF,当分块的长度值为0,且没有数据时,此次连接结束
漏洞的发生
HTTP1.1是支持在一个请求包中包含多个请求的,服务器自行根据表头GET
或POST
以及标尾,自行计算出每个请求的范围从而进行解析,但像下面这种环境,如果前端服务器和后端服务器处理请求的标准不同,比如前端服务器以Content-length
作为请求结束的标准,而后端服务器则以Transfer-Encoding
的最后一个请求块长度为0作为请求结束的标志,从而使得前端WAF或者后端WAF失效,达成HTTP走私攻击的目的.
所以HTTP走私总共有四种情况:
- CT-TE: 前端使用
Content-length
,后端使用Transfer-Encoding
- TE-CT: 前端使用
Transfer-Encoding
,后端使用Content-length
- TE-TE: 前后端均使用
Transfer-Encoding
,由于Transfer-Encoding
请求头的值可以混淆,具体使用的是chunk
还是其他,可能不一样 - CT-CT: 前后端均使用
Content-length
,由于能存在多个Content-length
,具体判断哪一个可能不一样
实例
Burpsuite lap
这个很明显的提示我们需要用CL-TE绕过前端限制,测试了一下发现有个敏感目录/admin
我们无法进入
根据提示我们尝试使用CL-TE进行绕过。
表头信息为:
POST / HTTP/1.1
........
Content-length: 47
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: localhost
a: b
这里需要传两次,原因大概做了个流程图:
接着结果就是:
最后删除:
未完待续....
参考文章: