laoxinse如题,sleep作为一个最经典的延迟执行反沙箱技术,是现在的大多数沙箱一检测到 sleep 函数,会直接跳过,加速或不去执行 sleep,用来对抗我们的反沙箱技术
POC概念如下:
//定义函数指针typedef void (NTAPI* pNtDelayExecution)(IN BOOLEAN Alertable,IN PLARGE_INTEGER DelayInterval);//旧的pNtDelayExecution pOldNtDelayExecution = (pNtDelayExecution)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtDelayExecution");//新的void NTAPI myNtDelayExecution(BOOLEAN Alertable, PLARGE_INTEGER DelayInterval){MessageBoxA(0,"检测到川哥想使用Sleep绕过沙箱","愚蠢的行为",0);pOldNtDelayExecution(Alertable, 0); //使延迟为0,基本上睡眠无效}void setHook() {if (MH_Initialize() == MB_OK){MH_CreateHookApi(L"ntdll.dll", "NtDelayExecution", myNtDelayExecution, reinterpret_cast<void**>(&pOldNtDelayExecution));MH_EnableHook(MH_ALL_HOOKS);}}void UnHook(){if (MH_DisableHook(MH_ALL_HOOKS) == MB_OK){MH_Uninitialize();}}void main() {//setHook();Sleep(3000);printf("hello laoxinsec.com");}
有鉴于此。我们可以通过自封装一个"sleep"的手段进行bypass:
基本原理:
KUSER_SHARED_DATA 结构是一个系统内核和用户模式(当然是只读模式)共享的结构,其中包含 Windows 操作系统存储在内存地址中的各种系统参数,该地址自 Windows NT 以来在 Windows 版本中保持不变,位于内存地址(0x7ffe0000),我们可以从用户空间访问该地址。值得注意的是,可以在此结构中的 +0x14 偏移处检查系统时间。
在上面的屏幕截图中看到的那样,SystemTime 成员属于_KSYSTEM_TIME类型。我们可以dt此类型来了解我们需要做什么。
虽然可以读取_KSYSTEM_TIME结构的所有三个组件以实现系统时间的完整读取,但要开发MySleep,我们实际上只需要读取 LowPart 和 High1Time。
制作计时器
利用迄今为止获得的知识来制作一个概念验证
unsigned long long __get_timestamp(){const size_t TICKS_PER_SECOND = 10000000; // A tick is 100ns.LARGE_INTEGER time;time.LowPart = *(DWORD*)(KSHARE_DATA_ADDRESS + 0x14); // Read LowPart as unsigned long.time.HighPart = *(long*)(KSHARE_DATA_ADDRESS + 0x1c); // Read High1Part as long.return (unsigned long long)((time.QuadPart) / TICKS_PER_SECOND);}void main() {printf("获取时间戳:%un", __get_timestamp());}
执行代码,可以从KUser_Shared_Data结构中读取并观察到一个递增值,该值反映了每秒的时间变化
Ok,现在我们可以增加一些计时器逻辑让我们的程序进入睡眠状态,而无需调用任何 WinAPI 或 Native API!!!
unsigned long long __get_timestamp(){const size_t TICKS_PER_SECOND = 10000000; // A tick is 100ns.LARGE_INTEGER time;time.LowPart = *(DWORD*)(KSHARE_DATA_ADDRESS + 0x14); // Read LowPart as unsigned long.time.HighPart = *(long*)(KSHARE_DATA_ADDRESS + 0x1c); // Read High1Part as long.return (unsigned long long)((time.QuadPart) / TICKS_PER_SECOND);}void main() {unsigned long long startTime = __get_timestamp();unsigned long long sleeptime = 10; //休眠10秒while (sleeptime > (__get_timestamp() - startTime)) {}//do something......such as payload()?}
此外,KUser_Shared_Data结构包含一些更有趣的东西,可以用它们来获取系统信息,而无需与 Windows API 交互,将在https://www.laoxinsec.com/站点发布继续探讨。
参考链接:https://www.legacyy.xyz/defenseevasion/windows/2022/07/04/abusing-shareduserdata-for-defense-evasion-and-exploitation.html
https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntexapi_x/kuser_shared_data/index.htm
https://www.vergiliusproject.com/kernels/x86/windows-10/22h2/_KUSER_SHARED_DATA
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/measure-command?view=powershell-7.4
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……




还没有评论,来说两句吧...