项目中的一个站,因为目标是基于第三方正规平台,只能找一些别的点进行渗透,正好看到了这个客服软件
前言
通过搜索引擎加上商务qq,得到了一个试用账号。下载客服软件,发现这个软件基于Electron 框架
介绍
Electron 是一款基于 Web 技术(HTML5 + Javascript + css)构建图形界面的开发框架,基于 nodejs 和 Chromium 开发。因为无痛兼容 nodejs 包管理(npm)的大量功能丰富的模块,相对于 native 实现降低了开发难度和迭代成本,受到了开发者的青睐。
解包
Electron的主文件在resources文件夹下,里面有个electron.asar,app.asar。electron.asar是自带的不用管,主要看app.asar,asar是压缩包,我们需要对它进行解压
安装asar
npm install -g asar
解压命令
asar extract app.asar <输出目录>
electron挖掘点
electron常见的漏洞有2个,一个是自定义协议造成的命令注入,一个是开启nodeIntegration造成的RCE。
自定义协议命令注入 (CVE-2018-1000006)
全局搜索setAsDefaultProtocolClient和registerSchemesAsPrivileged,并未发现关键字,说明未注册协议,这里就不用看了
开启nodeIntegration造成的RCE
**
全局搜索nodeIntegration,如果值为True,说明开启了Node.js扩展,可以执行系统命令。这时候我们只需要找到一个XSS点,然后执行Node.js系统命令,即可造成RCE。而这个客服软件nodeIntegration为True,且有XSS。Nodejs执行系统命令的语句是require(‘child_process’).exec('')
利用过程
与客服建立通话,发送payload如下

效果

漏洞分析
全局搜索{“type”:“say”, 定位到以下关键代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| sendMessageBtn: function() {
var t = this,
e = this.textarea.replace(/ /g, "").trim(),
a = !0;
if (this.externalLinkList.length && this.externalLinkList.forEach(function(i) { - 1 < e.indexOf(i.externalLink) && (t.$message.error("请勿发送包含外链的文本信息"), a = !1)
}), !a) return ! 1;
if ("" == this.chatInit.textarea.replace(/[ ]|[ ]/g, "")) return Object(v.Message)({
showClose: !0,
message: "发送的内容不能为空",
type: "error",
duration: 3e3
}),
!1;
this.chatTruth.showEmoji = !1;
var i = this.chatInit.textarea,
n = /\[(.+?)\]/g;
this.chatInit.textarea.match(n) && this.chatInit.textarea.match(n).map(function(t) {
for (var e in j.a) {
var a = "[" + j.a[e][0] + "]",
n = new RegExp("\\[(" + j.a[e][0] + ")\\]", "ig");
t == a && (i = i.replace(new RegExp(n, "g"), ":" + e + ":"))
}
});
var o = {
type: "say",
sendtime: this.getTimes(),
agent_avatar: this.chatInit.agentAvatar,
sendname: this.chatInit.agentName,
from_uid: this.chatInit.agentId,
to_uid: this.chatItem.onlineVisitorEntity.visitorId,
role: "agent",
msg_type: "text",
text: i
},
r = {
messagesId: this.chatItem.messageId,
visitorId: this.chatItem.onlineVisitorEntity.visitorId,
msgType: "text",
talk_time: "0",
text: i
};
|
可以看到text只过滤了/把它替为空,其他的完全没过滤。所以造成了RCE