2019-05-29 17:30 // 转载
JSON(Java Object Notation) 是一种轻量级的数据交换格式,易于阅读和编写,同时也易于机器解析和生成。
JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯。这些特性使JSON成为理想的数据交换语言。
这种纯文本的数据交互方式由于可以天然的在浏览器中使用,所以随着ajax和web业务的发展得到了广大的发展,但是如果这种交互的方式用来传递敏感的数据,并且传输的时候没有做太多安全性控制的话将导致安全漏洞,根据敏感信息的不同会导致应用遭受不同级别的攻击。
单从字面上就可以理解的出来,JSON劫持(JSON Hijacking )就是对数据进行窃取。恶意攻击者通过某些特定的手段,将本应该返回给用户的JSON数据进行拦截,转而将数据发送回给恶意攻击者,这就是JSON劫持的大概含义。一般来说进行劫持的JSON数据都是包含敏感信息或者有价值的数据。
在实际应用的过程中,JSON数据的传输会用到两种方式:
1.Xmlhttp方式获取
当在前端获取数据的时候,由于数据获取方和数据提供方属于同一个域下面,所以可以使用xmlhttp的方式来获取数据,然后再用xmlhttp获取到的数据传入自己的js逻辑如eval。Xmlhttp方式获取的数据示例如下:
{“username”:“vulnbox”,“password”:“wooyun”}
2.方式获取
如果传输的数据在两个不同的域,由于在java里无法跨域获取数据,所以一般采取标签的方式获取数据,传入一些callback来获取最终的数据,这就有可能造成敏感信息被劫持。方式获取的数据示例如下:
userinfo={“username”:“vulnbox”,“password”:“wooyun”}
总的来说,当网站以JSON形式输出数据,且其中包含用户敏感信息,攻击者通过第三方站点以CSRF手段使用户浏览器请求目标站点得到包含敏感信息的JSON数据,进而劫持到敏感信息。
发动一次成功的JSON劫持攻击必须要有如下先决条件:
1.受攻击的网站URL返回一个JSON对象或者数组,并且返回的数据有重要的价值,也就是敏感的数据
2.受攻击的网站地址支持GET请求的响应
3.受害人的浏览器没有禁用java
4.受害人浏览了钓鱼/恶意网站,并且受害人在受攻击的网站中,保存在COOKIE中的身份验证信息尚未清除
5.受攻击的站点没有做相关的防御措施
1.确定攻击网站
恶意攻击者要确定攻击的网站,一般会挑选有价值的网站(如购票网站、网购网站、论坛等)。由于大部分使用JSON作为数据传输的网站往往会使用到AJAX技术,而AJAX作为前端脚本,存在着透明性和公开性。这样导致的结果是增加了攻击层面和入口,为攻击者添加了更多的选择和便捷。
恶意攻击者常常浏览网站的脚本来寻找漏洞进行攻击,一但确定网站存在JSON劫持漏洞,即某个JSON服务或者接口返回有价值的敏感的JSON数组数据,那么攻击者就会针对这个网站进行JSON劫持攻击。
假设要攻击的站点地址是http://vuln.vulnerable.com/Home/GetJson,其服务器端代码示例如下:
[HttpGet]
[Authorize]
public ActionResult GetJson()
{
var result=new[]{new {Id=1,Name="张三"},new {Id=2,Name="李四"}};
return Json(result, JsonRequ
estBehavior.AllowGet);
}
2.设置恶意钓鱼站点诱骗受害者点击
在第一步明确了要攻击的站点后,恶意攻击者第二步就是要诱骗受害人点击和进入到钓鱼/恶意网站。恶意攻击者常常在网络上通过各种方式诱骗受害人进入到他们精心布置的陷阱中。
a.通过邮件群发,发送大量垃圾/钓鱼邮件等待受害者点击邮件中的链接。
b.通过社交软件和网站发送链接。
c.还有其他的各种方式,比如论坛发帖、各种即时通讯工具等。
3.劫持受害者的数据
受害人点击了恶意链接进入到钓鱼网站中,攻击者利用构造好的脚本,就可以劫持受害人的数据了,其流程如下:
a.向进行攻击的目标网站发送一个GET请求(假设攻击的URL是http://vuln.vulnerable.com/Home/GetJson,这个URL会返回JSON数组数据),只要在网页中放置如下代码,就会自动朝目标发送一个HTTP GET请求:
< src=“http://vuln.vulnerable.com/Home/GetJson”>
b.恶意网站成功发送一个带有身份验证信息的GET请求后,成功的获取到了攻击站点返回的数据,响应的数据需要是JSON数组或者JSON对象。攻击者接下要做的就是将响应到钓鱼网站的数据发送到自己服务器的数据库上,数据劫持就完成了。
尽量避免跨域的数据传输,对于同域的数据传输使用xmlhttp的方式作为数据获取的方式,依赖于java在浏览器域里的安全性保护数据。如果是跨域的数据传输,必须要对敏感的数据获取做权限认证,具体的方式可以包括:
1.referer来源限制,利用前端referer的不可伪造性来保障请求数据的应用来源于可信的地方,此种方式力度较弱完全依赖于referer,某些情况下(如存在xss)可能导致被绕过。
2.加入token。利用json hijacking的方式获取数据是CSRF的一种,不过较之传统的CSRF不能获取数据只能提交而言,这种方式利可以获取一些敏感信息。如果能让攻击者对接口未知,就可以实现json hijacking的防御了。利用token对调用者的身份进行认证,这种方式对于调用者的身份会要求力度较细,但是一旦出现xss也可能导致前端Token的泄露,从而导致保护失效。
3.对于同域的json使用情况下,可以在数据的输出头部加入while(1);的方式避免数据被标签的方式引用,这可以防止一些比较有特性的浏览器里导致的数据泄漏。
1.http://haacked.com/archive/2009/06/25/json-hijacking.aspx
2.http://mp.weixin.qq.com/s/LF1AWqHIHdUVQ8fC4fvw8Q《QQ邮箱是如何泄露的:JSON劫持漏洞攻防原理及原理》
(本文来源:公众号“阳光测试在线”)