盧濤,李紅軍
摘要:木馬程序設(shè)計最主要的工作是將功能代碼實現(xiàn)隱藏,我們可以采用遠程線程技術(shù),通過動態(tài)鏈接庫方法,借助遠程線程將木馬作為線程隱藏在其他進程中,從而達到隱藏的目的。
關(guān)鍵詞:進程; 木馬; 動態(tài)鏈接庫
中圖分類號:TP393文獻標(biāo)識碼:A文章編號:1009-3044(2010)11-2612-02
1 概述
Windows系統(tǒng)平臺上提供了有效的編程和運行環(huán)境,可以將獨立的程序模塊創(chuàng)建為較小的DLL(Dynamic Linkable Library)文件,同時可對這些DLL文件功能模塊進行單獨編譯和測試。在運行時,只有當(dāng)EXE程序確實要調(diào)用這些DLL模塊的情況下,系統(tǒng)才會將它們裝載到內(nèi)存空間中。此方式不僅減少了EXE文件的大小和對內(nèi)存空間的需求,而且使這些DLL模塊可以同時被多個應(yīng)用程序使用。Microsoft Windows自己就將一些主要的系統(tǒng)功能以DLL模塊的形式實現(xiàn)。例如IE中的一些基本功能就是由DLL文件實現(xiàn)的,它可以被其它應(yīng)用程序調(diào)用和集成。
在windows系統(tǒng)中,WS2_32.DLL是使用標(biāo)準(zhǔn)的動態(tài)鏈接庫來加載服務(wù),然后通過加載的服務(wù)來實現(xiàn)系統(tǒng)功能,并調(diào)用WSPStartup來初始化。WSPStartup是Windows Socket 2的初始化函數(shù),也就是入口函數(shù),通過指定參數(shù),來實現(xiàn)提供應(yīng)用程序所期望的協(xié)議信息,然后我們可以獲得所保存的系統(tǒng)服務(wù)提供者的DLL名稱和路徑,加載系統(tǒng)服務(wù)后,可以查找到自己所要加載DLL的相關(guān)信息, 進而調(diào)用系統(tǒng)的各個服務(wù)提供者函數(shù)。在數(shù)據(jù)傳輸服務(wù)提供者的實現(xiàn)中,我們需要兩個程序,一個是可執(zhí)行文件用來安裝傳輸服務(wù)提供者;另一個就是DLL形式的數(shù)據(jù)傳輸服務(wù)提供者。
2 基本原理
DLL木馬的實現(xiàn)原理是:程序員在DLL程序中包含木馬功能相關(guān)的代碼,隨后在目標(biāo)主機系統(tǒng)中選擇特定進程,以某種方式強行執(zhí)行進程,并且調(diào)用包含木馬功能的DLL,最終使木馬功能代碼得到執(zhí)行,從而達到侵襲目標(biāo)系統(tǒng)的目的。由于DLL程序自身的特點決定了以這種形式加載木馬不僅可行,而且具有良好的隱藏性:
1) DLL程序被映射到宿主進程的地址空間中,可以共享宿主進程的資源,在目標(biāo)主機的級別進行非法訪問,獲取相應(yīng)的系統(tǒng)資源;
2) DLL程序沒有獨立的進程地址空間,可以避免在目標(biāo)主機中留下痕跡,從而達到隱蔽自身的目的。
在每個操作系統(tǒng)中都有系統(tǒng)網(wǎng)絡(luò)服務(wù),它們是在系統(tǒng)啟動時自動加載,而且很多是基于IP協(xié)議的。若程序設(shè)計者編制一個IP協(xié)議的傳輸服務(wù)提供者,并安裝在服務(wù)提供者數(shù)據(jù)庫的最前端,系統(tǒng)網(wǎng)絡(luò)服務(wù)就會加載我們的服務(wù)提供者。如果將木馬功能代碼嵌入到服務(wù)提供者的DLL文件之中,在啟動系統(tǒng)網(wǎng)絡(luò)服務(wù)時我們的木馬程序也會被啟動。這種形式的DLL木馬只須被安裝一次,而后就會被自動加載到可執(zhí)行文件的進程中,還有一個特點就是它會被多個網(wǎng)絡(luò)服務(wù)加載。通常在系統(tǒng)關(guān)閉時,系統(tǒng)網(wǎng)絡(luò)服務(wù)才會結(jié)束,所以我們的木馬程序同樣可以在系統(tǒng)運行時保持激活狀態(tài)。
我們可以將自已的木馬以線程方式注入遠程進程之中,遠程進程則是合法的用戶程序,這樣用戶管理者看到的只是合法進程,而無法發(fā)現(xiàn)木馬線程的存在.從而達到隱藏的目的。
3 動態(tài)鏈接庫木馬的實現(xiàn)
若DLL木馬實現(xiàn)了隱藏,我們在任務(wù)管理器中是看不到木馬“進程”,它完全溶進了系統(tǒng)的內(nèi)核。DLL木馬可以注入其它進程的方法為遠程線程插入,遠程線程插入技術(shù)指的是通過在另一個進程中創(chuàng)建遠程線程的方法進入那個進程的內(nèi)存地址空間。將木馬功能以DLL的形式實現(xiàn)后,需要使用插入到目標(biāo)進程中的遠程線程將該木馬DLL插入到目標(biāo)進程的地址空間,即利用該線程通過調(diào)用Windows API LoadLibrary函數(shù)來加載木馬DLL,從而實現(xiàn)木馬對系統(tǒng)的侵入。
DLL木馬功能代碼程序注入到系統(tǒng)中必須涉及到一個非常重要的Windows API函數(shù) CreateRemoteThread。與之相比所習(xí)慣使用的CreateThrea函數(shù)只能在進程自身內(nèi)部產(chǎn)生一個新的線程,而且被創(chuàng)建的新線程與主線程共享地址空間和其他資源;而CreateRemoteThread則不同,它可以在另外的進程中產(chǎn)生線程。CreateRemoteThread函數(shù)中的參數(shù)hProcess用于指定要創(chuàng)建線程的遠程進程,其函數(shù)原型為:
HANDLE CreateRemoteThread(
HANDLE hProcess, //遠程進程句柄
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId);
線程函數(shù)的代碼不能位于我們用來注入DLL木馬的進程所在的地址空間中,也就是說,我們不能想當(dāng)然地自己寫一個函數(shù),并把這個函數(shù)作為遠程線程的入口函數(shù);不能把本進程的指針作為CreateRemoteThread的參數(shù),因為本進程的內(nèi)存空間與遠程進程的不一樣。
我們可以將已經(jīng)編制好的木馬功能代碼編譯為DLL文件,然后將此DLL木馬注入程序,也就是將其注入到系統(tǒng)正在運行的系統(tǒng)進程中去,其實現(xiàn)步驟如下:
3.1 打開遠程進程
hRemoteProcess = OpenProcess(
PROCESS_CREATE_THREAD | //允許創(chuàng)建線程
PROCESS_VM_OPERATION | //允許VM操作
PROCESS_VM_WRITE, //允許VM寫
FALSE, dwRemoteProcessId );
3.2 計算DLL路徑名需要的內(nèi)存空間
int cb = (1 + lstrlenW(pszLibFileName)) * sizeof(WCHAR);
pszLibFileRemote = (PWSTR) VirtualAllocEx( hRemoteProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
3.3將DLL的路徑名復(fù)制到遠程進程的內(nèi)存空間
iReturnCode = WriteProcessMemory(hRemoteProcess, pszLibFileRemote, (PVOID) pszLibFileName, cb, NULL);
3.4 計算LoadLibraryW的入口地址
PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
3.5 啟動遠程線程,通過遠程線程調(diào)用用戶的DLL文件
hRemoteThread = CreateRemoteThread( hRemoteProcess, NULL, 0, pfnStartAddr, pszLibFileRemote, 0, NULL);
3.6 等待遠程線程退出
WaitForSingleObject(hRemoteThread, INFINITE);
4 總結(jié)
DLL木馬注入進程進行隱藏的技術(shù)和方法有很多,而且這一技術(shù)發(fā)展也相當(dāng)快,本文僅從一個側(cè)面加以討論,希望通過這一探討讓我們對DLL木馬注入進程隱藏技術(shù)有一個更清楚的認(rèn)識,同時也為我們防范他人利用進程手段非法入侵提供參考。
電腦知識與技術(shù)2010年11期