漏洞概要 关注数(24) 关注此漏洞
缺陷编号:wooyun-2015-0150916
漏洞标题:QQ浏览器9内置帐号助手代码缺陷导致可获取记住的其它网站密码
相关厂商:腾讯
漏洞作者: gainover
提交时间:2015-10-31 20:57
修复时间:2015-12-17 14:48
公开时间:2015-12-17 14:48
漏洞类型:设计错误/逻辑缺陷
危害等级:高
自评Rank:15
漏洞状态:厂商已经确认
漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]
Tags标签: 无
漏洞详情
披露状态:
2015-10-31: 细节已通知厂商并且等待厂商处理中
2015-11-02: 厂商已经确认,细节仅向厂商公开
2015-11-05: 细节向第三方安全合作伙伴开放(绿盟科技、唐朝安全巡航)
2015-12-27: 细节向核心白帽子及相关领域专家公开
2016-01-06: 细节向普通白帽子公开
2016-01-16: 细节向实习白帽子公开
2015-12-17: 细节向公众公开
简要描述:
之前版本8时,已经发过一个可以获取记住的密码的问题,但现在QQ浏览器从8升级到版本9了,内核已换成webkit了,扩展机制也不是自己实现的那一套了。然而QQ浏览器9中,记住密码的功能依然是通过扩展来实现,并且由于扩展的实现代码存在缺陷,依然可以导致跨域获取记住的其他网站密码。
详细说明:
1. 下载QQ浏览器9 最新版本
2. 首先,随便打开一个页面,我们可以看看QQ浏览器里内置了哪些扩展会使用到content script,发现有一个account helper,这不又是帐号助手么,这个内置的帐号助手会不会又存在问题?
从代码里可以看到记住密码的填充流程:
a. 建立一个connect,
b. 向背景页发送一个消息,用于获取需要填充的密码,
c. 背景页根据消息获得数据后,发回给当前页面的content script,
d. 当前页的content script的接受fill指令后,执行setData函数存储获取的密码数据。。最后执行fill()函数进行表单填充。
3. 来看看这个流程里会不会有什么缺陷。。
从步骤2可以看出,获取填充密码的流程位于背景页中,所以我们根据
chrome-extension://dbjbbhdmofcmcjdmfolgmgcihbjbaali/account_helper.js
这个地址可以得到背景页地址:
chrome-extension://dbjbbhdmofcmcjdmfolgmgcihbjbaali/background.html
定位background.html里与获取填充密码相关的代码:
从代码可以看到,get密码的函数调用, get(d, {...}, 回调函数);
d变量为需要获取密码的域名,并且,d = getDomain(a.sender.tab.url)
也就是说,我们所要获取哪个域名下记住的密码,是通过getDomain函数从页面URL里取出来的。
那么,getDomain函数会不会存在问题呢?
4. 为了看看getDomain是如何工作的,我们打开QQ空间的登录页面,并且记住密码,
然后,我们在background.html的getDomain函数里下断点:
继续跟进tld.getDomain函数:
在这个函数里,url会经过 isValid --> cleanHostValue --> extractTldFromHost 进入b变量,b进入f变量,最终函数返回f.
其中isValid比较简单,不管了,
所以,我们跟进 d.cleanHostValue函数:
5. 如上图所示,cleanHostValue函数里,是通过正则i,从url里来进行匹配,最终返回正则匹配结果的第4个group,b[4],因此正则i成了关键,我们看看正则i是啥?
正则的第4个括号是 host,对正则认真分析一下,不难构造出下面的URL:
http://**.**.**.**:8080/?@**.**.**.**
和正则对应一下,如下图所示:
可见,我们的地址虽然是**.**.**.**:8080 下的,但 host 会被认为是**.**.**.**
6. 接下来的extractTldFromHost等函数关系并不大,我们为了验证结果,本地搭建一个8123的服务,然后页面内容就是QQ空间同样的表单。
用QQ浏览器访问:http://**.**.**.**:8123/?@**.**.**.**
可以看到密码会被自动填充。
并且这个密码可以通过脚本被获取:
测试代码见测试代码区域。
具体效果见漏洞证明。
7. 虽然已经可以获取密码了,我们还是继续看下剩下的处理流程:
可以看到被绕过的host为**.**.**.**,最后经过extractTldFromHost函数后, 返回 **.**.**.**
8. 继续:
可以看到,到了get函数时, d 就是 getDomain的返回值 **.**.**.**,
而a.sender.tab.url就是我们页面的url地址:"http://**.**.**.**:8123/?@**.**.**.**/"
get函数的回调内容,就是存储的密码信息,随后就是发送fill指令回content script
9. 差不多就是这样了。。
漏洞证明:
如下图所示:
图片地址:http://**.**.**.**/lc/35JrkTMSnntgxz3Em4N 密码:Q0UE
修复方案:
从URL里获取主机域名,不需要用正则吧? 显然有其它更保险的获取办法。。。
版权声明:转载请注明来源 gainover@乌云
漏洞回应
厂商回应:
危害等级:高
漏洞Rank:10
确认时间:2015-11-02 15:06
厂商回复:
非常感谢您的报告,问题已着手处理,感谢大家对腾讯业务安全的关注。如果您有任何疑问,欢迎反馈,我们会有专人跟进处理。
最新状态:
暂无