使用FRIDA為Android應用進行脫殼的操作指南
FortiGuard實驗室最近遇到了很多加殼Android惡意軟體。這類惡意軟體一個很有趣的點是,儘管使用的加殼工具是一樣的,但生成的惡意軟體卻常常會發生變化。
分析加殼工具通常令人望而生畏。因為不光分析流程很難理解,並且分析過程中往往也伴隨著大量的垃圾資訊。
正因為如此,我們想分享我們在處理分析這類惡意軟體時出現的一些問題。並且這篇文章也將演示如何使用開源免費工具解壓當今最常見的dropper部署的惡意軟體。
參考樣本是:509aa4a846c6cb52e9756a282de67da3e8ec82769bceafa1265428b1289459b3
靜態分析
樣本概述
首先,看看我們正在處理的APK。
圖1:APK中包含的檔案
這個樣本顯然就比較可疑,比如MawmjulbcbEndsqku ^ nd.cml檔案是個什麼鬼?
我們先從bash命令開刀,看看能不能處理這個檔案,然而並沒有檢測到任何檔案型別。接著我們再試圖通過hex editor去開啟檔案(但我們實際上使用了radare2,它是一個很好用的開源逆向工程框架),不過最後還是無法確定此檔案的型別。
圖2:hex檢視下的MawmjulbcbEndsqku ^ nd.cml
列的內容和名稱看起來像是隨機字元,這可能是主應用程式使用的加密檔案。
也許通過Android Manifest,我們才能獲得我們想得到的資訊。
Android Manifest
AndroidManifest.xml是一個Android二進位制XML檔案,其中包含有關該應用程式的大量資訊,包括:
·應用程式的軟體包名稱,可以在裝置上訪問
· 應用程式使用的活動、服務和接收器的完整列表(如果未在此處宣告,以後將無法使用它們)
· 完整的許可權列表
· 執行期間使用的意圖過濾器的完整列表
· 其他通常不那麼重要的東西,比如使用的圖示等。
我們首先注意到的就是完全隨機的字串組成了該應用程式所有元件的名稱。這是一種惡意意圖的標識,但合法的應用開發人員也會使用它來使競爭對手更難以對其產品進行逆向工程。
接著引起我們注意的一件事是:除了應用類com.asgradc.troernrn之外,yeSACsSs檔案中沒有宣告Android元件(活動、接收方和服務類)。這樣很奇怪:宣告不存在的類並跳過現有的類有什麼用呢?
現在很明顯的一個事實是,這個APK載入了額外的外部程式碼。此外,考慮到請求的許可權的數量和性質(比如請求傳送SMS訊息),我們可以相當肯定這段程式碼沒有任何用處。
圖3:AndroidManifest SMS過濾器
逆向脫殼工具
有許多免費工具可將APK反編譯成可讀程式碼,包括:
· Apktool:獲取類的SMALI表示
· dex2jar:將.dex檔案轉換為jar存檔,可以使用jd-gui進行分析
· jadx:將java中的所有程式碼反編譯成方便的GUI
我個人最喜歡用的是jadx,但多些選擇也不錯,因為在極少數情況下,只有部分工具能夠反編譯程式碼。
所以我們接下來開始分析jadx上的APK。然而,事情並不如我想象中那麼順利……
圖4:脫殼工具的應用程式類
在真正的脫殼過程中,我們遇到了許多無用的垃圾資訊:無意義的字串、無意義的計算、無意義的函式。我們花了一段時間來嘗試理解執行流程:如果加密檔案要解密,那麼它要麼需要呼叫某個加密庫,要麼擁有自己的解密例程。一旦解密完成,就需要使用某種類載入器物件載入新檔案。
不幸的是,APK匯入檔案中沒有包含這些庫。APK中包含的內容是允許檔案間接呼叫任何已載入庫的Reflection方法。然而,再一次,這些反射方法引數也是使用無數無法理解的函式動態建立的。
很明顯靜態分析不能解決這個問題。我們必須轉而找尋新方法了。
動態分析
谷歌有提供所有Android版本中sdk下載,可以通過Android Studio建立模擬器。這是一種測試惡意軟體的完美方式,不會有被感染的風險。
因此,我們首先使用Marshmallow 6.0模擬器獲取此示例並通過adb(Android Debug Bridge)安裝了APK。如果APK要載入新的可執行檔案,裝置的內建記錄器(在我們的例子中是模擬器)應該能夠獲取到。
我們運行了連線到系統記錄器的adb命令,並且只選擇了包含我們的dropper包名的那些行:
$ adb logcat | grep "com.jgnxmcj.knreroaxvi"
然後我們啟動了應用程式。在很多雜亂的輸出中,我們終於找到了我們一直在尋找的東西:
10-25 17:12:11.001 24358 24358 W dex2oat : /system/bin/dex2oat --runtime-arg -classpath --runtime-arg--instruction-set=x86 --instruction-set-features=smp,ssse3,-sse4.1,-sse4.2,-avx,-avx2 --runtime-arg -Xrelocate --boot-image=/system/framework/boot.art --runtime-arg -Xms64m --runtime-arg -Xmx512m --instruction-set-variant=x86 --instruction-set-features=default --dex-file=/data/user/0/com.jgnxmcj.knreroaxvi/app_files/rzwohkt.jar --oat-file=/data/user/0/com.jgnxmcj.knreroaxvi/app_files/rzwohkt.dex
APK確實建立了一個新的.dex檔案。很好,我們只需要獲取此檔案,就不需要逆轉dropper了。
但問題又來了,當我們嘗試抓取該檔案時,我們無法在/data/user/0/com.jgnxmcj.knreroaxvi/app_files中找到它。顯然許多惡意軟體編碼器的創作者通常會在使用後清理了它們。所以我們面臨的下一個問題是,如何阻止dropper刪除檔案?
讓我向您介紹這個完美工具:FRIDA。
FRIDA是一個非常棒的檢測工具包,它允許在應用程式執行期間連線Javascript程式碼,還可以修改函式、欄位等等。
在這種情況下我們想要做的是阻止應用程式刪除rzwohkt.jar檔案,以便我們可以將它拉到我們的機器上進行分析。
使用FRIDA的過程一般是這樣的:我們的MO將先找到負責刪除的類,然後勾住類函式並跳過它。但是,我們不想再次重複靜態分析的狀況,所以使用動態分析來跳過這部分。
我們只有找出哪個系統呼叫被用於刪除執行,我們才能繞過它。不管在混亂的程式碼中呼叫是在哪裡進行的,如果我們在系統中鉤住了正確的本機函式,那麼應該能夠檢索所需的有效負載。
使用Strace
接下來的一個重要問題是,我們怎麼才能找到正確的函式呢?幸運的是,有一種簡單的方法可以獲得執行期間發生的所有函式呼叫的完整列表。
Strace是一個很棒的Linux實用工具,它能讓使用者獲得程序和Linux核心之間所有互動的完整報告,並且Android支援它,所以它是我們的理想工具。
圖5:Strace的輸出結果
FRIDA程式碼
最後,我們獲得了所需的所有信息。現在是時候建立我們的FRIDA鉤子了。
首先,根據所使用的架構,我們需要在移動模擬器上執行正確的frida-server。
既然我們有了連線FRIDA程式碼的方法,現在要做的就是建立指令碼,鉤住unlink()函式並跳過它。為此,我們使用了Interceptor.replace(目標,替換)方法,它允許我們替換目標處的函式,並用了Module.findExportByName(module,exp)獲取指向函式的指標,如果模組名稱未知,null可以作為模組傳遞(但會影響速度)。
console.log("[*] FRIDA started"); console.log("[*] skip native unlink function"); // create a pointer to the function in the module var unlinkPtr = Module.findExportByName(null, 'unlink'); Interceptor.replace(unlinkPtr, new NativeCallback(function (){ console.log("[*] unlink() encountered, skipping it."); }, 'int', []));
現在,每當呼叫unlink()函式時,FRIDA將攔截呼叫並執行我們的程式碼。在這種情況下,它只會輸出一個記錄器字串,並通知我們已經跳過了呼叫。
最後,我們只需要將指令碼附加到應用程式程序裡。所執行的dropper_startup.py是一個快速啟動應用程式的python指令碼,我們接著將FRIDA指令碼附加到frida-server。
圖6:FRIDA輸出
但在前幾次執行過程中,unlink()也同樣會對相應檔案進行刪除操作。最後,在二次取消連結後,我們能夠執行:
$ adb pull /data/user/0/com.jgnxmcj.knreroaxvi/app_files/rzwohkt.jar
併成功獲取了檔案——一個包含classes.dex有效負載的jar存檔。
結論
Android惡意軟體的發展日新月異,其架構就像更成熟的Windows惡意軟體一樣,也在往復雜化的趨勢前進。Droppers只是部署有效負載的一種確實有效的方式。隨機字串和無意義函式的確很容易欺騙AV引擎,但是,使用以下簽名可以保護Fortinet客戶端免受這些因素的影響:
Dropper:Android / Agent.CHG!tr Payload:Android / Agent.ARL!tr
FortiGuard Labs將對這些惡意軟體活動保持持續監控。
此部落格中使用的所有指令碼都可以在FortiGuard Lion github頁面上找到。
IOC/">IOC:
Packer: 509aa4a846c6cb52e9756a282de67da3e8ec82769bceafa1265428b1289459b3
Payload: 4fa71942784c9f1d0d285dc44371d00da1f70f4da910da0ab2c41862b9e03c89