搜索
查看: 1433|回复: 0

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

[复制链接]

11

主题

11

帖子

24

积分

新手开车

Rank: 1

积分
24
发表于 2022-6-2 20:06:22 | 显示全部楼层 |阅读模式


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

1. 前提

HTTP1.1


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




  • 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-Length和Transfer-Encoding的作用:


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


例:我这里随便找个包



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

  

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








2. 漏洞原理

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




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









3. 详细分类及利用

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



3.1 CL-TE

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


利用过程:


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



构造如下请求包发送

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

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





详细解析:


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

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





利用:


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


  • 极客用火狐,抓包,改,发包
  • 普通人用星愿去访问这个站,直接拒绝服务



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





3.2 TE-CL

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



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

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

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

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





3.3 TE-TE

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


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


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






4. 如何发现

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




回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表