Android漏洞解析之旅---利用ZipEntry漏洞實現免root寫惡意文件到應用的沙盒中

一、前言

Android中的漏洞真的很多,一不小心就踩到坑了,最近開發過程中遇到一個問題,解決發現一個很大的漏洞,而這個漏洞到現在也沒有修復,google也沒有想過修復,下面就來看看這個漏洞的場景。

 

二、漏洞場景分析

Android中現在開發過程中會有很多場景中使用到解壓縮文件,比如動態加載機制,可能下載了apk/zip文件,然後在本地做解壓工作,還有就是一些資源在本地佔用apk包的大小,就也打包成zip放到服務端,使用的時候在下發。本地在做解壓工作。那麼在Android中解壓zip文件,使用的是ZipInputStream和ZipEntry類,代碼比較簡單:

代碼看上去很簡單,但是這段代碼中就存在一個問題,就是那個zipEntry.getName方法,這個方法返回的是zip文件中的子文件名稱,按照正常邏輯,解壓這個子文件到本地都是直接用相同的名字即可,但是這裏zip文件就存在一個漏洞:

zip文件中的子文件名格式沒有格式要求,也就是可以包含特殊字符。

但是在系統中是有限制的,比如Windows中:

在Linux中:

這些系統中是不允許文件名包含一些特殊字符的,但是在ZipInputStream/ZipOutputStream類卻是可以的。

也就是說使用ZipOutputStream類進行壓縮文件,這裏可以對文件名不做任何限制,壓縮代碼也簡單:

只用ZipEntry類做單個文件壓縮:

這裏的ZipEntry可以指定隨意的名稱,而這個名稱就是文件在zip中的文件名。但是問題是這裏對名稱沒有任何限制,那麼如果我們的zip包被人惡意的攔截,然後進行修改,當然這裏他可以使用ZipInputStream/ZipOutputStream類,寫一個簡單的小程序,就可以把惡意文件寫入到zip中

 

三、漏洞出現的原因

這裏的惡意漏洞的問題就在於:

因爲文件名沒有限制,所以攻擊者可以把惡意文件名稱命名爲:../../../../data/data/xxx.xxx.x/hacker.dex,因爲Android是基於Linux系統的,在Linux系統中../這個符號代表是回到上層目錄,那麼這裏可以多弄幾個這個符號,這樣就會回到Android系統的根目錄,然後在進入當前應用的沙盒目錄下,寫一個文件了。當然這裏只能寫入本應用中,而不能寫入其他應用。

存在的風險:比如現在知道了一個應用的沙盒數據的詳細信息,比如一些隱私數據存放在SharedPreferences.xml中,或者是有動態加載機制,需要加載的dex存放在一個目錄中,那麼這時候我們可以利用這個漏洞,把幾個惡意文件,命名成

../../../../data/data/xxx.xxx.xxx/shared_pref/info.xml,或者是../../../../data/data/xxx.xxx.xxx/dexfile/dynamic.dex等

這樣在使用ZipEntry進行解壓文件的時候,因爲直接使用了ZipEntry.getName方法或者文件名,然後直接釋放解壓到本地了,所以這時候就相當於替換了本應用的沙盒數據了,這個也是利用了app本身的權限來寫入沙盒數據。

 

四、漏洞案例分析

上面分析完了漏洞,下面就用一個簡單的例子來看看問題吧:

因爲,我們上面分析知道,在本地系統中命名這樣特殊格式的文件,在進行壓縮成zip文件是不行的,因爲系統不支持這種命名格式,所以這裏需要寫一個小程序,把這個特殊的文件名的文件壓縮成zip,便於測試,然後在進行解壓:

先進行壓縮文件,方便測試,產生一個demo.zip文件,然後在進行解壓驗證漏洞問題,這裏驗證問題的重點是:

這裏把zip中需要解壓的文件名前加上前綴:../../../data/data/cn.wjdiankong.androidzipleakdemo/ 這樣解壓之後的目錄就是本應用的沙盒中了,注意這裏的../這樣的符號不要太多,只要能回到根目錄就可以了。

這裏爲了方便,直接使用echo命令,寫入aaa內容到demo.txt文件中,然後點擊壓縮,再次查看多了demo.zip文件了:

看到了,這裏就把zip中的惡意文件demo.txt釋放到了應用的沙盒中了,如果這個文件是dex或者啥,替換原來應用的一些重要文件,那麼後果會很嚴重的。

 

五、如何避免這個漏洞問題

上面的問題,我們瞭解了,主要是因爲ZipEntry在進行壓縮文件的時候,名稱沒有做任何限制,而在Android系統中../這種特殊符號代表的是回到上層目錄,又因爲這個解壓工作在本應用中,可以藉助app的自生權限,把惡意文件名改成:../../../data/data/...即可在解壓的時候把文件解壓到了應用的沙盒中。

那麼其實問題在於最後一步解壓,因爲我們不會去修改解壓之後的文件名,默認都是直接解壓即可,那麼這裏修復這個漏洞問題很簡單了,有很多種方式,核心就一個就是不要讓有特殊字符,比如:../ 的文件成功解壓,或者是解壓到本地文件名稱不能包含這種特殊字符即可:

這裏可以直接過濾來防護這個問題了。

 

六、問題延展

上面分析了現在應用很多都有從服務端下載zip文件,然後在本地進行解壓的功能,在解壓的過程中默認不回去進行文件名的操作,所以就存在一些特殊字符的文件名被釋放到了本地,從而產生重大後果。但是這裏有一個前提,就是你需要下載的zip文件被攻擊者攔截到了,並且替換了。但是如果在下載的過程中就做一層安全其實也是可以的,比如使用https協議,然後在結合文件的MD5比對功能,這樣就可以防止zip包被人攔截替換了。本地也就不會存在這樣的風險了。

所以現在Android中動態加載技術和插件化開發已經很普遍了,但是在下載這個階段一定要好防護工作,一個是服務端可以採用https協議,而客戶端需要做文件的MD5比對,以及這種解壓工作的防護過濾。

如果你的項目現在正好有解壓zip的功能,請看完這篇文章之後,儘快去審查一下項目中解壓有沒有做防護,沒有的話就儘快加上吧!

 

本文的目的只有一個就是學習更多的逆向技巧和思路,如果有人利用本文技術去進行非法商業獲取利益帶來的法律責任都是操作者自己承擔,和本文以及作者沒關係,本文涉及到的代碼項目可以去編碼美麗小密圈自取,歡迎加入小密圈一起學習探討技術

 

七、漏洞總結

本文主要介紹了一個不起眼的漏洞,但是隱藏着很嚴重的問題,這個漏洞主要是因爲如下幾點綜合產生的:

1、ZipEntry對壓縮文件名沒有特殊要求

2、在Android系統中../特殊字符代表着回到上級目錄

3、藉助本應用的權限,把數據寫入沙盒中

因爲這三點,就可以在解壓過程中把惡意文件解壓到應用的沙盒中,當然這裏有一個前提就是你的zip包被人攔截並且篡改加入這種特殊字符的惡意文件了。

關於這個漏洞的修復,Google一直沒有修復,只是在Api中做了提醒:

可以看到google對該方法給出了一個安全提示,提示開發者如果該方法的返回值中包含有"../"跳轉符,需要特別注意不要將文件寫到了目標文件夾之外。如果不對"../"跳轉符做過濾,就有可能遍歷目錄,在解壓zip文件時以本app的權限覆蓋任意文件。

項目下載:http://download.csdn.net/detail/jiangwei0910410003/9594958

 

八、總結

人生處處是坑,Android系統處處是漏洞,開發中碰到這個問題,真的很難注意到,但是卻隱藏這很大的風險,所以有項目中用到了zip解壓的速度檢查項目,如果有的話,看看有沒有添加防護過濾,保證我們的項目沒有這個漏洞的風險!

 

《Android應用安全防護和逆向分析》

點擊立即購買:京東  天貓  

更多內容:點擊這裏

關注微信公衆號,最新技術乾貨實時推送

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章