HTTP走私攻击
HTTP走私攻击
HTTP请求走私是一种技术,用来干扰网站处理用户的HTTP请求,可以用来绕过waf,进而实现对敏感数据的未授权访问
原理
由于不同服务器对RFC标准实现的方法和标准不同,对同一个HTTP请求,不同服务器采取不同的处理方法,导致了不同的结果
利用方式
CL(Content-Length)不为0时的GET请求
在RFC2616中,并没有对GET请求像POST请求那样携带请求体作出规定。在RFC7231中也仅仅是提醒了一下
假设代理服务器允许GET请求携带请求体,但是后端服务器不允许GET请求携带请求体,那么后端服务器会忽略掉代理服务器传过来的GET请求中的Content-Length头,不进行处理,这样就会导致请求走私
1 | GET / |
前端服务器收到请求后,通过读取CL,判断这是一个完整的请求,转发给后端服务器。然后后端服务器收到后,因其不对CL进行处理,所以认为收到了两个请求
1 | GET / HTTP/1.1 |
和
1 | GET /flag HTTP/1.1 |
因此走私了一个包
CL-CL型
在RFC7230中,规定当服务器收到两个CL但是两者不同时,返回400错误
但是在不执行此规范的服务器来说,前端服务器会按照第一个CL的值对请求进行处理,后端服务器会按照第二个CL的值进行处理
假如现在有两个包
1 | POST / HTTP/1.1 |
对于前端来说第一个包就是
1 | POST / HTTP/1.1 |
对于后端会被处理成
1 | POST / HTTP/1.1 |
CL-TE型
前端服务器只处理Content-Length这一请求头,后端服务器则忽略它只处理Transfer-Encoding请求头
Transfer-Encoding为chunked的时候,会分块传输,chunk包含块头和数据体,二者以及块之间以CLRF符号分割(\r\n)如下
1 | GET / |
假设我们整一个包
1 | POST / |
前端服务器处理CL,确认请求正文的长度为13字节,然后转发该请求到后端服务器,后端服务器处理TE头,因此使用分块传输,处理了第一个块,长度声明为0,那么终止请求,下面的flag字符就走私了,后端服务器认为他们是下一个请求的开始
TE-CL型
前端服务器只处理Transfer-Encoding这一请求头,后端服务器忽略该请求头,只处理CL
1 | POST / |
前端服务器处理Transfer-Encoding
头,因此将消息体视为使用分块编码。它处理第一个块,它被声明为4字节长,直到下面一行的开始走私。它处理第二个块,它声明为零长度,因此被视为终止请求。此请求被转发到后端服务器。
后端服务器处理Content-Length
标头,并确定请求正文的长度为3个字节,直到下一行的开头。以下字节,从flag
,则后端服务器将把它们视为序列中下一个请求的开始,要注意此处读取的是4\r\n,所以是3个字节
TE-TE型
当前端和后端服务器都支持TE头,可以通过某种方式来混淆导致其中一个服务器不处理它
1 | Transfer-Encoding: xchunked |