愛伊米

從Geost到Locker:監控Android惡意軟體混淆的演變過程

趨勢科技的研究人員透過相隔近一年的Geost和Locker樣本研究了Android惡意軟體混淆方法的演變,發現該惡意軟體的開發者使用了外部混淆服務。

早在2019年,趨勢科技的研究人員研究了Geost,這是一個具有有趣的混淆層的Android木馬。透過比較2019年的發現和2020年的新樣本,本文詳細介紹了其混淆方法的演變。

本次的調查始於研究人員調查Android木馬殭屍網路的活動,他們發現攻擊者實際上正在使用外部服務進行APK混淆,而以前從未發現過這種情況。然後,他們通過了解其使用情況並發現其客戶端來詳細審查這項服務。我們在一篇論文和三篇部落格文章中分享了我們聯合調查的結果。

本文從技術方面描述了所使用的混淆方法,以及隨著時間的推移,在不同樣本中反映的混淆師程式碼的演變。如前所述,研究人員第一次分析Geost樣本是在2019年。將近一年後,作為聯合調查的一部分,研究人員分析了新的樣本。第二次,研究人員分析了三個被同一個服務混淆的應用程式:一個Locker應用程式,一個SMS竊取程式和一個廣告軟體。本文集中討論了2019年以來的Geost惡意應用程式和2020年之後的Locker混淆的應用程式之間的差異,這些差異顯示了混淆服務在大約一年內生成的程式碼的演變。

一個混淆應用程式的string 。xml檔案的摘要

從上圖中可以明顯看出,所有符號名稱都被混淆了。上面的圖還顯示了研究人員遇到的第一級混淆。有趣的是,在一個程式包中,原始類名被連續生成的字串替換,這些字串從一個字母(比如“a”到“z”)開始,到兩個字母(比如“aa”、“ab”等等)開始,程式包中的最後一個以“fm”結束。與第一階段一樣,其餘的類名稱被隨機生成的字串替換,長度範圍從6到12個字元不等。更改很可能是由服務混淆程式完成的。不過在外部混淆之前,先前惡意APK中已經存在的符號很可能已經被混淆了。

惡意Geost樣本中的字串被打亂的位元組陣列替換,事實上,這是另一個被混淆的層。在以前至少包含一個字串的每個類中插入一個反彙編方法。這個方法總是有三個引數,它們定義了反彙編演算法的引數;但是,每個方法中的引數都是隨機排序的,這使得解壓縮任務變得複雜。因此,一個反彙編Python指令碼是不夠的,必須對每個類進行修改。圖2是一個反彙編方法的示例。

從Geost到Locker:監控Android惡意軟體混淆的演變過程

一個反彙編方法的示例

鑑於第二階段的複雜性高於第一階段,因此這種方法使對第二階段進行逆向工程的任務處於同一級別。與其他惡意APK樣本相比,該方法還被證明是防止有害資訊洩漏的有效方法。

垃圾程式碼數量大大增加

從2020年年中開始,樣本中的垃圾程式碼數量明顯高於將近一年之前的Geost樣本中的垃圾程式碼數量。表1中的數字證明了這種猜測,除了少量的滴管程式程式碼更改外,垃圾類和垃圾程式碼行的數量都大大增加了。

從Geost到Locker:監控Android惡意軟體混淆的演變過程

不同滴管APK樣本的複雜度比較

加密的惡意APK檔名

在Geost示例中,加密的第二階段DEX檔案儲存在名為“。cache”的檔案中,該檔案又儲存在根APK目錄中。該檔案在解密並存儲在“ydxwlab。jar”檔案中之前,已重新命名為“。localsinfotimestamp1494987116”。在所有較新的示例中,APK根目錄中還有一個名為“tracks”的目錄,如圖3所示,該目錄包含幾個隨機命名的檔案。

從Geost到Locker:監控Android惡意軟體混淆的演變過程

“tracks”的目錄內容

小於100位元組的檔案包含隨機生成的字串,檔案“online。m3u”包含路徑“tracks / radio。ogg”。這個radio。ogg檔案包含一個加密的惡意載荷。

值得注意的是,與以前的Geost示例相比,這裡也有很小的變化,因為現在有了一個非常簡單的標頭,它是加密資料的字首。如圖4所示,此標頭包含以小尾數形式編碼的四個位元組的長度。此外,臨時解密的DEX檔案的名稱已修改為“skjoxawp。jar”。

radio。ogg檔案的標頭,其中包含後面的加密資料的長度

字串串聯方法

即使在第一階段中使用的所有字串都已加密,但出於某種原因,其中的三個字串也會被分成兩部分,然後透過一種研究人員已命名為CombineStrings的混淆方法進行連線。僅當第二個引數大於零時,此方法將第一個和第三個引數中獲取的字串連線起來。將字串拆分為“forName”,“android。app。Instrumentation”和“newApplication”。這個細節說明了混淆程式碼的開發者是如何特別小心處理這些字串的,這三個字串都用在核心函式中,該函式載入並啟動第二階段的程式碼,如圖5所示。

這段程式碼展示了特殊的combineStrings()串聯方法的用法

此時,舊示例和新示例之間的差異僅在第二個引數小於或大於零(參見圖6)的程式碼分支中才可見,這從未真正執行過。因此,改變的原因是未知的。

從Geost到Locker:監控Android惡意軟體混淆的演變過程

新舊版本的combineStrings()方法之間的差異

呼叫方法的演變

與我以前的文章一樣,部分程式碼混淆是透過用Java Reflection等效項替換某些系統方法呼叫來完成的,在此方法中,用於反射呼叫的字串引數被加密。圖7顯示了此方法的示例。

上圖是透過反射呼叫替換getDir()方法的示例,然而,字串引數已經被解密。

研究人員已將此階段命名為invokeMethod,該方法的主要任務是驗證引數並呼叫對應的類method。invoke()。在新的示例中,與Geost使用的版本相比,這種方法要複雜得多。這是滴管程式的程式碼仍在不斷髮展以及該服務背後的參與者仍在投資於程式碼開發的主要證明之一。

兩個版本在複雜性上的差異如圖8到圖11所示,圖8顯示了Geost的invokeMethod,而圖9到圖11顯示了用於Locker的相同方法的程式碼。

從Geost到Locker:監控Android惡意軟體混淆的演變過程

Geost示例中的完整invokeMethod()

從Geost到Locker:監控Android惡意軟體混淆的演變過程

新示例中使用的invokeMethod()的第一部分

從Geost到Locker:監控Android惡意軟體混淆的演變過程

新示例中使用的invokeMethod()的第二部分

從Geost到Locker:監控Android惡意軟體混淆的演變過程

invokeMethod()的新版本中使用的invocationProcess()方法

虛假標誌程式碼

在已經描述過的滴管程式碼部分中,虛假標誌程式碼可能是最不重要的。儘管如此,值得注意的是,新樣本發生了令人驚訝的變化。除了Geost示例中的HttpURLConnection類和方法符號之外,滴管中的所有字串都是加密的,符號名稱也都是被混淆的。在消除混淆之後,很明顯,程式碼的相關部分也永遠不會被執行。這可能是開發者設計的另一種轉移注意力的策略,目的是將分析師的注意力轉移到一個虛假標誌程式碼上。這個虛假標誌程式碼模仿命令和控制(C&C)開啟序列,如圖12所示。

Geost示例中的虛假標誌

這段程式碼被放置在Geost示例的invokeMethod()中,還應該注意的是,較新的示例不使用HttpURLConnection類。相反,它們使用SQLiteQueryBuilder類和其他相關方法,在deleteFile()方法中放置虛假標誌,如圖13所示。

從Geost到Locker:監控Android惡意軟體混淆的演變過程

較新示例中的虛假標誌

自動有效載荷解密

第一個階段中的所有字串以及有效載荷均使用RC4演算法進行了加密,並且解密金鑰已進行了硬編碼。所有新的和舊的分析示例也是如此,也就是說,在找到金鑰之後,這也允許指令碼化的有效載荷解密和進一步分析。

幸運的是,找到金鑰並不困難,因為有一個byte[]變數的宣告,該變數具有包含所述金鑰的立即初始化陣列值。但是,除了一個byte[]變數之外,我沒有找到另一個這樣宣告的示例。在宣告時初始化的變數陣列的其餘部分為int型別,這些大多是位元組陣列初始化文字。儘管如此,它們直接作為字串建構函式引數放置。

總結

對被自動混淆服務混淆的樣本的分析證明,該服務背後的攻擊者仍在對其改進進行努力。值得慶幸的是,程式碼中的更改似乎對混淆質量和最終檢測率幾乎沒有影響。除了滴管程式程式碼的變化之外,插入的垃圾程式碼數量顯著增加。包含有效載荷的檔案透過標頭的改變而變得豐富,這個可能是為了提高解密的可靠性或使有效載荷的解密更加複雜。有效載荷的位置和名稱也已被更改,以模仿一組audio track檔案。

儘管有這些變化,但新舊示例的特性使它們成為可能,而且很容易被解密。例如,目錄和有效負載檔案的固定名稱使得對惡意檔案的追溯變得簡單。APK資原始檔中儲存的來自惡意有效載荷的字串也使檢測和回溯更加容易,因為這些字串允許有效載荷進行分類。

然而,儘管存在這些缺陷,仍然有必要監控這種混淆服務的可能發展。被該服務混淆的數千個示例也證明了其可用性。畢竟,它很容易被使用,並且減少了檢測混淆APK的機會。透過這種方法,攻擊者成功地實現了隱藏惡意內容的主要目標。

參考及來源:https://www。trendmicro。com/en_us/research/20/l/from-geost-to-locker-monitoring-the-evolution。html