Electron客户端漏洞挖掘
转载请注明出处:https://youngrichog.github.io/
描述
最近一段时间都在研究客户端相关的漏洞,想着能在客户端漏洞挖掘方向有所突破,做为一个多年混迹于Web安全的🐶来说,换换口味去尝试新的方向也不错,2018年看到大佬没用多长时间就挖掘到客户端RCE漏洞的我眼红了,2019年偶然间和大佬撞洞了,从此激发了我对客户端漏洞的向往。
本文中基本不含二进制安全相关内容,主要是从Web安全的视角去学习挖掘使用Electron做跨平台桌面的应用。
基本的学习思路:乌云漏洞镜像–>搜索关键字“客户端命令执行”、“客户端漏洞”、“客户端远程命令执行”–>遇到不懂的名词进行搜索和学习–>遇到需要学习的内容记录下来,然后后续进行学习–>对一些漏洞发现和漏洞利用的点进行思考
前前后后记录了一些:
1.UXSS是什么?如何利用?
2.文件名如何修改为../../../../../../xxx/xxxx这种?
3.特权域如何查找?例如百度浏览器baidu.com都是特权域
4.RFD攻击是什么?
UXSS
UXSS(Universal Cross-Site Scripting Attacks)通用跨站脚本攻击,利用浏览器本身或浏览器扩展中的漏洞来实现XSS。攻击者可以访问浏览器中当前打开的任何页面,包括内部浏览器页面,即使是不同域的情况。从攻击者的角度来看,UXSS漏洞同远程命令执行漏洞一样有价值。UXSS和XSS的区别就是范围不同、漏洞对象的不同。
研究方向:
- 浏览器插件
例子:https://blog.neargle.com/2018/02/14/hacking-chrome-extensions-chapter-one-a-uxss/
- 探针
通过探测目标使用插件情况,对其进行安全研究,做到点对点攻击。我们应该脑图下在定点攻击一个目标的时候到底有多少种攻击路径 :-)
例子:https://mp.weixin.qq.com/s/HHPxGTk55oEw0Pj4TRg6FA
- 浏览器本身
例如:IE8跨站脚本过滤器缺陷/IE6或火狐浏览器扩展程序Adobe Acrobat的漏洞/Flash Player UXSS 漏洞
一份不错的参考:https://research.google/pubs/pub48028/
RFD
RFD(Reflected-File-Download-Attack)为反射文件下载漏洞,攻击者可以通过受信任的域名中下载文件从而控制受害者。
看起来这句话,好像就是一个下载文件的意思 😂
这个漏洞触发的几个关键点:
- 文件名和文件拓展名是可控的
- 命令注入,用户可以在url中注入; | &等
- 文件内容可控
- 域名可信度较高
例如:
http://www.xxxx.com/download/filename=1.php&content=test
http://www.xxxx.com/download/filename=1.bat&content=test||calc
这样就完成了漏洞的触发,可能我这里也是描述的不是很准确 QaQ
学习过程当中遇到不懂的了解完成后,就开始回到正题 Electron客户端漏洞挖掘
漏洞发现
如何发现客户端漏洞?
第一条路:XSS
第二条路:URL Scheme
第三条路:混合攻击
第四条路:监听端口(调试端口、RPC等)
我们在对客户端进行漏洞挖掘的时候,首先需要进行XSS的漏洞挖掘,寻找XSS触发的点。这里在发现XSS的过程中可以借助客户端自带的代理设置或者我们自行设置,通过Burp进行一些自动化的XSS发现,当然也是黑盒方向。白盒的话,通过可以在应用目录下找到asar包,通过解压得到打包前的文件asar extract xxx.asar ./
然后就是对输入可控的地方进行代码审计。这里在挖掘XSS的时候,有个大家都容易忽略的点,location.hash(),例如:http://www.baidu.com/index/message#parameter,document.write(location.hash),输出#parameter,http://www.baidu.com/index/messag#<script>a1ert(1)</script>
当我们得到XSS后,我们需要判断该应用是否有特权域,在我挖掘的过程中暂时没有发现应用存在特权域的情况,可能是我刚开始接触的原因?在浏览器中会存在特权域,例如Chrome浏览器中chrome://extensions/、chrome://settings/、chrome://downloads/等等都是特权域,有些厂商的浏览器还会将自己的部分域名设置为特权域,例如早些时候的百度浏览器会将baidu.com设置为特权域,除此之外浏览器的信任站点(Trusted sites Intranet Zone)也是特权域。那么为什么有些浏览器会将自己的域名设置为特权域,或者说为什么会有特权域?由于业务需要,或者说需要调用某些功能、某些操作、API等就会用到特权域。file://也是特权域
这里有一个逻辑:如果应用存在特权域,而我们的XSS不在特权域内,那么我们需要挖掘一个特权域内的XSS或直接进行高危API的寻找,如果说API不在特权域内我们就可以随便进行调用。如果应用不存在特权域,那就开始杀戮就好了。
URL Scheme,应用为了方便自己,会注册自定义的协议,URL Scheme经常用于:应用间的互相跳转、唤醒应用、跳转页面、唤起应用传参。我们可以经常见到,我们在网页上打开某页面的时候会提示我们是否在打开链接,当我们点击是之后就会唤醒应用,如下面我们在浏览器输入ssh://123.123.123.123,就会唤起终端进行ssh链接。
应用注册URL Scheme有两种办法:
1.应用在安装过程中进行注册表创建(HKEY_CLASSES_ROOT)
2.Electron API进行注册 app.setAsDefaultProtocolClient(protocol[, path, args])
注册表:
1 | HKEY_CLASSES_ROOT |
其中%1表示占位符,可以用来进行参数的传递,如果我们想运行alert.exe,那么我就可以通过伪协议打开,alert:就会启动,此外我们想知道哪些应用注册了伪协议就可以遍历注册表HKEY_CLASSES_ROOT。
这里提供几个自动化发现的脚本:
https://images.seebug.org/archive/duh4win.vbs
https://images.seebug.org/archive/duh4mac.m
https://images.seebug.org/archive/duh4linux.sh
https://github.com/ChiChou/LookForSchemes
这里我引用下其他大佬写的文章
链接地址:https://paper.seebug.org/515/
HKEY_CLASSES_ROOT 下不仅保存了伪协议的列表,还有文件扩展名的关联数据。事实上 Win32 程序处理本地文件和 url 的打开是类似的,甚至可以使用同一套 Win32 API —— ShellExecute(Ex) 。算上 ANSI 和 Unicode 的版本,一共 4 个函数。
打开一个本地文件:
ShellExecuteW(NULL, L”open”, L”c:\hello.txt”, NULL, NULL , SW_SHOW );
通过系统默认浏览器访问淘宝:
ShellExecuteW(NULL, L”open”, L”https://www.taobao.com", NULL, NULL , SW_SHOW );
可以看到除了 lpFile 之外其他参数可以保持完全一致。ShellExecuteExW 也是类似的情况。
ShellExecute 系列函数在这里埋了两个坑。首先是可能存在开发者原本打算传入 url,却被解析成本地路径而变成打开文件甚至运行可执行文件;其次是关联命令行里包裹参数 “%1” 的双引号竟然是可以被闭合掉的。
在 MSDN 中直接说明了闭合引号这一行为:
To mitigate this issue:
Avoid spaces, quotes, or backslashes in your URI
Quote the %1 in the registration (“%1” as written in the ‘alert’ example registration) However, avoidance doesn’t completely solve the problem of quotes in the URI or a backslash at the end of the URI.
再回到注册表关联的字符串部分。既然可以用双引号闭合 “%1”,这意味着可以通过伪造 argv 来向应用程序插入多个参数开关。例如 alert:1” –this-is-the-new “what
最终创建的命令行变成了:
“C:\Program Files\Alert\alert.exe” “alert:1” –this-is-the-new “what”
Electron 生成的应用发行包包括两部分——预编译好的 Electron 运行时和应用本身的 Web 资源文件打包(*.asar)。由于 Electron 基于 Chromium 开发,一些 Chromium 的命令行开关对于 Electron 的主执行文件同样起作用。
我们可以发现如果在对%1处理不妥时就可以进行参数注入,最终可结合Chromium的命令造成命令注入。
可利用的Chromium命令:
- –renderer-cmd-prefix
- –gpu-launcher
- –utility-cmd-prefix
- –ppapi-plugin-launcher
- –nacl-gdb
- –ppapi-flash-path
- –ppapi-flash-args
好像还有其他的,不过太长时间不记得了。
突发奇想,其实我们可以进行自动化的漏洞挖掘,我们通过程序进行批量遍历url scheme然后进行批量化的执行伪协议并注入恶意命令,然后谁弹计算器就是谁有问题😂可能略显笨拙,但是只要能解决问题就好了。当然有些url scheme是通过app.setAsDefaultProtocolClient注册的,其实我们就可以去尝试批量提取。YY结束!!
混合攻击,这样的攻击场景我们经常看到,例如在Web方向,黑客通过构造恶意SQL的xlsx表格上传至平台导致SQL注入,还有ssrf、xml等。当然还可以看到有很多可以引用第三方文档、pdf、excel、视频、音乐等,这样的话就会造成混合攻击。
《Hacking: The Next Generation: The Next Generation》在这本书中有提到混合攻击,https://www.amazon.com/Hacking-Next-Generation-Animal-Guide/dp/0596154577,混合攻击因涉及多个应用,也是最容易出问题。
监听端口(调试端口、RPC等),有些应用为方便调用和开发人员调试,会在本地监听一些奇怪的端口,这些端口上可能就会存在一些接口可以进行利用。有些应用的API可以在开发文档里面找到。
漏洞利用
当我们挖掘到XSS后,我们要确定有无特权域,然后进行后续操作。特权域里面的XSS称为XCS
无特权域->寻找特权API(下载、执行等)->写POC
有特权域->寻找不在特权域内的高危API->写POC
有特权域->寻找特权域XSS->寻找特权API->写POC
这里有4个问题需要关注,如何寻找应用自己的API?如何执行使用child_process进行命令执行?应用内如何打开调试模式?信任站点(Trusted sites Intranet Zone)的漏洞利用?
如何寻找应用自己的API?
我们可以根据目标应用浏览器内核相应对比,这里以Chrome为例,Chrome Console->window,发现大量函数,然后在目标应用也进行相同操作,两者进行对比就可以发现那些是应用独有的。然后针对应用自有的进行分析看是否有可利用的函数。如果有require那是最好的,有可能require会被重命名,这里要注意下。window.parent会返回当前窗口父窗户的函数,说不定就会有惊喜
如何执行使用child_process进行命令执行?
当Electron应用的nodeIntegration属性设置为True,就可以直接调用child_proccess直接命令执行,除了这个属性,contextIsolation属性也会存在安全风险,在contextIsolation值设置为false的时候,一个普通web页面上的js代码可以通过preload的方式(预加载)影响到Electron内部renderer上的js代码执行,使得RCE有可能在nodeIntegration被设置为false的情况下实现利用。该属性默认就是false!!
应用内如何打开调试模式?
打开DevTools的方式,默认是Ctrl+Shift+I,如果不对需要查看源码找到electron.globalShortcut.register,具体看注册了什么键值
这里假设我们发现特权API,可以进行下载,但是没有执行的办法,我们有什么利用方式吗?
可下载,无法执行:
1.DLL劫持
2.系统启动目录
3.覆盖常用软件(例如覆盖终端,然后使用伪协议进行执行)
4.文件加载
还有利用浏览器缓存+伪协议,这里有一个例子:http://wy.zone.ci/bug_detail.php?wybug_id=wooyun-2016-0175902
特权API除了可能包含下载、执行,还可以读文件、删除文件、获取敏感信息如读cookie文件、判断补丁信息、软件安装等
信任站点(Trusted sites Intranet Zone)的漏洞利用?
- 信任站点XSS
- 域名控制权(还有额外彩蛋:中间人攻击,例如可控DNS)
- 网站权限
当我们发现应用存在URL Scheme后,尝试进行命令注入,这里会遇到一个问题就是在Chrome、Firefox浏览器下进行测试的时候,会对URL进行urlencode,CEF框架不会对URL进行urlencode,这样就可以触发漏洞。在进行命令注入的时候,我们需要根据情况对%1的参数进行闭合。
"c:\Windows\\System32\cmd.exe" %1
%1 则payload:href=’cmd://123 –renderer-cmd-prefix=”cmd.exe /c start calc.exe” ‘
"c:\Windows\\System32\cmd.exe" "%1"
“%1”则payload:href=’cmd://123” –renderer-cmd-prefix=”cmd.exe /c start calc.exe ‘
1 | <iframe src='cmd://? --renderer-cmd-prefix="cmd.exe /c start calc.exe"'> |
写累了,暂时先这样吧 :-)
反正是按照自己理解写的,写错了就写错了吧,但是得给我指出来呀,不能让我一直错下去。
欢迎指点与交流!
Respect
去年跨过的浏览器PPT