背景
隨著移動應用的廣泛普及,惡意軟件也日趨複雜和隱蔽。本報告著眼於一個由ReBensk 提交至incinerator.cloud 的惡意Android 軟件樣本。
樣本哈希值:
MD5: 2f371969faf2dc239206e81d00c579ff
SHA-256: b3561bf581721c84fd92501e2d0886b284e8fa8e7dc193e41ab300a063dfe5f3
在ReBensk 提交至incinerator.cloud 的多個惡意樣本中,我們特別關注了一款經過自定義修改的APK 文件,以下簡稱為“樣本b356”。這個樣本採用了獨特的混淆和隱蔽技術,導致標準的解壓縮工具無法成功解壓其內容。通過特定的修正操作,我們成功突破這一限制,並進一步分析了該樣本。
分析過程
1. 解壓失敗分析
在嘗試使用7z 工具解壓這個APK 文件時(Apk 本質上是一個ZIP 文件),遇到錯誤顯示AndroidManifest.xml header錯誤,這說明標準的解壓過程無法正確地解壓樣本b356。
在使用010 Editor 打開APK 文件並應用ZipAdv 模板進行解析後,並未發現任何明顯的錯誤或異常。
為了更深入地了解問題,我們打開了一個正常運行的APK 文件進行對比分析。這樣做是為了確定是否存在某種特殊或不規則的結構或數據,可能是導致解壓失敗的原因。
通過對比發現,我們發現樣本b356 採用了一個不非法的壓縮算法0x23C2。在標準的ZIP 格式規範中,壓縮方法由一個短整數(short)表示,取值通常如下文所示(以下代碼取自010 Editor 的ZIPAdv.bt 模板)。由於0x23C2不是任何已知的標準壓縮方法,因此7z 等解壓工具無法識別和處理。
因此,樣本b356 採用了未知的壓縮算法,導致通用壓縮工具解壓縮失敗。但為什麼它能在Android 系統上仍然可以成功安裝和運行呢?
2. Android 系統的成功解析與運行原因
正如下圖所示, 根據Android 系統源代碼,當系統遇到非COMP_DEFLATE的壓縮算法時,它會採用“未壓縮”(COMP_STORED)的方法處理輸入文件。具體來說,系統直接讀取未壓縮數據的長度,並據此進行解析。
請注意看黃框和紅框中的代碼對比,在黃框中,如果使用的是COMP_DEFLATE 壓縮算法,系統將按照相應的方法解壓縮,如果不是,系統將直接讀取壓縮前的長度,然後進行處理。
這就解釋了為什麼修改了AndroidManifest 的壓縮方法後,系統仍然可以正確運行。樣本b356 在正常打包流程完成後,將包中的AndroidManifest.xml 文件內容替換為未壓縮前的內容,並將壓縮算法替換為非COMP_DEFLATE 。因此,常規解壓工具會失敗,但Android 系統會按照未壓縮的方式處理,因此可以正常運行。
3. 解壓程序的修改建議
3.1 修復 Apk
按照Android 系統的處理方式,Apk 的AndroidManifest.xml 只能採用兩種壓縮方式。 COMP_DEFLATE 或未壓縮。
如果壓縮算法不是默認的COMP_DEFLATE ,那麼一定是未壓縮。因此修復apk 的方法是,如果發現壓縮算法不是COMP_DEFLATE ,將壓縮算法設置為0,即未壓縮,並將壓縮後的長度設置為壓縮前的長度。這樣,常規解壓工具就可以解壓了。
修復後,我們嘗試使用7-Zip(通常簡稱為7z)工具進行解壓,結果如下圖所示。儘管仍然存在錯誤,特別是關於CRC(循環冗餘檢查)值尚未修復的問題,但我們已成功解壓了APK 文件,並可以訪問其中的AndroidManifest.xml 內容。
3.2 靜態分析工具的修復
靜態分析工具可以按照系統的解壓方式處理,如果發現AndroidManifest.xml 的壓縮方法不是COMP_DEFLATE ,那麼就讀取壓縮前的長度作為AndroidManifest.xml 的內容。
總結
由於Android 系統在解析時對非COMP_DEFLATE 的壓縮方式採取的是未壓縮處理,從邏輯上看,這種做法並不符合規範,因此,導致b356 成功地利用了這一邏輯漏洞。徹底的解決方案應該是Android 系統按照規範的zip 包解壓格式進行處理。
來源:https://www.liansecurity.com/#/main/news/GzKmQIoBUQjGUXE22_tO/detail
Recommended Comments