设为首页收藏本站
查看: 3587|回复: 0

[翻译]规避技术: 拦截

[复制链接]
  • TA的每日心情
    开心
    2022-1-9 18:41
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2021-9-12 16:53:11 | 显示全部楼层 |阅读模式
    备注
    原文地址:https://evasions.checkpoint.com/techniques/hooks.html
    原文标题:Evasions: Hooks
    更新日期:2021年6月1日
    此文后期:根据自身所学进行内容扩充
    因自身技术有限,只能尽自身所能翻译国外技术文章,供大家学习,若有不当或可完善的地方,希望可以指出,用于共同完善这篇文章。

    目录
    • 拦截检测方法
    • 1. 检查系统功能中是否设置了拦截
    • 2. 通过鼠标拦截检查用户的点击中是否存在特定字符串
    • 2.1. Windows Vista+
    • 识别标志
    • 反制措施
    • 归功于
    拦截检测方法
    这里描述的技术利用拦截来检测用户的存在,或者作为检查是否安装了一些不寻常的主机操作系统拦截的手段。
    1. 检查系统功能中是否设置了拦截
    恶意软件在特定地址读取内存,以检查Windows API函数是否被拦截。
    这种方法是基于这样一个事实,即仿真环境最有可能钩住这些功能,以便能够在伪装期间收集数据和统计数据。
    要检查的常用函数:
    • ReadFile
    • DeleteFile
    • CreateProcessA/W
    通过以下函数读取内存:
    • ReadProcessMemory
    • NtReadVirtualMemory
    然后可以使用不同的算法进行检查:
    • 将前两个字节与\x8B\xFF(mov edi,edi)进行比较 —kernel32函数的典型出现方式。
    • 将前N个字节与\xCC-软件断点(int 3)进行比较,该断点未直接与拦截连接,但仍有可疑行为。
    • 将前N个字节与\xE9(调用)或\xEB(jmp指令)进行比较-用于重定向执行的典型指令。
    • 正在检查执行重定向的push/ret组合
      等等
    要计算每一种可能的比较是非常困难的,所以应用程序行为中不正常的一般迹象是读取操作系统库所在的内存。如果更准确地说:读取 "有趣 "的函数所在的内存。
    这篇文章解释了如何检测用户模式下的钩子并移除它们。下面的代码样本取自这篇文章
    检测拦截的样本:
    1. HOOK_TYPE IsHooked(LPCVOID lpFuncAddress, DWORD_PTR *dwAddressOffset) {
    2.     LPCBYTE lpBytePtr = (LPCBYTE)lpFuncAddress;

    3.     if (lpBytePtr[0] == 0xE9) {
    4.         *dwAddressOffset = 1;
    5.         return HOOK_RELATIVE;    // E9 jmp is relative.
    6.     } else if (lpBytePtr[0] == 0x68 &&  lpBytePtr[5] == 0xC3) {
    7.         *dwAddressOffset = 1;
    8.         return HOOK_ABOLSUTE;    // push/ret is absolute.
    9.     }

    10.     return HOOK_NONE;            // No hook.
    11. }

    12. LPVOID lpFunction = ...;
    13. DWORD_PTR dwOffset = 0;
    14. LPVOID dwHookAddress = 0;

    15. HOOK_TYPE ht = IsHooked(lpFunction, &dwOffset);
    16. if (ht == HOOK_ABSOLUTE) {
    17.     // 1. Get the pointer to the address (lpFunction + dwOffset)
    18.     // 2. Cast it to a DWORD pointer
    19.     // 3. Dereference it to get the DWORD value
    20.     // 4. Cast it to a pointer
    21.     dwHookAddress = (LPVOID)(*(LPDWORD)((LPBYTE)lpFunction + dwOffset));
    22. } else if (ht == HOOK_RELATIVE) {
    23.     // 1. Get the pointer to the address (lpFunction + dwOffset)
    24.     // 2. Cast it to an INT pointer
    25.     // 3. Dereference it to get the INT value (this can be negative)
    26.     INT nJumpSize = (*(PINT)((LPBYTE)lpFunction  + dwOffset);
    27.     // 4. E9 jmp starts from the address AFTER the jmp instruction
    28.     DWORD_PTR dwRelativeAddress = (DWORD_PTR)((LPBYTE)lpFunction + dwOffset + 4));
    29.     // 5. Add the relative address and jump size
    30.     dwHookAddress = (LPVOID)(dwRelativeAddress + nJumpSize);
    31. }
    复制代码
    解除拦截函数的样本:
    1. // Parse the PE headers.
    2. PIMAGE_DOS_HEADER pidh = (PIMAGE_DOS_HEADER)lpMapping;
    3. PIMAGE_NT_HEADERS pinh = (PIMAGE_NT_HEADERS)((DWORD_PTR)lpMapping + pidh->e_lfanew);

    4. // Walk the section headers and find the .text section.
    5. for (WORD i = 0; i < pinh->FileHeader.NumberOfSections; i++) {
    6.     PIMAGE_SECTION_HEADER pish = (PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(pinh) +
    7.                                  ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));
    8.     if (!strcmp(pish->Name, ".text")) {
    9.         // Deprotect the module's memory region for write permissions.
    10.         DWORD flProtect = ProtectMemory(
    11.             (LPVOID)((DWORD_PTR)hModule + (DWORD_PTR)pish->VirtualAddress),    // Address to protect.
    12.             pish->Misc.VirtualSize,                        // Size to protect.
    13.             PAGE_EXECUTE_READWRITE                         // Desired protection.
    14.         );

    15.         // Replace the hooked module's .text section with the newly mapped module's.
    16.         memcpy(
    17.             (LPVOID)((DWORD_PTR)hModule + (DWORD_PTR)pish->VirtualAddress),
    18.             (LPVOID)((DWORD_PTR)lpMapping + (DWORD_PTR)pish->VirtualAddress),
    19.             pish->Misc.VirtualSize
    20.         );

    21.         // Reprotect the module's memory region.
    22.         flProtect = ProtectMemory(
    23.             (LPVOID)((DWORD_PTR)hModule + (DWORD_PTR)pish->VirtualAddress),    // Address to protect.
    24.             pish->Misc.VirtualSize,                        // Size to protect.
    25.             flProtect                                      // Revert to old protection.
    26.         );
    27.     }
    28. }
    复制代码

    2. 通过鼠标拦截检查用户的点击中是否存在特定字符串
    这项技术由这个链接描述(第4页,第7页)。

    恶意软件设置鼠标拦截来检测点击(或更多)如果它发生。如果是这样的话,恶意软件会将主机视为一个常规的主机,即最终用户在屏幕后面,而不是虚拟环境。如果没有检测到鼠标点击,那么很可能是一个虚拟环境。
    使用的函数:
    • SetWindowsHookExA/W (WH_MOUSE_LL, ...)
    • GetAsyncKeyState
    代码样本 (SetWindowsHookExA):
    1. HHOOK g_hhkMouseHook = NULL;

    2. LRESULT CALLBACK mouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
    3. {
    4.   switch (wParam)
    5.   {
    6.   case WM_MOUSEMOVE:
    7.     // ...
    8.     break;
    9.   case WM_NCLBUTTONDOWN:
    10.     // ...
    11.     break;
    12.   case WM_LBUTTONUP:
    13.     UnhookWindowsHookEx(g_hhkMouseHook);
    14.     CallMaliciousCode();
    15.     ExitProcess(0);
    16.   }
    17.   return CallNextHookEx(g_hhkMouseHook, nCode, wParam, lParam);
    18. }

    19. g_hhkMouseHook = SetWindowsHookEx(WH_MOUSE_LL, mouseHookProc, GetModuleHandleA(NULL), NULL);
    复制代码

    代码样本 (GetAsyncKeyState):
    1. std::thread t([]()
    2. {
    3.   int count = 0;
    4.   while (true)
    5.   {
    6.     if (GetAsyncKeyState(VK_LBUTTON) || GetAsyncKeyState(VK_RBUTTON) || GetAsyncKeyState(VK_MBUTTON))
    7.     {
    8.       if (++count == 2)
    9.         break;
    10.     }
    11.     Sleep(100);
    12.   }
    13.   CallMaliciousCode();
    14. });
    15. t.join();
    复制代码
    识别标志
    没有为这个规避组提供识别标志,因为很难在以某种规避技术为目标的代码和 "合法使用 "的代码之间做出区别。
    反制措施
    • 与函数拦截检查:设置内核模式钩子;第二个解决方案是使用堆栈路由来实现函数拦截。
    • 与通过拦截进行的鼠标点击检查相比:使用鼠标移动伪装模块。

    归功于
    归功于0x00sec.org论坛的用户dtm。

    由于Check Point名为InviZzzible的工具采用了模块化的代码结构,因此需要更多的空间来展示这个工具的代码样本,以达到相同的目的。这就是为什么我们决定在整个百科全书中使用其他伟大的开源项目作为例子。

    评分

    1

    查看全部评分

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    红盟社区--红客联盟 

    Processed in 0.058309 second(s), 22 queries.

    站点统计| 举报| Archiver| 手机版| 黑屋 |   

    备案号:冀ICP备20006029号-1 Powered by HUC © 2001-2021 Comsenz Inc.

    手机扫我进入移动触屏客户端

    关注我们可获取更多热点资讯

    Honor accompaniments. theme macfee

    快速回复 返回顶部 返回列表