Author:衛士通攻防實驗室([email protected])
顧名思義,注入這種技術就是將代碼或DLL注入到另外一個正在運行的進程中,以實現隱藏自身或其他目的。常見病毒根據其需求會選擇不同的注入方式,但每種注入方式都是值得我們了解和學習的。本系列文章打算把常見病毒的注入方式分門別類地進行匯總,在每個類別中選擇一個有代表性的病毒,逆向分析該病毒的注入方式,并展示給各位讀者,以供大家學習和參考。
作為本系列的第一篇,筆者將介紹利用WriteProcessMemory()函數進行的DLL注入。作為該類注入方式的代表DesktopLayer.exe也很具有分析價值,下面開始進入正文。此外,筆者忠心希望本系列能給讀者一點啟發和幫助,但由于筆者知識有限,才疏學淺,文中不當或錯誤之處還請各位讀者包容和指正。
Name | DesktopLayer.exe |
Size | 55.00 KB (56320 bytes) |
MD5 | FF5E1F27193CE51EEC318714EF038BEF |
該病毒是近一兩年出現的,功能全面,結構合理,是個不錯的分析和學習對象。為了讓讀者更順利的進行分析和學習,筆者在2.1-2.3節逆向分析介紹了實現注入之前的代碼功能,如果對這部分不感興趣或是不打算逆向這個樣本,可以直接跳到2.4節。
樣本被加了UPX 2.90殼。UPX殼最主要的目的是減小程序的體積,其特點是較高的壓縮率和較快的解壓速率,與TMD、VMP這類殼的設計理念完全不同,這類殼更注重對代碼提供保護的殼。UPX是免費軟件,其官網上可以找到每個UPX版本的加殼程序和相應脫殼程序,網址為http://upx.sourceforge.net/。這里筆者也懶得去網上翻了,直接手動脫殼就可以了,其脫殼后的入口點模樣如下:
脫殼之后的樣本仍然壓縮了大量的代碼,深入分析之后,可以判斷為是變形UPX殼。由于UPX是開源的,所以很多同行會根據需要修改UPX的源代碼。該變型殼首先解碼UPX解碼部分的代碼,然后利用UPX的解碼代碼再次解碼惡意功能的代碼。其中,第一次解碼完成后,會跳入該地址繼續執行,該地址與3.1.1節所述的UPX代碼基本相同,等完成其解碼之后,可以再次Dump,其最終的入口點如下:
經過二層脫殼之后,會發現樣本的圖標已經改變:
圖中左側為原始圖標,右側為完全脫殼之后的圖標。
當正確地脫掉兩層殼之后,就會看到這段程序原本的模樣:
下面開始著重分析其功能,首先是獲取測試機的默認瀏覽器及其位置,其獲取方式是查找注冊表中,HKCR\http\shell\open\command
的鍵值:
在筆者分析機中,該值為:
即默認的IE瀏覽器,位置為C:\Program Files\InternetExplorer\iexplore.exe。而后會通過FindFirstFile()函數判斷是否存在該文件,即iexplore.exe:
如果不存在,那么會在幾個默認位置進行查找:
如果存在,則繼續后續操作。接下來會創建互斥體。進而,會通過GetModuleFileName()函數獲取自身執行體所在位置和文件名:
進而會將自身執行體的文件名與DesktopLayer.exe比較:
由于筆者獲取到的樣本名字是dnf_srv.exe,顯然與之不同。那么,樣本會以此判斷以下7個目錄是否可以有讀寫權限:
當找到第一個有權限的目錄是,在該文件夾下創建名為Mirosoft的文件夾。在筆者的測試機中,%HOMEDRIVE%%HOMEPATH%是有相應權限的,即會在C:\Users\zzz目錄下,創建Microsoft文件夾。并將dnf_srv.exe重命名為DesktopLayer.exe,并復制到C:\Users\zzz\Microsoft文件夾下:
此后,調用CreateProcess()創建該進程:
創建該進程之后,程序就調用ExitProcess()退出了。
此次執行一直到比較執行體名稱的位置之前,都沒有任何變化。而與DesktopLayer.exe比較之后,出現了不同行為。首先是,對ntdll.dll中的ZwWriteVirtualMemory()進行hook操作:
其操作結果為:
而后,會調用CreateProcess函數,啟動iexplore.exe進程,該進程的執行體所在位置已于上文中通過查詢注冊表方式找到:
Createprocess()函數內部會調用ZwWriteVirtualMemory()函數,從而執行其經過hook的代碼,其調用棧如下:
其中,sub_402A59即為其HookCode.
HookCode首先完成其正常的WriteVirtualMemory()函數功能:
進而,通過ReadProcessMemory()函數獲取iexplore.exe進程的內存信息:
根據讀取到的內存,可以找到后續對iexplore.exe的hook點。
然后,在自身進程內,解碼出rmnsoft.dll,手動加載,并根據導入表和重定位表進行相應的操作,最后修改頁保護等操作:
當在本地加載完之后,就會把rmnsoft.dll注入到iexplore.exe,這需要分6步進行:
第一步,將DLL寫入iexplore.exe:
特別強調的是,在iexplore.exe中申請的內存位置和本進程申請內存的位置是一樣的,這樣做的好處是:避免了在iexplore.exe的重定位操作,大大減小了代碼的復雜度。在筆者的測試機中,其基地址同為0x20010000,如圖:
第二步,將初始化導入表代碼寫入iexplorer.exe:
這里需要指出的是,代碼內容主要為對PE頭的進行操作的PIC代碼。
第三步,將修改頁保護相關代碼寫入iexplorer.exe。
該段代碼的作用是通過PE頭得到各個區段的頁保護屬性,同樣是PIC代碼。
第四步,將修復代碼寫入iexplorer.exe。
該段代碼會調用第1步、第2步、第3步寫入的代碼。在第5步中,會執行此步驟中的代碼。
第五步,將相關數據寫入iexplorer.exe。
第六步,在剛剛找到的hook點寫入shellcode,尋找hook點的相關內容見上文:
其中,shellcode內容為:BF 00 00 07 00 68 00 00 08 00 FF D7,長度為0xC。
0x70000和0x80000分別為第3步寫入的代碼基址和第4步寫入的數據基址。等程序運行到hook點時,會執行shellcode,從而跳到0x70000地址即第3步寫入的代碼繼續執行進行相關操作。
至此,完整的注入過程和方法已經分析完畢。如果對這部分不是很理解,建議閱讀和學習《程序員的自我修養》一書,該書中滿滿的全是干貨。
下面看一下iexplore.exe的執行效果如何:
執行shellcode:
然后初始化導入表:
然后,分段判斷并修改代碼的頁保護:
最后,調用DLL main:
此后,該惡意DLL會開始他的行為。
該DLL可以在其加載之前dump出來,這里就不做演示了。此外,該DLL并未有混淆或者加殼等措施,逆向起來比較輕松,這里就不做詳細分析,只做簡要介紹:
如上圖,DLL會創建5個線程,其中每個線程會實現其相應的惡意功能。
本文以病毒DesktopLayer.exe為樣本,著重介紹了利用WriteProcessMemory()函數進行DLL注入的方法,簡而言之,可以認為程序直接將所有相關的代碼和數據直接寫到被注入的進程空間中。其注入的DLL只在內存中出現,并未在硬盤中出現過。這種注入方式需要對PE結構有較好的理解,且對DLL裝載過程有很好的理解,建議不熟悉這部分內容的讀者可以閱讀和學習《程序員的自我修養》,以進一步獲得提高。
本系列會陸續介紹其他常見病毒的注入方式,希望各位讀者能夠有所收獲。