Check Point的研究人員最近發現了一種名為FluHorse的新型惡意軟件。該惡意軟件具有幾個模仿合法應用程序的惡意安卓應用程序,其中大多數安裝量超過100萬次。這些惡意應用程序竊取受害者的憑據和雙因素身份驗證(2FA)代碼。 FluHorse針對東亞市場的不同領域,並通過電子郵件進行傳播。在某些情況下,第一階段攻擊中使用的電子郵件屬於知名對象。惡意軟件可以在數月內不被發現,這使其成為一種持久、危險且難以發現的威脅。
其中一個惡意軟件樣本在3個月後仍未在VirusTotal(VT)上檢測到
攻擊者使用規避技術、模糊處理和執行前的長時間延遲等技巧來躲過虛擬環境的檢測。通常,這些技巧都有自定義實現,需要開發者付出大量的努力。
令人驚訝的是,FluHorse內部沒有使用自定義實現的技巧,因為惡意軟件的開發者在開發過程中完全依賴開源框架。儘管一些應用程序部分是用Kotlin創建的,但惡意功能是用Flutter實現的。 Flutter是一個開源的用戶界面軟件開發工具包,由谷歌創建。它用於為各種平台開發跨平台應用程序,包括用於移動設備的Android和iOS,使用單個代碼庫。 Flutter之所以成為惡意軟件開發人員的一個有吸引力的選擇,是因為它使用自定義虛擬機(VM)來支持不同的平台,而且它易於創建GUI元素。此外,由於自定義的虛擬機,分析此類應用程序非常複雜,這使得該框架成為Android網絡釣魚攻擊的完美解決方案。
模擬應用程序攻擊者會為每個國家的目標開發一個虛假應用程序:攻擊者努力仔細模仿所有關鍵細節,以避免引起任何懷疑。
網絡釣魚讓我們看一下如何在應用程序的不同變體中實現網絡釣魚,有趣的是,惡意應用程序不包含任何東西,除了為受害者提供輸入可能性的幾個窗口副本。沒有添加額外的函數或檢查。這種刻意的簡單性讓我們得出結論,惡意軟件的開發者並沒有在他們創建的編程部分投入太多精力,又或者他們可能故意做出這個決定,以進一步減少被安全解決方案檢測到的機會。
不管他們的意圖是什麼,這個計劃都很有效。受害者輸入敏感數據後,這些數據會被洩露到CC服務器。與此同時,惡意軟件要求受害者在“處理數據”時等待幾分鐘。在這一步中,短信攔截功能發揮作用,將所有傳入的短信流量重定向到惡意服務器。如果攻擊者輸入被盜憑證或信用卡數據,然後被要求輸入雙因素身份驗證(2FA)代碼,這也會被攔截。網絡釣魚方案如下:
惡意軟件如何進行網絡釣魚攻擊
請注意,根據惡意應用程序的類型(針對電子收費、銀行或約會用戶),可能不需要憑據或信用卡號。
感染鍊和目標在受害者的設備上安裝惡意應用程序之前,必須先發送惡意應用程序。這就是電子郵件誘餌派上用場的地方。我們追踪了不同類型惡意應用程序的感染鏈,並在這些電子郵件的收件人中發現了多個知名對象,包括政府部門和大型工業公司的員工。
電子郵件誘餌很好地利用了社會工程,並與隨後安裝的惡意APK的所謂目的一致:支付通行費。
這是一個帶有fetc.net.tw-notice@twfetc.com發件人地址:
攻擊者發送給政府接收者的電子郵件示例
攻擊者使用的惡意fetc-net[.]com域與fetc公司的官方網站fetc.net.tw非常相似。
在這個惡意網站上,攻擊者添加了一個額外的保護層,以確保只有受害者才能下載APK:如果目標的用戶代理與預期的用戶代理匹配,就會下載APK。此檢查是通過客戶端JavaScript執行的:
惡意軟件安裝完成後,需要短信權限:
ETC APK請求SMS權限
在此步驟中獲得的權限將在受害者輸入敏感數據後生效。
惡意電子收費APK此應用程序僅包含3個窗口:
惡意ETC APK按順序顯示的窗口
第一個窗口詢問用戶憑證,第二個窗口詢問信用卡數據。所有這些敏感數據都被洩露到惡意的CC服務器。接下來,第三個窗口要求用戶等待10分鐘,因為“系統繁忙”。希望用戶關閉應用程序,或者至少在合理的時間內不被懷疑。當用戶被“系統繁忙”消息誤導而產生虛假的安全感時,攻擊者會執行所有必要的操作,即攔截所有帶有2FA代碼的短信,並利用被盜數據。
這個誘餌應用程序的整個GUI看起來像是原始ETC應用程序的一個簡單副本,用於收取通行費。以下是惡意和合法應用程序入口窗口的可視化比較:
原始輸入窗口(左)和惡意APK輸入窗口(右)
原始應用程序不顯示任何用於登錄或輸入用戶憑據的字段。相反,有一個單獨的窗口用於此目的:
原始應用程序登錄表格
惡意VPBank APK此應用程序僅包含2個窗口:
惡意VPBank APK按順序顯示的窗口
其原理與其他惡意APK相同:要求用戶輸入憑據,然後等待15分鐘(而惡意ETC APK則為10分鐘)。在此期間,惡意軟件攔截所有傳入的SMS,從而為攻擊者提供他們可能需要的所有2FA代碼。請注意,此應用程序不要求提供信用卡詳細信息。
惡意和合法應用程序登錄窗口之間的比較:
原始登錄窗口(左)和惡意APK輸入窗口(右)
如上所示,即使缺少某些GUI元素,惡意副本看起來也很好。
惡意約會APK約會應用程序不包含任何窗口。相反,它實際上充當了一個瀏覽器,引導用戶進入釣魚約會網站。但是,竊取和處理數據的原理是一樣的。
我們沒有與受害者交互的所有步驟的屏幕截圖,因為在撰寫本文時,負責處理從該APK竊取的數據的惡意服務器尚未激活。根據代碼,只有信用卡數據被盜,不需要憑證。
APK中顯示的釣魚交友網站窗口
所示消息的翻譯如下:
網絡釣魚網站上顯示的消息翻譯。
技術細節與分析純Android應用程序相比,分析基於flutter的應用程序需要一些中間步驟才能達到目的。
深度分析如上所述,Flutter使用自定義的虛擬環境來支持具有單一代碼庫的多平台開發。開發過程中使用了一種名為Dart的特定編程語言。分析Flutter平台代碼變得更容易了,因為它是一個開源項目,但仍然是一個繁瑣的過程。
Flutter Github頁面中的Dart演示
讓我們來看看在處理Flutter運行時的特殊領域時遇到的一些複雜情況。我們用哈希2811f0426f23a7a3b6a8d8b7e1bcd79e495026f4dcdc1c2fd218097c98de684解剖了一個APK。
ARM的Flutter運行時使用自己的堆棧指針寄存器(R15)而不是內置的堆棧指針(SP)。哪個寄存器用作堆棧指針在代碼執行或反向工程過程中沒有區別。然而,這對反編譯器來說有很大的不同。由於寄存器的使用不規範,會生成錯誤且難看的偽代碼。
啟動惡意軟件分析的一個好方法是確定與CC服務器的通信協議。這可以說明很多惡意功能。裡面有一個字符串,對應於我們在釣魚電子郵件中看到的網站:
惡意APK中字符串中CC服務器的地址
然而,當我們試圖找到對此字符串的一些引用時,分析失敗:
IDA中沒有對CC服務器字符串的引用
我們的目標是創建對該字符串的引用,以定位執行CC通信的代碼。
Flutter -re-demo和reFlutter可以用來處理Flutter應用程序,其主要思想是使用運行時快照來創建Dart對象並查找對它們的引用。 reFlutter的主要目的是收集函數的名稱,而flutter re-demo允許我們處理在應用程序執行期間收集的內存轉儲。
然而,除了內存快照之外,還需要一些更多的運行時信息。 Flutter運行時使用堆來創建對象,並將指向已創建對象的指針存儲在一個稱為對像池的特殊區域中。指向該池的指針被傳遞到寄存器X27中的方法。我們需要找到對像池的位置。
flutter-re-demo使用Frida收集內存轉儲並獲取對像池地址。如果我們使用在flutter-re-demo存儲庫中可用的dump_flutter_memory.js腳本運行APK,我們會看到所需的地址:
帶有所需地址的Frida腳本輸出
現在我們已經擁有了開始一個高效的逆向工程所需的所有元素。
在用map_dart_vm_memory.py加載轉儲文件並運行create_dart_objects.py腳本後,我們現在至少可以看到一些對象:
腳本創建的對象
有一個名為create_dart_objects.py的腳本,用於創建dart對象。該腳本通過遍歷對像池、解析記錄和創建對象來工作。腳本沒有關於這些對象的信息,腳本會為它們創建以下描述對象格式的結構:
這裡的NNN被“class id”取代,如下所示:
由create_dart_objects.py創建的結構
在Flutter應用程序逆向工程時,研究人員注意到最後一個字段(unk)經常被用作指針。可以考慮將該字段從簡單的QWORD轉換為OFFSET QWORD。這可能會給帶來一些誤報,但也可能非常有助於創建參考。因此,我們決定更改由腳本創建的unkin結構的字段類型。以下是對原始腳本的更改:
對dart_obj_create.py腳本的更改
研究人員提到的存儲庫包含一個用於創建對Dart對象引用的腳本:add_xref_to_art_objects.py。當運行它時,該腳本會遍歷代碼並創建對create_Dart_objects.py腳本創建的Dart對象的引用。不過此時仍然只有一個對我們感興趣的字符串的引用,即來自對像池的引用:
沒有對CC服務器URL的引用
我們的第一個想法是,也許根本沒有交叉引用?不過這不可能,存在幾個交叉引用,例如,這個對象就具有引用:
幾個從函數到對象的引用
這是從函數中引用的對象:
引用在函數代碼中的外觀
通過瀏覽add_xref_to_dart_objects.py的代碼,我們可以看到文件dart_obj_xref.py。該文件還遍歷代碼,嘗試根據寄存器X27提取對數據的引用,計算這些引用的偏移量,最後創建IDA引用。對代碼的分析表明,原始腳本支持訪問該對象的兩種ARM代碼變體:
代碼是否使用了一些其他指令來引用寄存器X27?讓我們檢查一下。為了方便起見,讓我們修改腳本,並為用X27處理的每條指令添加一條註釋:
dart_obj_xref.py修改
然後,我們可以檢查用X27處理的結構的反彙編程序列表,這些構造沒有附加對Dart對象的註釋引用。我們可以通過IDA生成一個列表文件並使用grep實用程序進行grep,從而部分自動化這些操作,如下所示:
首先,grep查找具有X27的所有字符串。然後,所有這些字符串都給了第二個grep命令,只打印那些不包含對Dart對象引用的字符串。因此,我們只看到不受支持的X27引用。
當檢測到不受支持的X27構造時,我們將在腳本中添加支持該構造的代碼。經過幾次迭代,我們終於獲得了對CC地址字符串的引用:
對CC地址字符串的引用
讓我們從sub_70FD611C0C開始檢查這些函數。簡要概述顯示,當與CC服務器通信時,此函數打算使用路徑為“/addcontent3”的HTTP POST方法來執行:
sub_70FD611C0C函數的偽代碼
另一個Dart對像也有對這個函數的引用:
對Dart對象的引用
當我們遍歷這些引用時,我們最終得到了帶有以下代碼的函數:
負責監聽所有傳入短信的代碼
此函數為所有傳入的短信安裝一個偵聽器。
為了確保我們做了正確的靜態分析,我們在運行時在一個真實的設備上檢查了這個函數。實際上,我們捕獲了一個發送到CC服務器的POST請求。
這是設備收到帶有“Fdsa”文本的短信後的CC請求示例:
因此,使用sub_70FD611C0C函數將短信洩露到CC服務器
除了被洩露的數據類型和服務器路徑之外,函數sub_70FD61EBC4和sub_70FD61EECC看起來與已經分析的sub_70FD 611C0C非常相似。這些函數分別使用路徑“/addcontent”和“/addcontent2”,用於洩露受害者的憑據和支付卡信息。
DEX代碼中沒有服務器通信的痕跡,因此我們可以假設所有通信都位於應用程序的Flutter部分。在分析了與命令控制服務器通信相關的所有功能之後,我們可以描述網絡協議。
CC通信CC協議旨在將數據從受攻擊設備發送到服務器。沒有命令可以在相反的方向上發送,即從服務器發送到受攻擊設備。 HTTPS用於傳輸數據,並且使用了幾個終端。
以下是我們在分析樣本中遇到的每個終端的介紹:
用於約會惡意應用程序的網絡誘餌變體使用了非常相似的協議。這是一個洩露信用卡數據的示例:
Recommended Comments