# Aplikacje desktopowe Electron
{{#include ../../../banners/hacktricks-training.md}}
## Wprowadzenie
Electron łączy lokalny backend (z **NodeJS**) i frontend (**Chromium**), chociaż brakuje mu niektórych mechanizmów bezpieczeństwa nowoczesnych przeglądarek.
Zazwyczaj kod aplikacji electron można znaleźć wewnątrz aplikacji `.asar`, aby uzyskać kod, musisz go wyodrębnić:
```bash
npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file
```
W kodzie źródłowym aplikacji Electron, w pliku `packet.json`, można znaleźć określony plik `main.js`, w którym ustawiane są konfiguracje zabezpieczeń.
```json
{
"name": "standard-notes",
"main": "./app/index.js",
```
Electron ma 2 typy procesów:
- Proces główny (ma pełny dostęp do NodeJS)
- Proces renderera (powinien mieć ograniczony dostęp do NodeJS z powodów bezpieczeństwa)
.png>)
**Proces renderera** będzie oknem przeglądarki ładującym plik:
```javascript
const { BrowserWindow } = require("electron")
let win = new BrowserWindow()
//Open Renderer Process
win.loadURL(`file://path/to/index.html`)
```
Ustawienia **procesu renderera** mogą być **konfigurowane** w **procesie głównym** w pliku main.js. Niektóre z konfiguracji **zapobiegną uzyskaniu RCE** lub innych luk w zabezpieczeniach, jeśli **ustawienia są poprawnie skonfigurowane**.
Aplikacja electron **może uzyskać dostęp do urządzenia** za pomocą interfejsów API Node, chociaż można ją skonfigurować, aby temu zapobiec:
- **`nodeIntegration`** - jest `wyłączone` domyślnie. Jeśli włączone, pozwala na dostęp do funkcji node z procesu renderera.
- **`contextIsolation`** - jest `włączone` domyślnie. Jeśli wyłączone, procesy główny i renderer nie są izolowane.
- **`preload`** - pusty domyślnie.
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - jest wyłączone domyślnie. Ograniczy to działania, które NodeJS może wykonać.
- Integracja Node w Workerach
- **`nodeIntegrationInSubframes`** - jest `wyłączone` domyślnie.
- Jeśli **`nodeIntegration`** jest **włączone**, umożliwi to korzystanie z **API Node.js** na stronach internetowych, które są **ładowane w iframe** w aplikacji Electron.
- Jeśli **`nodeIntegration`** jest **wyłączone**, wówczas preloady będą ładowane w iframe.
Przykład konfiguracji:
```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,
},
}
```
Niektóre **RCE payloads** z [tutaj](https://7as.es/electron/nodeIntegration_rce.txt):
```html
Example Payloads (Windows):
Example Payloads (Linux & MacOS):
```
### Przechwytywanie ruchu
Zmień konfigurację start-main i dodaj użycie proxy, takiego jak:
```javascript
"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",
```
## Wstrzykiwanie kodu lokalnego w Electron
Jeśli możesz lokalnie uruchomić aplikację Electron, istnieje możliwość, że możesz sprawić, aby wykonała dowolny kod JavaScript. Sprawdź jak w:
{{#ref}}
../../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md
{{#endref}}
## RCE: XSS + nodeIntegration
Jeśli **nodeIntegration** jest ustawione na **włączone**, JavaScript na stronie internetowej może łatwo korzystać z funkcji Node.js, po prostu wywołując `require()`. Na przykład, sposób uruchomienia aplikacji kalkulatora w systemie Windows to:
```html
```
## RCE: preload
Skrypt wskazany w tym ustawieniu jest **ładowany przed innymi skryptami w rendererze**, więc ma **nieograniczony dostęp do Node APIs**:
```javascript
new BrowserWindow{
webPreferences: {
nodeIntegration: false,
preload: _path2.default.join(__dirname, 'perload.js'),
}
});
```
Dlatego skrypt może eksportować node-features do stron:
```javascript:preload.js
typeof require === "function"
window.runCalc = function () {
require("child_process").exec("calc")
}
```
```html:index.html
```
> [!NOTE] > **Jeśli `contextIsolation` jest włączony, to nie zadziała**
## RCE: XSS + contextIsolation
_**contextIsolation**_ wprowadza **oddzielone konteksty między skryptami strony internetowej a wewnętrznym kodem JavaScript Electron**, aby wykonanie JavaScript w każdym kodzie nie wpływało na siebie nawzajem. Jest to niezbędna funkcja, aby wyeliminować możliwość RCE.
Jeśli konteksty nie są izolowane, atakujący może:
1. Wykonać **dowolny JavaScript w rendererze** (XSS lub nawigacja do zewnętrznych stron)
2. **Nadpisać wbudowaną metodę**, która jest używana w preload lub wewnętrznym kodzie Electron na własną funkcję
3. **Wywołać** użycie **nadpisanej funkcji**
4. RCE?
Są 2 miejsca, w których wbudowane metody mogą być nadpisane: W kodzie preload lub w wewnętrznym kodzie Electron:
{{#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}}
### Ominięcie zdarzenia kliknięcia
Jeśli na kliknięcie linku nałożone są ograniczenia, możesz być w stanie je obejść **wykonując kliknięcie środkowe** zamiast zwykłego lewego kliknięcia.
```javascript
window.addEventListener('click', (e) => {
```
## RCE za pomocą shell.openExternal
Aby uzyskać więcej informacji na temat tych przykładów, sprawdź [https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8](https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8) oraz [https://benjamin-altpeter.de/shell-openexternal-dangers/](https://benjamin-altpeter.de/shell-openexternal-dangers/)
Podczas wdrażania aplikacji desktopowej Electron, zapewnienie odpowiednich ustawień dla `nodeIntegration` i `contextIsolation` jest kluczowe. Ustalono, że **wykonywanie zdalnego kodu na stronie klienta (RCE)**, które celuje w skrypty preload lub natywny kod Electron z głównego procesu, jest skutecznie zapobiegane przy tych ustawieniach.
Po interakcji użytkownika z linkami lub otwieraniu nowych okien, uruchamiane są określone nasłuchiwacze zdarzeń, które są kluczowe dla bezpieczeństwa i funkcjonalności aplikacji:
```javascript
webContents.on("new-window", function (event, url, disposition, options) {}
webContents.on("will-navigate", function (event, url) {}
```
Te nasłuchiwacze są **nadpisywane przez aplikację desktopową**, aby wdrożyć własną **logikę biznesową**. Aplikacja ocenia, czy nawigowany link powinien być otwarty wewnętrznie, czy w zewnętrznej przeglądarce internetowej. Decyzja ta jest zazwyczaj podejmowana za pomocą funkcji `openInternally`. Jeśli ta funkcja zwraca `false`, oznacza to, że link powinien być otwarty zewnętrznie, wykorzystując funkcję `shell.openExternal`.
**Oto uproszczony pseudokod:**
.png>)
.png>)
Najlepsze praktyki bezpieczeństwa Electron JS odradzają akceptowanie nieufnej zawartości za pomocą funkcji `openExternal`, ponieważ może to prowadzić do RCE przez różne protokoły. Systemy operacyjne obsługują różne protokoły, które mogą wywołać RCE. Aby uzyskać szczegółowe przykłady i dalsze wyjaśnienia na ten temat, można odwołać się do [tego zasobu](https://positive.security/blog/url-open-rce#windows-10-19042), który zawiera przykłady protokołów Windows zdolnych do wykorzystania tej podatności.
**Przykłady exploitów protokołów Windows obejmują:**
```html
```
## Odczyt wewnętrznych plików: XSS + contextIsolation
**Wyłączenie `contextIsolation` umożliwia użycie tagów ``**, podobnie jak `