当jsonp劫持遇到POST三两事
Posted iDersec
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当jsonp劫持遇到POST三两事相关的知识,希望对你有一定的参考价值。
About JSONP
JSONP全称是JSON with Padding,是基于JSON格式的为解决跨域请求资源而产生的解决方案。它的基本原理是利用html的元素标签,远程调用JSON文件来实现数据传递。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外。利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。
参考资料:
https://en.wikipedia.org/wiki/JSONP
http://justcoding.iteye.com/blog/1366102/
About JSONP劫持
但是jsonp虽然可在其它的域下来请求数据。但是也不能设置成任意域下均可访问,否则就可能造成传递的数据被劫持。JSON劫持又称“JSON Hijacking”,这个问题属于CSRF(Cross-site request forgery跨站请求伪造)攻击范畴,当某网站通过JSONP的方式跨域(一般为子域)传递用户认证后的敏感信息时,攻击者可以构造恶意的JSONP调用页面,诱导被攻击者访问,以达到截取用户敏感信息的目的。一个例子:
<script ></script>
<script>
function hacker(data){
alert(data["username"]);
}
$.ajax({
'url': 'http://10.0.0.11/jsonp/jsonp.php',
'type':'GET',
'dataType':'JSONP',
data:'callback=hacker',
'success':function(hacker){},
});
</script>
其实可简写,但是为了调试后期POST,所以用的ajax请求。简写为:
script type="text/javascript">
function callback(result) {
alert(result.username);
}
</script>
<script type="text/javascript" ></script>
构造代码,当登录了网站的浏览器访问这个页面后,就可任意劫持到信息:
服务器端代码:
<?php
if(isset($_GET['callback']))
{
header("Content-type: application/json");
echo $_GET['callback']."({\"username\":\"admin\"})";exit;
}
?>
参考资料:
http://blog.knownsec.com/2015/03/jsonp_security_technic/
https://dev.socrata.com/docs/cors-and-jsonp.html
当jsonp 遇到POST
服务端代码改为:
<?php
if(isset($_POST['callback']))
{
header("Content-type: application/json");
echo $_POST['callback']."({\"username\":\"admin\"})";exit;
}
?>
把上文Poc中的type改为POST发现也没返回数据,抓包查看请求:
发现还是以GET方式发送了请求,$.ajax
对jsonp进行了封装看起来像是ajax请求。由于jsonp是针对get请求的跨域解决,即使type设置了post,在jsonp的时候,也会自动转换成get,只有去手动设置crossDomain为true,或者实际上是跨域,才能修改type。
假设把Poc中的'dataType':'JSONP',删去,抓包发现,POST请求就发出去了在响应里也能看到返回的数据,但是的但是,被浏览器的同源策略拦截了:
分析发现:
jsonp在设计时候本来就是这样设计的,只能通过GET获取数据,不能通过POST获取,浏览器同源策略写到:浏览器有一种同源策略(Same origin policy),同源是指域名、协议、端口相同,当浏览器执行一个脚本(例如 JavaScript)的时候会检查这个脚本是否同源,否则不会执行该脚本,因为浏览器认为来自同站点的资源是安全的。在浏览器中,<script>、<img>、<iframe>、<link> 等标签都可以加载跨域资源,而不受同源限制,但浏览器限制了JavaScript 的权限使其不能读、写加载的内容。而<script>、<img>、<iframe>、<link> 这些标签的加载本来就是GET方式的请求,不会存在POST的存在,所以在设计时候就限制了,只能GET请求。
参考资料:
https://en.wikipedia.org/wiki/JSONP
http://www.jb51.net/article/46463.htm
当POST遇到json
当时遇到的问题比这个还复杂点,是POST请求,而且请求为发送的是json,构造HTML表单默认content-type为application/x-www-form-urlencoded,后台默认的接受到的是一个字符串string。想到一个办法,自定义headers可修改content-type,代码为:
<script ></script>
<script>
datas = '{"username":0,"uid":1}';
function hacker(data){
alert(data["username"]);
}
$.ajax({
'url': 'http://10.0.0.11/jsonp/jsonp.php',
'type':'POST',
data:datas,
headers:{
'Accept':'application/json',
'Content-Type': 'application/json',
},
'success':function(hacker){},
});
</script>
首先去除了第13行。请求:
抓包发现正常请求了,但是Content-Type为application/x-www-form-urlencoded。加上13行后请求,抓包却发现:
请求变成了option,原来同源策略还做了一个限制,在json通过POST方式传递时候会做一个判断:是否满足同源策略要求,如果不满足,就会去服务器做一个请求,是否满允许足跨域资源共享(CORS),加上当前的域和请求方式,发送一个OPTION请求做判断。若满足则继续发送,若不满足则不会发送,用这样的策略来保证数据安全性。所以就会造成请求不成功!
参考资料:
http://www.ruanyifeng.com/blog/2016/04/cors.html
https://www.w3.org/TR/cors/
写在最后
写这篇文章并没有多少技术创新性,知识点许多大牛可能都很熟悉了,但是我之前对jsonp劫持的漏洞原理和造成原因及利用防护等不是特别的清楚,特别是同源策略对安全来说是相当重要的一部分,但是一直没时间细心去研究,说来叶巧最近遇到的几个问题都是最后卡在了同源策略上了,目前对我来说还是绕不过,(如果绕过去了就是一个CVE了,期待有一天突发奇想就绕过去了吧,大家有啥绕过经验也可以给我分享分享),研究了做个笔记,防止以后忘记!
By:iDer
以上是关于当jsonp劫持遇到POST三两事的主要内容,如果未能解决你的问题,请参考以下文章