在這篇文章中,我們將會跟大家討論目前惡意軟件在隱藏其Windows API訪問痕跡時所采用的常用技術。在本文所給出的分析樣例中,為了確定惡意軟件的功能,分析人員必須計算要計算出API的起始地址并對運行時進程進行符號解析。
在介紹完這些技術之后,我們會給大家演示一款我們自行開發的開源工具,在IDA腳本的幫助下,它可以對虛擬機中正在運行的進程進行符號解析操作。這樣一來,它便給我們提供了一種能夠快速提升反匯編代碼可讀性的有效方法。
技術分析
在執行一次分析時,我們通常可以看到惡意軟件會嘗試掩蓋(通過模糊處理等技術)它所要使用的API。作為一名惡意軟件分析人員,如果想要確定待分析的惡意軟件會使用哪一個API,首先我們要做的就是對其進行符號解析,這樣才能確定惡意代碼真正的功能。
在這篇文章中我們所要討論的兩種常見的混淆技術為Encoded Function Pointer Tables和Detours Style Hook Stubs。在這兩種場景中,API的入口點是無法直接從源代碼中找出來的。
比如說,請大家先看下面這張圖片中的代碼,這部分代碼來自于xdata加密勒索軟件樣本C6A2FB56239614924E2AB3341B1FBBA5的內存數據中提取出來的:

在上面這張圖片中,我們可以看到一個數字值被加載進了eax,然后再與另一個數字值進行異或運算,最后作為一個函數指針被加載調用。需要注意的是,這些數字值只有在一個正在運行的進程中才有意義。我們可以根據內存導出數據中的這些數字值來計算出最終的數字結果,但我們還需要想辦法弄清楚這個特定進程中所解析的API地址。除此之外我們還要考慮到,首選基地址沖突或開啟了ASLR的系統都將有可能引起DLL重定位。
下面這張圖片中顯示的是數字值的初始化設置地址:

在我們此次的分析場景中,初始值是通過一次API哈希查詢來完成加載的,這樣一來,我們現在就有很多種方法可以來解決目前所面臨的問題了。我既可以搜索一個公開的哈希列表,然后提取出其中的哈希值來構建一個我們自己的數據庫,或者也可以想辦法對已解碼的API地址進行動態解析。
在我們真正開始之前,讓我們先來看一看另外一個例子。下圖所顯示的代碼來自于Andromeda樣本(3C8B018C238AF045F70B38FC27D0D640):

上圖所示的是惡意軟件注入在內存中的代碼,我們可以看到其中的第一個指令是從實際的Windows API中竊取來的,并存儲在一個stub之中。在這種情況下,惡意軟件可以通過這些stub訪問所有的API。我們也可以從反匯編代碼中看到,竊取來的指令是可變長度的指令。
為了對這些功能函數進行深入解析,我們需要完成以下幾個步驟:
1.枚舉出所有的stub;
2.計算第一條指令占有多少個字節;
3.提取出jmp地址;
4.減去竊取來的指令所占字節,得到API的入口點(entrypoint);
5.對計算出來的地址進行解析,找出指定的進程實例;
6.將stub重命名為有意義的值;
在這個例子中,我們嘗試搜索了相關值的交叉引用,但并沒有得到什么有意義的結果,F在我們面臨的主要是兩個問題:首先,我們如何才能更好地對計算出的API地址進行解析?;其次,如何才能將解析數據與我們的IDA數據庫聯系起來或添加進數據庫中?
我們所嘗試的第一種技術首先要計算出所有的最終地址,將它們寫入到代碼文件中,然后將數據注入到進程中,最后在下圖所示的調試程序中檢查數據表。由于調試程序中已經有一個API地址查詢表了,所以我們可以更加方便快速地得到我們所需要的信息。

這樣一來,我們就可以提取出相關的符號解析然后通過一個腳本來將其整合進我們的IDB中。
我們的工具
我們真正要做的是為每一個進程構建一個我們自己的符號查詢表,并通過我們的腳本來將這類表的訪問操作流程化。那么現在首先需要解決的問題是:我們如何才能構建出API地址的查詢表?為了解決這個問題,我們可以按照以下步驟進行操作:
1.枚舉出一個進程所加載的所有DLL;
2.對于每一個DLL,遍歷輸出表并提取出函數名和RVA;
3.根據DLL基地址計算出API的入口地址,然后提取出RVA;
4.根據上述所有信息構建出一個查詢表;
雖然上述步驟聽起來好像很麻煩的樣子,但我們已經給大家提供了能夠自動完成上述操作的代碼庫了。下面這張圖片展示的是我們針對這種特殊場景所開發出來的一款遠程查詢工具。

為了充分釋放這種類型的工具所能帶來的便捷性,這種工具必須具備高效性。那么我們怎樣才能更好地訪問這些數據呢?以下幾個因素是我們需要考慮的,例如數據如何提交、工具可接受的是哪種輸入格式、以及工具如何更好地整合到我們的分析過程之中。
我們首先得考慮如何與該工具進行交互。為了最大程度地實現靈活性和可擴展性,我們可以選擇下面這三種方法:
1.查詢請求通過textbox單獨提交;
2.查詢請求通過批量文件提交;
3.查詢請求通過網絡和遠程客戶端提交;
對于輸入格式,我們可以選擇以下幾種:
1.十六進制內存地址
2. 不區分大小寫的API名稱
3.dll_name@ordinal4.dll_name.export_name
工具的輸出是一個CSV列表,其中包含有地址、名稱、序數和DLL。雖然該工具的基本功能已經足夠強大,但是在我們的分析過程中,我們仍然需要一種更加高效的方法來使用這款工具。該工具雖然可以很好地處理單獨的查詢請求和測試,但對于批量查詢還不能夠很好地支持。批量文件查詢有時是非常方便的 ,但它需要將數據輸出/導入與IDA數據庫進行整合。
實際上,我們真正需要的是在IDA中運行我們的腳本,計算API地址,然后在IDA腳本的運行過程中解析這些地址,它將允許我們在進程的運行過程中對函數和指針進行重命名。為了實現這個目標,我們可以在IDA Jscript中整合一個網絡客戶端。IDA Jscript是一款開源的IDA腳本工具,它具備語法高亮、智能感知、函數原型提示工具和調試器等組件。

在這個例子中我們可以看到,腳本解碼了xdata指針表,通過網絡對API地址進行了解析,然后生成了一個IDC腳本并在IDA中對指針進行了重命名。運行該腳本之后,反編譯輸出結果的可讀性大大增加了。

接下來,讓我們回到剛才Andromeda的那個例子。我們可以通過下圖所示的idajs腳本恢復出惡意軟件所使用的API相關信息。

注:對于IDAPython用戶,推薦使用一款python遠程查詢客戶端。
總結
本文對惡意軟件常用的Windows API模糊技術進行了分析,由于這些技術的存在,使得惡意軟件分析人員必須提取出程序的運行時數據,計算出入口地址,然后將特定運行進程中提取出的數據解析成可讀性較高的數據。除此之外,本文還介紹了一款簡單的開源工具,這款工具可以整合多種IDA腳本語言,并允許分析人員繞過惡意軟件所使用的模糊技術。
【工具下載】
|