Expand Chrome Exploit : From client to server
前言
过去的近一年的时间(本文在21年开的头,期间一直是hidden状态),我接触了万恶的浏览器安全,不过只是一个脚本小子的水平 :(
最开始是由于一些工作上的因素,关注了一些主流的IM客户端,难易程度不等,当然也看了不少前辈的精彩工作,比如二哥的各种奇妙的xss、伪协议打🐧啥的。无奈功夫不到家只能另辟蹊径,再加上大学时候@wuyan学长某次回学校给我们做小组分享的时候展示了当时印象笔记的一个xss的时候提了一句,很多客户端你可以把它当成一个浏览器来看;至此这才有了后来的探究和一点点成果吧,时至今日,相关漏洞早已修复,攻击手法也早已“众所周知”,所以写个记录也没有什么:D
客户端
主要是一些Electron和CEF客户端
一些背景 & 调研工作
主流客户端的情况,以前 & 现在
关注客户端安全的同学应该会发现Electron&CEF的应用越来越广泛了,从早些的时候某音乐播放器的xss2rce到后面被关注到内置浏览器本身,当然大佬可能更早的时候就这么玩了 :D
其实是用浏览器框架来开发客户端是一直以来就有的东西,比如下面这张图(可能不完全):
也有直接从chromium做定制开发的,即原生的方式开发,比如某先进IM
这么做的好处是显而易见的:
使用成熟的嵌入式浏览器框架(cef, electron等)能够快速开发应用
能够规避很多复杂的底层设计(c/c++)
前端–>APP跨平台的特性,且很灵活,
更加方便支持自定义协议/扩展/JS对象等
…
与此同时,浏览器的攻击面就自然而然地引入进来了,再结合客户端本身,1+1>2的即视感。本文重点关注浏览器相关的内容,那按照浏览器的思路去考虑就是:
1 | 攻击者构造恶意页面-->客户端访问-->RCE |
这条攻击链路上的前置条件是**客户端可以打开任意URL(直接or间接)**,随后就是常规的浏览器Exploit,分成Render RCE+SBX两部分。
妙就妙在很多客户端出于一些特殊的需求他没有开沙箱。
这里有一份统计 : https://github.com/sickcodes/no-sandbox,当然也不一定对(比如微信是CEF吧),有些客户端也发生了一些变化,不过可以通过历史记录看出来变化趋势,大家都在慢慢地开启沙箱,尝试逐渐收敛风险。
--no-sandbox
的风险是显而易见的,另一个问题是patch gap
,chromium那个更新频率没有几个客户端能跟上,甚至说基本跟不上,再加上功能优先,版本升级或者补丁合入并没有那么高的优先级(也有可能是风险没体现出来,不受重视),所以大部分基于chromium的客户端多多少少都滞后一些大版本,这就造成了大量潜在的Nday影响这些客户端,甚至从RCE到SBX一条龙。
攻击思路
是否直接打开URL
- 直接打开,发链接点了就内置浏览器打开,这类早期IM会这样干,可能是为了“用户体验没有割裂感”
- 特殊的消息才会内置浏览器打开,比如卡片?
- 是否有url白名单,不能绕过的话可能需要多一个白名单域名下的xss做桥梁
- 特殊的scheme有url参数,参考Android客户端的那种情况
- 其他的奇奇怪怪的入口,比如监听端口,处理函数有个啥
openBrowser
的东西
Chromium版本确定
- UA,这个不一定准吧,毕竟启动参数是可以改的,代码里也可以改,一般情况下是可信的
- JS引擎特性,这个我在之前一个文章里提到过ByteCTF2021 chatroom writeup,用于探测后端puppeteer的版本
以上两种方式结合是最好的,能判断出来很精准的版本
选个好"day"
Pj0/github/twitter/v8 commits
@BugsChromium
版本-代码commit之前互查询可以参考: https://omahaproxy.appspot.com/
case1
xxminibrowser
(xx是啥我也不知道)这个洞应该在21年上半年就修复了,而且陆陆续续补掉了不少攻击的前置条件
- Open URL
最早可以随便打开,后面就变成了特殊的消息,再后来越来越窄吧
- 版本确定
用上面的方法确定了具体的版本,还是很准确的
选个好day
当然了,在那个时候这个客户端他的好兄弟“小而美”也是差不多的情况,好好选day能都打了,21年hvv爆出的RCE就是这个情况(藏洞没有好下场 - -!)
当时用的是crbug659475,挺好用的,感谢keen lab的大哥 :D 为了提高成功率甚至还做了这样的事情:
1 | var worker; |
2022.8 update
“小而美”好像在hvv期间开了 --jit-less
后面又下掉了 ,现在的cmdline,与此同时也升级到了M81
case2
S***e
- Open URL
这个点说来还有点故事,20年的时候发现了,直到21年吧有一个老外也发现了并且发在了推特上
说来也简单,就是个看起来是A打开确实B的问题,主要服务端也不做校验就转发是有点离谱的; 对于打开的URL也是有白名单检查的,所以特定域下的xss是攻击的桥梁 :(
- 版本
M78 这个没什么好说的
- 选个day
m78可选的很多(比如CVE-2020-6418),注意目标的是x86,需要做一些改造,而且之前遇到过有些洞只在x86_64 work的情况
2022.8 update
参数 & 版本
case3
Android webview
这类其实也算个重灾区,很多厂商会选择自己定制webview,且为了方便不开沙箱,线上丰富多彩的功能也提供了很多攻击的入口,发链接、扫码、卡片消息;但是也都会在打开URL前考虑加一层拦截,提示用户“xxx不是xxxxxx,确定要打开吗”。但是21年反垄断之后,这个限制就下掉了,随之而来的就是这样的安全风险。
对于甲方来说就是,我的定制webview依赖chromium,我又没办法及时更新,沙箱也一定能开,在 nday和 patch gap
的双重打击之下,你的SRC可能就变成“提款机”,每个月谷歌一发补丁,再加上是不是爆出个在野利用,你的SRC一定经常收到这样的报告: xxxxx RCE
。
我也有做安全运营的朋友饱受其害,我只能建议他内部专项治理,定期合补丁,能上沙箱就沙箱,这个真没啥好办法。
总结
作为攻击方
- 搞定入口,这个比较吃经验了,见招拆招吧
- 多盯着点commit,开发一些工具啥的也可以,方便用
- 利用武器化,不是只弹个计算器就完了的
作为防守方
打补丁case by case,但是每个月都要来那么一次,还不能全自动化,有效但费人力。
开沙箱,毕竟是个浏览器,还是能打IPC穿沙箱穿出来,不过这就要看具体漏洞情况了。
升级到最新版,如果不稳定怎么办,这个也不是个好办法
补丁+升级+沙箱
三个维度一起来,毕竟短板效应,少了哪一块都不行,甲方的话也可以搞一些白盒工具来做补丁check,确认漏洞是否存在,这块就见仁见智了,我也写过一套,效果还行:D
服务端
chrome headless_shell 和 puppeteer
基本上还是 Exploit Headless Chrome这篇文章的内容,核心问题还是沙箱&版本过低的问题,这块比较严重的是网上很多人写教程、博客都喜欢--no-sandbox
,我也不知道他们知不知道这个参数的影响,不过一传十十传百,你会发现很多后端无头浏览器多多少少有这类问题。
总结
作为防守方
- 安全开发意识提高,不要为了方便乱用参数
- 及时更新版本or打补丁
扯远一些,有些扫描器用chrome,可以使用这手段做反制,你敢爬我轻则crash重则rce。
作为攻击方
- 版本探测比较重要,做这个操作前先想想银手镯
- 什么?你还想exp?我看你想戴上银手镯
为了风险治理做了什么
说到这个就想到了2020.11.13 那个下午弹出计算器的时候
主要是三块吧,我发现甲方里涮一圈之后思维确实不太一样了。
首先要讲明白风险,这里也包含证明风险,需要强有力的证明,比如exp打穿这样,研发可能不太理解为什么这样可以RCE,这就需要沟通好让大家有相同的sense
其次是修复方案,不同业务线、场景不一样,这个得和业务聊明白了才好给方案,不然就是“空中楼阁”,这块就算是治理存量问题了
- 沙箱开不开
- 补丁无法自动合入,怎么处理更高效,能不能自动化节省排期
- 以后怎么办,建立个什么流程跑这个事情
最后可以开发一些工具做一些预警工作,相当于治理增量问题
存量怎么扫,补丁怎么提取,这个部分得好好设计构思
预警Bot,这个本质就是个爬虫+机器人,之前研究的时候自己搞过一个tg bot专门干这个,还能搞漏洞查询
总结
我认为很有意思的是这个攻击面对于防守方来说简直是“折磨”,只要你的项目使用chromium,你就不得不面临各种补丁、升级,这实际上是很难做到及时补丁&升级的,所以理论上存在patch gap
,这就导致很多吸引眼球的 xxx RCE
传播的非常广泛。早在21年7月份,腾讯的蓝军在21年发布了攻防启示:Chromium组件风险剖析与收敛,也详细地剖析了该攻击面以及修复方案,对于我自己来说比较可惜的是在公司内部搞了这块攻击面的治理工作没有出去讲一讲or发个文章啥的,到后面这篇文章出来后已经没什么可讲的了 :(
主要想对自己的一些工作做个简单的总结,所以才有了本文,时至2022.8,这个攻击面应该已经变得众所周知,没有什么秘密可言了,想来这手法我在17年某项目上也见过,不过当时是webkit。