JSON劫持漏洞攻防原理及演练
注* 作者发表这篇文章的时间较早,某些方法可能并不是最好的解决方案,但针对这种漏洞进行的攻击还依然可见,如早期的:QQMail邮件泄露漏洞,下面介绍的是对这种攻击原理的介绍。
不久之前,我写了一篇文章《一个微妙的JSON漏洞》,文中讲到这个漏洞可能会导致敏感信息泄露。针对该漏洞的特点,通过覆盖JavaScript数组构造函数以窃取(暴露)JSON返回数组,而现在大多数浏览器还无法防范这种攻击。
然而,通过和微软的Scott Hanselman交流,我了解到另外一个方法可能会影响更多的浏览器。在上周的挪威开发者大会上,我做了一个针对Json劫持漏洞的演示。
在我进一步讲之前,我先说一说,这个漏洞可能带来的影响。
在以下条件下,会出现这个漏洞:首先暴露JSON服务,并且该服务会返回敏感数据;返回JSON数组;对GET请求做出响应;发送这个请求的浏览器启用了JavaScript并且支持_defineSetter_方法。
如果我们不使用JSON发送敏感数据,或者只对报文请求做出响应,那么我们的网站就不存在这个漏洞。
我不喜欢用流程图展示这个过程,我会尽量用图表描述。在第一页截图上,我们可以看到不知情的受害者登陆漏洞网站,漏洞网站返回了一个身份认证的cookie。
我们都可能收到过一些垃圾邮件,邮件中附有链接,发送者声称这有一段搞笑视频。这些大量的垃圾邮件都是一些别有用心的人发的。
但是实际上,这些链接指向的是那些坏家伙自己网站。当我们点击了链接,接下来的两个步骤会迅速进行。第一,我们的浏览器向这些网站发送请求。
第二,那些网站会响应一些包含JavaScript的HTML。这些JavaScript会带一个script标记。当浏览器检测到script标记,它就会向那些漏洞网站再发一个下载脚本的GET请求,携带着身份验证的cookie。
这样,那些坏家伙就伪装成了受害者的浏览器,利用其身份发出了一个包含敏感数据的JSON请求。接着,把JSON加载为可执行的JavaScript,这样以来,那些黑客就能够获取到这些数据。
为了加深理解,我们可以看看一个攻击的实际代码。假如漏洞网站返回带有敏感数据的JSON响应通过如下方式发送:
[Authorize]
publicJsonResultAdminBalances(){
varbalances=new[]{
new{Id=1,Balance=3.14},
new{Id=2,Balance=2.72},
new{Id=3,Balance=1.62}
};
returnJson(balances);
}
需要说明的是,上面的演示不是专门针对ASP.NET或者ASP.NET MVC,我仅仅是恰巧用ASP.NET MVC来演示这个漏洞而已。
假如这是HomeController的一种方法,我们通过对/Home/AdminBalances发送了一个GET请求,并且返回如下JSON文本:
[{“Id”:1,”Balance”:3.14},{“Id”:2,”Balance”:2.72},{“Id”:3,”Balance”:1.62}]
注意,我定义这个方法时使用了Authorize属性,用来验证请求者的身份。所以一个匿名的GET请求将不会得到敏感数据。
重要的是:这是一个JSON数组。包含JSON数组的文本是一个有效的JavaScript脚本,并且可以被执行。仅仅包含JSON对象的脚本不是一个有效的JavaScript可执行文件。
举个例子,如果我们有一个包含如下JSON代码的JavaScript文档:
{“Id”:1,”Balance”:3.14}
并且有一个指向这个文档的脚本标签:
<script src=”http://example.com/SomeJson”></script>
这样,我们会在HTML页中得到一个JavaScript错误。然而,倘若存在一个不幸的巧合,如果我们有一个script标签,这个标签指向仅仅含有一个JSON数组的文档,这样的话,这个标签就会被误认为是有效的JavaScript,并且数组会生效。
下面就让我们看看那些别有用心的人的服务器上的HTML页。
注*这里我们可以看到使用 Json Object 而不是Json Array返回你的数据,可以在一定程度上预防这种漏洞。
<html>
...
<body>
<scripttype="text/javascript">
Object.prototype.__defineSetter__('Id',function(obj){alert(obj);});
</script>
<scriptsrc="http://example.com/Home/AdminBalances"></script>
</body>
</html>
看到了什么?黑客正在改变对象的原型,用_defineSetter_这种特殊方法,覆盖JSON对象(Object)原本应有的默认行为。
在这个例子中,一个命名合适的ID在任何时候都可以被设置到任何对象上时,一个匿名的函数将会被调用,这个函数将会利用alert 函数显示属性值。注意,这时脚本仅仅会将数据发回给那些坏家伙,而不会发送敏感数据。
就像之前提到的,坏家伙需要使我们在登录漏洞网站后不久并且在会话仍旧有效时,访问他的恶意的网页。通过含有恶意网站链接的邮件进行钓鱼攻击的方式是很典型的。
如果你仍旧点击链接登录原网站,浏览器将会在加载脚本标签中引用的脚本并向网站发送你的身份验证cookie。直到连接上原网站,我们对JSON数据发出一 个有效的身份验证请求,并且会收到在我们浏览器中响应的有效数据。这些话可能听着很熟悉,因为它是一个真的变种伪造跨站请求,之前我写过这种情况。
因为在IE8上_defineSetter_是一个无效的方法,所以在IE8上看不到现象。我在Chrome和Firefox上都试过,都可以。
避免这个漏洞也很简单:或者从不发送JSON数组,或者只访问HTTP POST以获得需要的数据。举个例子:在ASP.NET MVC中,你可以用AcceptVerbsAttribute来实现:
[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
publicJsonResultAdminBalances(){
varbalances=new[]{
new{Id=1,Balance=3.14},
new{Id=2,Balance=2.72},
new{Id=3,Balance=1.62}
};
returnJson(balances);
}
这个方法的一个问题就是:像jQuery这样的很多JS库默认都是用GET方式发送JSON请求,而不是POST。举个例子,$.getJSON 默认发起的是GET请求。所以,当进行这种JSON访问时,我们需要确信我们是用客户端库发起的POST请求。
ASP.NET和WCF JSON服务端实际上在对象中用了“d”属性,包裹了他们的JSON,这我在另一篇文章中讨论过:
必须经过这些属性获得数据,似乎有些奇怪,但这需要通过一个客户端代理来实现来去除“d”属性,,以便不影响最终用户。
在ASP.NET MVC下,绝大多数开发者没有生成客户端代理,而是使用jQuery和其他类似的库,这样一来使用“d”属性的就有些尴尬。
注*其实MVC的方法有点复杂,到这里我们可以看出,JSON劫持漏洞是要以在受豁者的浏览器上执行JSON返回对象为前提的,其实Google使用了一种更加聪明的方法,通过添加“死循环”命令,防止黑客运行这段脚本,可参见这篇文章:为什么谷歌的JSON响应以while(1);开头?
检查首部(Http-Header)怎么样?
一些人可能会有疑问:“为什么不在响应一个GET请求之前,用一个特殊的首部对JSON服务进行检查?就像X-Requested- With:XMLHttpRequest或者Content-Type:application/json”。我认为这可能是个过渡,因为大多数的客户端 库会发送一种或两种Header,但是浏览器响应脚本标签的GET请求不这样。
问题是:在过去某个时候,用户可能会发出合法的JSON GET请求,在这种情况下,这个漏洞可能会隐藏在用户浏览器的正常请求之间。也是在此种情况下,当浏览器发出GET请求,这种请求可能会缓存在浏览器和代 理服务器的缓冲区。我们可以尝试着设置No-Cache header,这样,我们信任浏览器和所有的代理服务器能够正确地实现高速缓存并且信任用户也不会被意外地覆盖。
当然,如果我们用SSL提供JSON文本,这个特定的缓存问题将会很容易被解决。
注*这里我们可以看到防范方法这三:不要cache你的ajax请求,不过目前似乎所有的js库默认都是不cache的。
真正的问题在哪里?
Mozilla Developer Center发表的一篇文章中写道:对象和数组初始化设定项在赋值时不应该调用setters方法。这一点我同意。尽管有评论认为:也许浏览器真的不应该执行脚本。
但是在一天结束的时候,分派责任并不能使你的网站更加安全。这些浏览器的怪癖毛病将会时不时地出现。我们作为网站的开发者需要解决这些问题。 Chrome2.0.172.31和Firefox3.0.11也有这个软肋。IE8没有这个问题,因为它不支持这种方法,我也没有在IE7或者IE6中 试验过。
在我看来,在当前的客户端库下,安全访问JSON的默认方式应该是POST,并且我们应该选择GET,而不是其他方式。您觉得呢?您所了解的其他平台是怎么解决这个问题的呢?我很想听听大家的想法。
原文 haacked.com
JSON劫持漏洞攻防原理及演练的更多相关文章
- 老树开新花:DLL劫持漏洞新玩法
本文原创作者:丝绸之路 <img src="http://image.3001.net/images/20150921/14428044502635.jpg!small" t ...
- JSONP 安全攻防技术(JSON劫持、 XSS漏洞)
关于 JSONP JSONP 全称是 JSON with Padding ,是基于 JSON 格式的为解决跨域请求资源而产生的解决方案.他实现的基本原理是利用了 HTML 里 <script&g ...
- 点击劫持漏洞之理解 python打造一个挖掘点击劫持漏洞的脚本
前言: 放假了,上个星期刚刚学习完点击劫持漏洞.没来的及写笔记,今天放学总结了一下 并写了一个检测点击劫持的脚本.点击劫持脚本说一下哈.= =原本是打算把网站源码 中的js也爬出来将一些防御的代码匹配 ...
- 认识二进制安全与漏洞攻防技术 (Windows平台)
二进制漏洞是指程序存在安全缺陷,导致攻击者恶意构造的数据(如Shellcode)进入程序相关处理代码时,改变程序原定的执行流程,从而实现破坏或获取超出原有的权限. 0Day漏洞 在计算机领域中,0da ...
- Atitit. Xss 漏洞的原理and应用xss木马
Atitit. Xss 漏洞的原理and应用xss木马 1. XSS漏洞1 2. XSS的用途2 2.1. 盗取cookie2 2.2. 刷新流量 刷分3 2.3. DOS 窃取隐私”.“假冒身份”. ...
- 20155306 白皎 0day漏洞——漏洞利用原理之GS
20155306 白皎 0day漏洞--漏洞利用原理之GS 一.GS安全编译选项的保护原理 1.1 GS的提出 在第二篇博客(栈溢出利用)中,我们可以通过覆盖函数的返回地址来进行攻击,面对这个重灾区, ...
- JSONP 劫持漏洞实例
0x01 Jsonp简介 Jsonp(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据. 为什么我们从 ...
- Dll劫持漏洞详解
一.dll的定义 DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型.在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分 ...
- DLL劫持漏洞
写文章的契机还是看沙雕群友挖了十多个DLL劫持的漏洞交CNVD上去了... 就想起来搜集整理一下这部分 0x01 前言 DLL(Dynamic Link Library)文件为动态链接库文件,又称&q ...
随机推荐
- 实验 Unity Linear Color Space 发现结果不符合预期
美术前上个礼拜找我问光照图总是烘焙过暗的问题,一时兴起我在 Gamma 和 Linear 两个颜色空间切换了下,发现一个 Shader 明暗不同,另一个 毫无变化,于是激发了我去研究下在 Unity ...
- http请求,HttpClient,调用短信接口
项目中安全设置找回密码的功能,需要通过发送短信验证绑定手机,通过绑定的手机号验证并重新设置密码. 因为项目是通过maven管理的,所以需要在pom.xml文件中引入jar包, maven引入的jar包 ...
- 【拓扑排序或差分约束】Guess UVALive - 4255
题目链接:https://cn.vjudge.net/contest/209473#problem/B 题目大意:对于n个数字,给出sum[j]-sum[i](sum表示前缀和)的符号(正负零),求一 ...
- openstack vm实例pxe无法启动
问题如下: 创建vm没有任何报错,打开控制台提示: SeaBIOS (versio xxxxxxx) Machine UUID xxxxxxxxxx iPXE (http://ipxe.org) 00 ...
- [BZOJ3142][HNOI2013]数列(组合数学)
3142: [Hnoi2013]数列 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1721 Solved: 854[Submit][Status][ ...
- Codeforces 1051E Vasya and Big Integers&1051F The Shortest Statement
1051E. Vasya and Big Integers 题意 给出三个大整数\(a,l,r\),定义\(a\)的一种合法的拆分为把\(a\)表示成若干个字符串首位相连,且每个字符串的大小在\(l, ...
- 什么是ClassLoader
ClassLoader 做什么的? 顾名思义,它是用来加载 Class 的.它负责将 Class 的字节码形式转换成内存形式的 Class 对象.字节码可以来自于磁盘文件 *.class,也可以是 j ...
- CDOJ 1307 ABCDE 前缀和优化dp
ABCDE 题目连接: http://acm.uestc.edu.cn/#/problem/show/1307 Description Binary-coded decimal (BCD) is a ...
- hihocoder1322 树结构判定(161周)
hihocoder1322 : 树结构判定(161周) 题目链接 思路: 无向图中判断是不是一棵树. 并查集判断.判断是不是只有一个连通分量.并且该联通分量中没有环.没有环的判定很简单就是看边的数目和 ...
- CXF生成调用webservice的客户端
首先当前是从官网下载cxf组件. http://cxf.apache.org/download.html 下载后解压,在这里主要是用到解压后的bin目录中的wsdl2java.bat该批处理文件. 可 ...