惡意軟件反調(diào)試分析的對(duì)抗技術(shù)
在本文中,我們會(huì)介紹惡意軟件如何利用一個(gè)打包的Exe原始入口點(diǎn)來(lái)欺騙結(jié)構(gòu)化異常處理程序(SEH)。
在此,我們會(huì)拿一個(gè)名為sample.exe的惡意軟件樣本進(jìn)行具體講解,首先將其加載到ExeInfo,進(jìn)行打包。
注意入口點(diǎn)是28E8,此外,我們開始調(diào)試它的時(shí)候,為了確保不被ASLR檢查到并避免稍后出現(xiàn)的動(dòng)態(tài)加載,看看DLL的特點(diǎn),就可以看到這個(gè)DLL不能移動(dòng)。
現(xiàn)在將該sample.exe示例加載到OllyDBG中,它向我們提供了一個(gè)信號(hào),即代碼可以被壓縮,以下是我們之前看到的。
一旦樣本加載到OllyDBG中,它將開始在Unpacker代碼中運(yùn)行,由于手動(dòng)逐步執(zhí)行此代碼將需要很多時(shí)間,所以我們會(huì)很可能錯(cuò)過OEP,下面就分析一下我們已經(jīng)執(zhí)行的這幾行代碼。
有一些指向SHE結(jié)構(gòu)的FS寄存器,在進(jìn)一步了解之前,需要了解Windows是如何找到FS寄存器地址的。FS寄存器指向線程信息塊(TIB),其包含有關(guān)當(dāng)前正在運(yùn)行的線程的信息,并且指向SHE鏈的起點(diǎn)的指針位于TIB的偏移量0x00處。
現(xiàn)在,我們來(lái)看看結(jié)構(gòu)異常處理程序。
單個(gè)SEH記錄由堆棧上的兩個(gè)元素組成,此過程稱為_Exception_Registration。構(gòu)成SEH記錄的兩個(gè)要素是:
1.SEH處理函數(shù);
2.PTR到下一個(gè)SEH記錄;
這樣才能形成SEH鏈結(jié)構(gòu)。
一旦代碼被加載,它將519870復(fù)制到EAX并將其推到堆棧的頂部。
我們可以看看堆棧的頂部這個(gè)推送的ESP指向14FF80。
根據(jù)SEH的上述說(shuō)明,這是處理程序函數(shù)代碼,但仍然需要由下一行代碼PUSH DWORD PTR FS:[0]完成的FS來(lái)指出。把指針指向SEH鏈的堆棧頂部,將完成SEH記錄。此時(shí)寄存器的當(dāng)前狀態(tài)如下所示。
有了MOV DWORD PTR FS:[0], ESP的說(shuō)明,代碼通過將ESP(指向記錄的頂部)移動(dòng)到FS:[0]來(lái)將新創(chuàng)建的記錄指定到SEH鏈的頂端。執(zhí)行此語(yǔ)句后,我們可以看到堆棧狀態(tài)SEH記錄的兩個(gè)元素。
我們也可以在VEH/SEH鏈中創(chuàng)建新的記錄。
但是,自從下一行代碼XOR EAX,EAX將0放入EAX后,樣本代碼應(yīng)該執(zhí)行這個(gè)SEH處理程序代碼。
然后它試圖將它寫入一個(gè)只讀位置來(lái)導(dǎo)致異常,第一個(gè)處理程序會(huì)捕獲此異常,然后執(zhí)行解包程序代碼。
此外,在執(zhí)行最后一條語(yǔ)句時(shí),將跳轉(zhuǎn)到519870(記住這是我們之前提交給EAX寄存器的地址,并且是SEH處理函數(shù)SEH記錄的一部分)。
這是隱藏打包程序代碼的一種智能技術(shù),但是我們的分析還沒有完成,因?yàn)槲覀內(nèi)匀恍枰业絆EP,從二進(jìn)制文件中解壓縮代碼并重新構(gòu)建它是很困難的。
為此,我們將嘗試通過在打開代碼之前查找打包程序通常使用的一些常見模式:
- 一個(gè)是在解碼器代碼中尋找EAX跳轉(zhuǎn)的模式,通常是跳轉(zhuǎn)到未打包的代碼;
- 一個(gè)是打包機(jī)通常在打包代碼之前清理堆棧;
因此我們應(yīng)該按照這個(gè)順序查看:清理堆棧→JMP EAX。
一旦進(jìn)入519870(SEH處理程序代碼)中,我們可以通過每個(gè)指令,也可以沿著創(chuàng)建SEH記錄設(shè)置一個(gè)斷點(diǎn)。
下面就讓我們采用沿著創(chuàng)建SEH記錄設(shè)置一個(gè)斷點(diǎn)的辦法。
由于SEH被創(chuàng)建到系統(tǒng)上,所以當(dāng)創(chuàng)建結(jié)構(gòu)時(shí),我們將一個(gè)斷點(diǎn)放在堆棧的頂部。
然后運(yùn)行樣本,它需要用到下面這部分代碼。
這與我們正在尋找的模式相匹配,讓我們來(lái)執(zhí)行JMP eax,然后看看這個(gè)代碼將會(huì)帶給我們的驚喜,如下圖所示。
由于代碼28E8看起來(lái)更簡(jiǎn)潔,我們來(lái)轉(zhuǎn)一下這個(gè)代碼。
另外,我們還需要檢查這個(gè)轉(zhuǎn)儲(chǔ)代碼是否執(zhí)行,在執(zhí)行檢查之前,請(qǐng)先建立導(dǎo)入地址表。
現(xiàn)在,我們來(lái)分析Process Hacker中exe是否正在運(yùn)行。一旦exe啟動(dòng),它會(huì)給出錯(cuò)誤的警告。
有趣的是,這只是為了糾正錯(cuò)誤信息,因?yàn)榧词乖邳c(diǎn)擊ok之后,我們也可以看到進(jìn)程中的黑客進(jìn)程正在運(yùn)行并產(chǎn)生一個(gè)進(jìn)程。
通過本文的分析,你可以看到惡意軟件的開發(fā)者是如何包裝代碼并阻止分析的。