Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android安全開發之ZIP文件目錄遍歷,androidzip

Android安全開發之ZIP文件目錄遍歷,androidzip

編輯:關於android開發

Android安全開發之ZIP文件目錄遍歷,androidzip


1、ZIP文件目錄遍歷簡介

ZIP壓縮包文件中允許存在“../”的字符串,攻擊者可通過精心構造ZIP文件,利用多個“../”從而改變ZIP包中某個文件的存放位置,覆蓋替換掉應用原有的文件。如果被覆蓋掉的文件是是可.so文件、dex文件或者odex文件,輕則產生本地拒絕服務漏洞,影響應用的可用性,重則可能造成任意代碼執行漏洞,危害應用用戶的設備安全和信息安全。比如“寄生獸”漏洞,海豚浏覽器遠程命令執行漏洞,三星默認輸入法遠程代碼執行等。

阿裡聚安全的應用漏洞掃描器,可以檢測出應用的ZIP文件目錄遍歷風險,並有完整的修復方案。另外我們還發現日本計算機應急響應小組(JPCERT)給出的修復方案存在缺陷,容易使用不當(它提供的示例文檔就使用錯誤),可能起不到防止ZIP文件目錄遍歷的作用。

 

2、漏洞原理和風險示例

2.1 漏洞原理

在Linux/Unix系統中“../”代表的是向上級目錄跳轉,有些程序在當前工作目錄中處理到諸如用“../../../../../../../../../../../etc/hosts”表示的文件,會跳轉出當前工作目錄,跳轉到到其他目錄中。 
Java代碼在解壓ZIP文件時,會使用到ZipEntry類的getName()方法,如果ZIP文件中包含“../”的字符串,該方法返回值裡面原樣返回,如果沒有過濾掉getName()返回值中的“../”字符串,繼續解壓縮操作,就會在其他目錄中創建解壓的文件。

如我們構造的ZIP文件中有如下文件:

進行解壓的代碼如下,沒有對getName進行過濾:

 

解壓操作時的日志:

 

此ZIP文件存放在SD卡中,想讓解壓出來的所有文件也存在SD卡中,但是a_poc.txt文件卻存在了應用的數據目錄中:

 

2.2 風險示例

參考烏雲Drops上的文章:http://drops.wooyun.org/mobile/8293,以海豚浏覽器遠程代碼執行漏洞為例。海豚浏覽器海豚浏覽器的主題設置中允許用戶通過網絡下載新的主題進行更換,主題文件其實是一個ZIP壓縮文件。通過中間人攻擊的方法,替換掉這個ZIP文件。用來替換ZIP文件的惡意ZIP文件中,有重新編譯的libdolphin.so,此so文件,重寫了JNI_OnLoad()函數:

 

此so文件以“../../../../../../../../../../data/data/mobi.mgeek.TunnyBrowser/files/libdolphin.so”的形式存在惡意ZIP文件中。海豚浏覽器解壓惡意ZIP文件後,重新的libdolphin.so就會覆蓋掉原有的so文件,重新運行海豚浏覽器會彈出Toast提示框:

 

 

能彈出Toast說明也就可以執行其他代碼。

這裡分析下此漏洞產生的原因是: 
1、主題文件其實是一個ZIP壓縮包,從服務器下載後進行解壓,但是解壓時沒有過濾getName()返回的字符串中是否有“../”:

 

2、動態鏈接庫文件libdolphin.so,並沒有放在應用數據的lib目錄下,而是放在了files目錄中:

 

加載使用的地方是com.dolphin.browser.search.redirect包中的SearchRedirector:

應用使用的是System.load()來加載libdolphin.so而非System.loadLibrary(),在Android中,System.loadLibrary()是從應用的lib目錄中加載.so文件,而System.load()是用某個.so文件的絕對路徑加載,這個.so文件可以不在應用的lib目錄中,可以在SD卡中,或者在應用的files目錄中,只要應用有讀的權限目錄中即可。

在files目錄中,應用具有寫入權限,通過網絡中間人攻擊,同時利用ZIP文件目錄遍歷漏洞,替換掉文件libdolphin.so,達到遠程命令執行的目的。

應用的lib目錄是軟鏈接到了/data/app-lib/應用目錄,如果libdolphin.so文件在lib目錄下就不會被覆蓋了,第三方應用在執行時沒有寫入/data/app-lib目錄的權限:

 

3、JPCERT修復方案的研究

JPCERT提供的修復方案在文檔:https://www.jpcert.or.jp/present/2014/20140910android-sc.pdf。

其檢查方式是利用File類提供的getCanonicalPath()方法濾掉zipEntry.getName()返回的字符串中所包含的“../”,然後檢查這個字符串是否是以要解壓到的目標目錄字符串為開頭,如果是返回getCanonicalPath()獲取到的字符串,如果不是,則拋出異常:

 

但是在JPCERT給出的示例代碼中,對validateFilename()的調用對於APP來說不會達到防止任意目錄遍歷的目的:

 

其使用“.”,作為要解壓到的目的目錄,“.”表示當前目錄,經測試APP進程的當前工作目錄是根目錄“/”:

 

查看進程狀態,得到的APP進程的當前工作目錄cwd是鏈接到了根目錄:

 

如下的Demo,如果采用JPCERT示例中validateFilename(entry.genName(), “.”)的調用方式,還是會產生目錄遍歷讀到系統配置文件:

 

讀到的hosts文件內容:

正確的調用validateFilename()形式是傳入的要解壓到的目的目錄不要用“.”,而是指定一個絕對路徑。

 

4、阿裡聚安全對開發者建議

1)網絡傳輸盡量使用HTTPS,並正確使用HTTPS。 
2)對重要的ZIP進行數字簽名校驗,校驗通過才進行解壓。 
3)檢查Zip壓縮包中使用ZipEntry.getName()獲取的文件名中是否包含”../”或者”..”,檢查”../”的時候不必進行URI Decode(以防通過URI編碼”..%2F”來進行繞過),測試發現ZipEntry.getName()對於Zip包中有“..%2F”的文件路徑不會進行處理。

 

阿裡聚安全掃描器建議修復方案: 
在使用java.util.zip包中ZipInputStream類的進行解壓操作時,進行檢查,示例如下:

也可以使用java.util.zip包中的ZipFile類,直接讀取Zip包中的所有entries,然後檢查getName()的返回值是否包含“../”:

 

5、參考

[1] https://www.jpcert.or.jp/present/2014/20140910android-sc.pdf 

[2] 《海豚浏覽器與水星浏覽器遠程代碼執行漏洞詳解》http://drops.wooyun.org/mobile/8293 

[3] 《影響數千萬APP的安卓APP“寄生獸”漏洞技術分析》http://drops.wooyun.org/mobile/6910 

[4] 《三星默認輸入法遠程代碼執行》http://drops.wooyun.org/papers/6632 

[5] http://www.oracle.com/technetwork/articles/java/compress-1565076.html 

[6] http://stackoverflow.com/questions/1099300/whats-the-difference-between-getpath-getabsolutepath-and-getcanonicalpath 

[7] http://stackoverflow.com/questions/7016391/difference-between-system-load-and-system-loadlibrary-in-java

 

6、Android安全開發系列

目錄

Android安全開發之Provider組件安全

Android安全開發之淺談密鑰硬編碼

Android安全開發之淺談網頁打開APP

Android應用安全開發之淺談加密算法的坑

 

作者:伊樵、呆狐、舟海@阿裡聚安全,更多安全技術文章,請訪問阿裡聚安全博客

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved