谁能比我细—秒懂Http请求走私
谁能比我细---秒懂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