負載惡意軟體HawkEye的VB Inject樣本分析
*本文原創作者:Macc,本文屬於FreeBuf原創獎勵計劃,未經允許禁止轉載
0×01 概述
惡意軟體HawkEye的利用大多都是通過釣魚郵件分發,利用office直接啟動HawkEye主體或者一些經過加密的程式,本文中的VB Inject屬於後者,也把重心放在了除錯這個VB程式上。
檔案基本資訊如下:
項 | 值 |
---|---|
PEID | VB |
MD5 | 3e3cec381975a0c4a3a2333370ca0799 |
大小 | 684KB |
修改日期 | 2018/6/13 |
VirusTotal上的該樣本資訊:
病毒名大多為VBKrypt或者VBInject。
0×02 行為監控
將自身複製到C:\User\user\AppData\Romaing\WindowsUpdate.exe,建立C:\User\user\AppData\Romaing\pid.txt,C:\User\user\AppData\Romaing\pidloc.txt,並將WindowsUpdate.exe加入自啟動項。
用wireshark抓網路行為,發現該樣本會訪問 ofollow,noindex" target="_blank">http://whatismyipaddress.com/ ,並與yandex郵件伺服器建立連線。
0×03 反除錯
因為是個VB程式,首先就想到用VB decompile反編譯。效果如下:
似乎是沒不能看出什麼,於是來除錯一下。
步過這個call之後,會跳轉到一個錯誤指令:
想到可能是因為反除錯導致的,所以步入0x4012A1的call,然而裡面的程式碼都是模組msvbvm60的,一個比較快能定位到主程式的辦法就是通過VB decompile中顯示的地址。於是我在0x4A07D6、0x4A0BC8下斷。Form_Load中沒有什麼有用的資訊,直接斷到Form_Paint。
這裡做了一些字串的操作,直接自動步過,然後來到下面這個call:
回車進去看到有呼叫DllFunctionCall,這裡會呼叫RtlMoveMemory很多次,複製一段記憶體:
在迴圈結束的地方F4:
單步之後發現程式會在下圖位置執行起來,進入錯誤指令:
跟進後,又來到下面的call(因為其他的call都有函式名__vbaxxx),回車進入後發現這個call也呼叫了DllFuncitonCall:
呼叫了EnumWindows,這個函式一個引數是回撥函式,所以需要留意。
函式原型:
BOOL EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam );
lpEnumFunc是指向回撥函式的指標,lParam是傳遞給回撥函式的引數。
看此時棧的狀態,第一個引數位於0x12F4D8,在該處下斷。
然後F8->執行到使用者程式碼,斷到該處::
單步到後面的jmp之後跳到下面的地址:
這裡call edx之後,跳到錯誤地址,該地址正確編碼後的指令是:
地址為0x48EA92,但程式卻跳到了0x48EA93:
注意到在call之前的一條adc指令,程式在這裡加了1,導致跳轉到0x48EA93,反反除錯的話做到這裡把這條指令nop掉就可以了,不過可以看看[ebx+2]的值是怎麼決定的。
返回去看到這裡,就知道為什麼了。
fs:[esi](此時esi的值為0×18)指向自身(TEB結構),偏移為3的地址處是BeingDebugged, 0×01是被除錯中:
nop掉儲存再除錯。
0×04 執行時解密
從過了反除錯的地址0x48EA92開始:
干擾指令很多,還有一部分硬編碼。一直單步,遇到call都最好跟進,這段程式碼中的call不多:
呼叫DllFunctionCall得到EnumWindows的地址:
這裡可以直接步過:
然後出現VirtualAlloc,然後同樣DllFunctionCall得到VirtualAlloc地址,然後呼叫。
分配了記憶體1,推斷是要解密自身程式碼寫入到地址:
開始往這片記憶體寫入內容,然後跳轉到這個地址:
單步到下圖,又有一個反除錯,同樣是通過TEB讀取PEB BeingDebugged的值:
又呼叫一次VirtualAlloc分配記憶體2:
跟到下面又發現對PEB結構的訪問,偏移為0×68。
其實不太清楚偏移0×68是什麼,就查了一下:
PEB有一個名為NtGlobalFlag(偏移量為0×68)的欄位,程式可以挑戰識別它們是否正在被除錯。通常,當未除錯程序時,NtGlobalFlag欄位包含值0×0。在除錯程序時,該欄位通常包含值0×70。
此時這個值正好為0×70,所以這個je不能跳。
繼續單步跟,會呼叫很多次DllFuncitonCall,可以看到獲取了許多API的地址,如ShellExecuteW,WriteFile,CreateFile,VirtualProtect,CreateProcess等。
接下來又分配了記憶體3,地址為:
來看看分配的這三塊記憶體的狀態:
目前除了剛分配那個不能執行,其他的都可讀可寫可執行:
往記憶體0×3430000賦值:
開始解碼:
解碼完成後,有點PE頭的樣子了,只是少了標誌性的”MZ”:
呼叫GetCommandLineW,以獲取的路徑為引數建立子程序:
呼叫ZwAllocateVirtualMemory在指定程序分配記憶體:
將0x5A賦值給0×343600不完整的PE檔案,後面還會寫入’M’。
然後呼叫ZwWriteVirtualMemory寫入記憶體空間,寫入的內容地址正是0×343600。
父程序將解密出來要執行的PE寫入子程序的記憶體,然後中止當前程序。
0×05 樣本主體
在之前的行為監控中,注意到,樣本在C:\User\user\AppData\Romaing\目錄下生成了三個檔案 pid.txt,pidloc.txt,WindowsUpdate.exe。這些功能都是通過解密出來的PE實現的。樣本的VB程式碼只相當於一個外殼,執行時解密、建立子程序、注入程序等。提取出來的這個PE載入ExeinfoPE,發現這個程式是.NET Reactor型別的程式碼混淆。
這裡我用了de4dot-mod反混淆工具,不用工具直接動態除錯也可以。
去除反混淆後生成的檔案變成了528KB,原檔案大小為65512KB,用PEID開啟,可以看到匯入表只有一個動態連結庫mscoree.dll,函式是_CoreExeMain。
接下來嘗試用.NET的反編譯工具dnSpy試試。
反編譯成功後,發現該程式是惡意軟體HawkEye,用於憑據竊取,包括電子郵件Web瀏覽器,Bitcoin錢包,反病毒檢查,鍵盤記錄等。
*本文原創作者:Macc,本文屬於FreeBuf原創獎勵計劃,未經允許禁止轉載