首页
社区
课程
招聘
谁能比我细---秒懂Http请求走私
发表于: 2022-6-3 12:07 3055

谁能比我细---秒懂Http请求走私

2022-6-3 12:07
3055

HTTP1.1

首先我们需要了解下http1.1的特性,它是应用层的协议,这个不用多说

image-20220531194955358

keepalive

​ 在http1.1时代,每个http请求都需要打开一个tcp连接,keep-alive可以改善这种状态,提高利用率,即一个长连接,在一次TCP连接后不断开连接。 HTTP1.0的时候没有长连接这个概念,后来引入了长连接并通过Connection: keep-alive实现。

​ 但HTTP1.1的规则中,所有HTTP报文都必须是持久的,除非特意加上Connection: close,但实际中很多服务器和浏览器还保留着Connection: keep-alive

pipline

在1个Tcp连接中发送多个请求

Content-Length

HTTP包的一个标头,用来指明发送给接收方的消息的大小

Transfer-Encoding

传输编码

接下来我将用一个演示更加清晰的展示Content-LengthTransfer-Encoding的作用:

假设我们一个TCP连接上,存在多个HTTP报文,我怎么知道哪些内容属于第一个报文,哪些是第二个的呢?这个时候Content-Length的作用就来了,Content-Length来告诉对方包的请求体的数据长度。

例:我这里随便找个包

image-20220531210047366

但是实际情况中,Content-Length获得起来会存在一些问题,例如一些文件,需要计算其长度就大大增加了内存的消耗,而且当Content-Length的数值多或者少的时候都会发生问题。

image-20220531213853151

这个时候Transfer-Encoding的优势就来了,它的值为chunked时,表示使用分块编码,一个块包含十六进制的长度值和数据,用0长度块表示结束块,如下图所示。

image-20220531213354154

发生前提: 一般在前后端服务器分离或存在CDN加速服务的情况下

一般是后端和前端对于请求的结束认证不一致导致的,相当于后端对于第一个包产生了截断,前者正常处理,后者就会和第二个包进行拼接,这样就对第二个包造成了影响,详细看下下面这两张图。

image-20220601150127519

我这里通过Burpsuite的官方实验室进行演示

image-20220601155058206

前端服务器只处理Content-Length请求头,后端处理Transfer-Encoding请求头(把CL-TE方式看透,后边的都差不多我就简写了)

利用过程:

访问主页,抓包,改成POST请求

image-20220601155235565

构造如下请求包发送

image-20220601160041405

发送第一次,返回结果正常

image-20220601160100045

发送第二次,发现我们最开始构造的构造的请求,在0后边被截断,后边的G和第二个包结合解析,返回错误

<img src="https://mc-imgup.oss-cn-beijing.aliyuncs.com/img/20220601160119.png" alt="image-20220601160118971" style="zoom: 80%;" />

详细解析:

前端服务器根据Content-Length字段处理,所以从0到G结束(/r/n算一个)总和是6,所以前端没什么问题,而后端因为根据TE头来处理,第一次请求的时候它看到了为0的结束块,所以认为第一个包到0结束,而后剩下可以想象还在TCP链上,然后第二个包过来了,它们就合并到了一块

image-20220601161101200

所以第二个包,实际上在后端处理的时候是下图这个样子

image-20220601161317913

利用:

看懂了,怎么利用呢?如果有这个疑问,那证明你还是对该漏洞的原理没理解透彻,如之前的原理图那样,TCP传递的这些包不是来自一个人的,比如我这里用火狐当做黑客视角,用星愿浏览器当做普通用户视角

黑客用火狐,抓包,改,发包

普通人用星愿去访问这个站,直接拒绝服务

image-20220601161910329

其次,既然我们可以将任何东西留在后者的包内,那么我们就可以构造xss,sql注入,或者利用会话固定等等来打组合拳,也可以绕过前端认证。相反的我们也可以发包不带0结束块,这样后端认为第一个包还没完,紧接着用户的包来了,那么就将后者的包结合到我们自己发的包中,好了不多哔哔,更多利用方式自己探索吧。

前端服务器只处理Transfer-Encoding请求头,后端处理Content-Length请求头。

同样的我们尝试构造GPOST请求,你能想那这简单,反过来就可以了吗,你可能会想按如下方式构造请求包,CL为2,后端会截断,将G以及后边的数据和第二个请求拼接

image-20220601175036460

但是实际上如下图,将0也算了进去,因为既然后端是根据CL来处理请求的,它不是分块传输,自然就不认识0截断块,所以统统当字符串处理

image-20220601175153336

前端是通过TE来处理的,这个0还不能扔,那么这种情况就需要我们自己把GPOST写出来,如下图

image-20220601182553796

因为这里我们将CL的长度改成了4,所以5,c,/n,/r,那么后边的GPOST开头的数据就合并到了后边的数据包中,就将后边数据包的请求方式给覆盖了,还有注意数据块的长度要计算正确,如第一块是从G开始到9结束。

这种情况就是前后端都是用TE来处理请求,但是我们可以通过混淆TE头方式让后端不再根据TE处理而是变成了根据CL处理

这里我写了两个TE头,不过第二个头后边的E是小写,而且值,我瞎写了个low,这样后端发现了两个,而且值不同,不知道用哪个了,然后看见包里有CL那干脆就用CL头来处理包

image-20220601194434967

靶场里面有更多了请求走私漏洞,这里就不一一举例了。

我们这里可以使用Burp插件商店里面的HTTP Request Smuggler

image-20220601200031346


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 3
支持
分享
最新回复 (4)
雪    币: 4134
活跃值: (5847)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
2

感谢分享

最后于 2022-6-3 13:00 被badboyl编辑 ,原因:
2022-6-3 12:57
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
我不懂,支持一下。
2022-6-5 10:44
0
雪    币: 1
活跃值: (47)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
确实够细,感谢分享
2022-7-1 18:28
0
雪    币: 5314
活跃值: (4798)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
你真细!!
2022-7-1 21:33
0
游客
登录 | 注册 方可回帖
返回
//