大家好久不见呀,小黑上一篇文章说截至3.1日前肯定会恢复更新,没想到2月只有28天,这么快就到了deadline……今天紧急上线给大家写文章。
年也过完(很久)了,该收心学习了。今天给大家分享一下关于【jsonp劫持】漏洞的研究。
jsonp是json的一种使用模式,可以让网页从别的域名获取资料——跨域读取数据。
提到jsonp就必然绕不开跨域请求和同源策略的原理,所以先讲一下:
浏览器的一种安全策略,非同源的网站会有一些限制,主要防止恶意网站窃取信息。
两个网站需同时满足 协议相同 and 域名相同 and 端口相同 才是同源的。
https://www.baidu.com 和 http://www.baidu.com(协议不同)
https://www.baidu.com 和 https://api.baidu.com (域名不同)
https://www.baidu.com 和 https://www.baidu.com:81 (端口不同)
1、请求发起方无法用js读取非同源网页的cookie,localstorege和indexedDB
3、请求发起方向非同源地址发送的ajax请求浏览器会拒绝接受响应(可以发,接受方也能收到并且正确返回结果,但用户的浏览器会拒绝使用或显示接收方返回的结果)
1、你登录了网银没有退出,浏览器里还有银行的cookie。但你不必担心访问到不法分子搭建的钓鱼网站被窃取cookie。(非同源无法获取cookie)
2、你访问了网银还没有登录,这时又访问了钓鱼网站,你不必担心网银的登录框被钓鱼网站的js代码替换成假的。(非同源不能接触dom)
3、你登陆了网银没有退出,这时又访问了钓鱼网站,你不必担心钓鱼网站偷偷用ajax异步请求调用网银网站的api接口偷你的信息。(非同源ajax拒绝接受响应)
用 form 可以发请求,但是会刷新页面或新开页面
用 a 可以发 get 请求,但是也会刷新页面或新开页面
用 img 可以发 get 请求,但是只能以图片的形式展示
用 link 可以发 get 请求,但是只能以 CSS、favicon 的形式展示
用 script 可以发 get 请求,但是只能以脚本的形式运行
我是开发人员,我保证请求方和接受方都是我的网站,不存在安全问题,怎么能让它们突破同源策略,强制发跨域请求?
这种场景其实很常见,比如www.baidu.com向api.baidu.com发请求,在业务上是很合情合理的。但是同源策略偏偏也限制了这种场景,当今有很多办法可以优雅的解决。但以前没有,jsonp是一种比较早提出的相对【临时的】解决方案,这也是jsonp诞生的意义:为开发人员解决跨域请求的问题。
利用外链js脚本<script>标签可以不遵守同源策略的特点发起跨域请求,需要后端配合调用回调函数,用js函数读取请求对应的返回数据。
我是开发人员,A和B两个网站都是我能控制的且它们非同源。现在我想用jsonp让A向B发送跨域请求并且能接收到返回的数据。流程如下:
(1)A网站定义js回调函数,函数定义一个参数用来接受返回的数据。
![JSONP劫持 JSONP劫持]()
(2)A网站通过script标签跨域请求B网站,请求中附带cookie(浏览器自动附带)和callback参数(用于告诉B网站回调函数名称,开发人员手动指定)。
![JSONP劫持 JSONP劫持]()
(3)B网站接受到请求,需要返回callback参数指定的函数调用格式的js代码,函数里面的参数通常是json数据格式(懒得画图了。这里借用轩辕师傅的图,把左边的callback参数的值和右边返回的loadData函数名都换成test123就和上面对应上了)
![JSONP劫持 JSONP劫持]()
(4)虽然B网站的返回数据A网站用script标签无法直接获取,但这堆数据已经被A网站当成外链的js代码执行了,相当于在A网站上添加了下面的代码:
![JSONP劫持 JSONP劫持]()
(5)因为返回数据就是语法正确的js格式,且含义是调用A网站的回调函数,参数是A网站真正需要的数据。所以A网站可以在回调函数里正确的处理返回的数据。
![JSONP劫持 JSONP劫持]()
利用场景:一般用于蜜罐溯源,获取踩了蜜罐的攻击者的身份信息。
举例描述:假设某个知名购物网站,这个网站获取收货地址的接口用了jsonp且未做防御,蜜罐就可以用script标签请求这个接口,并在回调函数里获取该接口返回的数据,即收货地址。攻击者购完物,没有退出这个网站,然后就发起攻击行为,不小心踩了蜜罐。蜜罐就可以获取到攻击者的收货地址,达到溯源的目的。
利用代码(假设api.test.com就是这个购物网站):
<script type="text/javascript">
<script type="text/javascript" src="https://api.test.com?&callback=test123"></script>
(1)alert不能弹json对象,所以上面的代码中a参数用JSON.stringify方法转换成了字符串,才能正常弹框。console.log方法没这个限制。
(2)定义函数和调用的顺序问题:定义回调函数需要在请求接口前面,否则会有函数未定义的问题。
(3)chrome高于某个内核版本在跨域jsonp场景,已经不会自动携带cookie了。需要认证的接口就无法正常工作了。(QQ浏览器用70内核还可以,360安全浏览器用86内核就不行了)
(4)火狐浏览器已有明文提示未来也将移除支持,现在暂时还可以复现。
由此可见jsonp是解决历史遗留问题的一个老旧方案了,现在解决跨域问题有类似cors等更优雅的解决方法,可预见的是,未来jsonp的消失应该是历史必然。
打开F12,在网络请求中找json格式的数据,找callback参数,在前端源码中找src中带参数的script标签。
-严格安全的实现 CSRF 方式调用 JSON 文件:限制 Referer 、部署一次性 Token 等。
-严格安装 JSON 格式标准输出 Content-Type 及编码( Content-Type : application/json; charset=utf-8 )。
-严格过滤 callback 函数名及 JSON 里数据的输出防止产生xss漏洞。
-严格限制对 JSONP 输出 callback 函数名的长度。
-其他一些比较“猥琐”的方法:如在 Callback 输出之前加入其他字符(如:/**/、回车换行)这样不影响 JSON 文件加载,又能一定程度预防其他文件格式的输出。还比如 Gmail 早起使用 AJAX 的方式获取 JSON ,听过在输出 JSON 之前加入 while(1) ;这样的代码来防止 JS 远程调用。
-refer过滤不严谨,在url中通过域名、页面、参数都可以主动构造关键词绕过防御。
-空 Referer:使用 <iframe> 调用 javscript 伪协议来实现空 Referer 调用 JSON 文件。
<iframe src="javascript:'<script>function JSON(o){alert(o.userinfo.userid);}</script><script src=http://www.qq.com/login.php?calback=JSON></script>'"></iframe>
-配合xss漏洞完美破解【限制 Referer+ 部署随机 token 的防御方案】。(Content-Type不严格定义时,一般callback参数这里可能会有xss漏洞)
最近在研究jsonp获取身份信息的方案,研究完才知道这方案用不了多久了,心塞塞。
这篇文章里07章节的配合xss漏洞破解refer+token防御方案的具体方法,小黑还没有研究透彻,也许以后会再写一篇文章分享吧。如果有师傅对此有心得欢迎在留言区指导,万分感谢!
https://zhuanlan.zhihu.com/p/35473030
https://mp.weixin.qq.com/s/DZ0jADaJpEXnue_mbBbiCQ
https://mp.weixin.qq.com/s?__biz=MzIxOTM2MDYwNg==&mid=2247485025&idx=2&sn=ab3e37be46e28923840ae420fee51e58
https://blog.knownsec.com/2015/03/jsonp_security_technic/
喵,点个赞再走吧~
原文始发于微信公众号(小黑的安全笔记):JSONP劫持
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
点赞
https://cn-sec.com/archives/808226.html
复制链接
复制链接
-
左青龙
- 微信扫一扫
-
-
右白虎
- 微信扫一扫
-
评论