专栏名称: Gamma实验室
Gamma实验室是专注于网络安全攻防研究的实验室,不定时向外输出技术文章以及自主研发安全工具,技术输出不限于:渗透,内网,红队,免杀,病毒分析,逆向,ctfwp等,实验室只用于技术研究,一切违法犯罪与实验室无关!
目录
相关文章推荐
跟宇宙结婚  ·  节目更新:跟宇宙结婚悄悄话 vol.249 ... ·  昨天  
跟宇宙结婚  ·  回味首映礼:2024年在《头脑特工队2》首映 ... ·  2 天前  
51好读  ›  专栏  ›  Gamma实验室

edr对抗技术1-api unhook output

Gamma实验室  · 公众号  ·  · 2024-05-11 00:17

正文

0x01 关于对抗api hook技术

auth:cmrex

文章灵感来自于:阿里云先知fdx师傅

出现场景

杀软会对敏感的api事先进行hook操作,例如:

VirtualAllocmemcpyCreateRemoteThreadEx

等诸如此类的api函数。所以就可以使用下列几种办法来对抗:

  1. syscall实现apihook绕过

  2. unhook技术

那么他们的特点分别是:

  1. 在 syscall 的时候有时候会导致堆栈不完整,在杀软看来是一些异常的行为,比如下图可以看到 RIP 指针直接已经在 Program 里面了。

  2. 通过一些办法,让我们获得一个没有被hook的ntdl。

syscall实现apihook绕过

unhook技术

重载ntdll的代码段

这里借用别人的一张图,大概是这样:因为刚开始是有一个ntdll被载入内存,然后杀软对其hook,自然也就是修改了代码段。然后这个时候,我们用新的ntdll的代码段覆盖被hook的代码段,实现ntdll重载。

  1. 将 ntdll.dll 的新副本从磁盘映射到进程内存

  2. 查找被 hook 的 ntdll.dll的 .text 部分的虚拟地址

    1. 获取ntdll.dll基址

    2. 模块基址 + 模块的 .text 段 VirtualAddress

  3. 查找新映射ntdll.dll的 .text 段的虚拟地址

  4. 获取被 hook 的 ntdll .text 段的内存写的权限

  5. 将新映射的ntdll.dll的 .text 段覆盖到被 hook 的 ntdll 的 .text 部分

  6. 还原之前被 hook 的 ntdll .text 段的内存被原本的内存权限

劣势

这种方式是最简单的并且理论上可以对所有的 dll 进行 hook,但是缺点是需要读取磁盘上的 dll,而如果杀软对读取系统 dll 的行为进行了监控,那么我们这种方式其实是不好使的。

PE 文件映射绕过 hook

如果被打开文件是PE格式,那么这个文件会按照内存展开,那么我们猜想是不是这个被第二次载入内存的ntdll是不是就是一个干净的ntdll,能不能帮助我们绕过一些inline hook。这种其实是载入第二个ntdl来绕过hook。流程:

  1. 使用CreateFileMapping->MapViewOfFile映射一个ntdll

  2. 自己实现一个GetProcAddress函数

  3. 使用自写GetProcAddress函数获取nt函数其实就是打开一个新的pe格式的ntdll,然后摄取这个ntdll里的函数直接使用。这种也会被专门设置的防止ntdll重载规则拦截。

如何使用

这里是使用了NtAllocateVirtualMemory,从新的ntdll创建的

pNtAllocateVirtualMemory NtAllocateVirtualMemory = (pNtAllocateVirtualMemory)GetProcAddressR((HMODULE)lpNtdllmaping, "NtAllocateVirtualMemory");
int err = GetLastError();
LPVOID Address = NULL; SIZE_T uSize = 0x1000;
NTSTATUS status = NtAllocateVirtualMemory(GetCurrentProcess(), &Address, 0, &uSize, MEM_COMMIT, PAGE_READWRITE);

直接跳转

我们都知道加载 dll 的函数是 LoadLibrary,这个函数在 kernel32.dll 里面,然而这个函数在 ntdll 里面对应的函数时 LdrLoadDLL,而我们这个方法的主角就是 LdrLoadDLL。 在 x64 平台下,我们去查看这个函数的汇编指令

而我们就可以自实现一个函数,汇编如下

其中第一条指令时 LdrLoadDLL 的第一条指令,我们自己实现,防止此条指令被 hook,变成 jmp 指令。

address 就是内存中 LdrLoadDLL 第二条指令的位置,在 x64 下就是 address(LdrLoadDLL)+5

mov qword ptr[rsp + 10h]  //原始的LdrLoadDll中汇编,使用我们自己的防止被hookmov r11,address     //address(LdrLoadDLL)+5jmp rllret

这样我们就自己实现了一个跳转函数,demo 代码可以参考

挂起的进程获取干净的ntdll

当一个进程还没有被运行,刚开始加载若干dll的时候,会记载没有被hook的ntdll,以及edr的dll。这个时候这里的ntdll是干净的ntdll。

没有被hook

如果是被hook了,这里会出现一个跳转,跳转到edr的dll中去。所以我们里的思路是:

  • 新挂起进程的内存是干净的,没有被 hook 的

  • 所有的系统 dll 在被加载时的内存空间都是一样的启动一个进程,挂起它,读取他的干净的ntdll,然后自己使用。

首先创建一个进程挂起

```cppSTARTUPINFOA* si = new STARTUPINFOA();PROCESS_INFORMATION* pi = new PROCESS_INFORMATION();//BOOL stat = CreateProcessA_p(nullptr, (LPSTR)"C:\\Windows\\System32\\svchost.exe", nullptr, nullptr, FALSE, CREATE_SUSPENDED, nullptr, nullptr, si, pi);BOOL stat = CreateProcessA_p(nullptr, (LPSTR)"cmd.exe", nullptr, nullptr, FALSE, CREATE_SUSPENDED | CREATE_NEW_CONSOLE, nullptr, "C:\\Windows\\System32\\", si, pi);
HANDLE hProcess = pi->hProcess;printf("PID : %d\n", pi->dwProcessId);

通过遍历进程中加载的模块来查找ntdll.dll的基地址

为此,我们使用了paranoidninja的自定义函数。这里它被命名为GetDll()

WCHAR findname[] = L"ntdll.dll\x00";PVOID ntdllBase = GetDll(findname);printf("ntdll.dll base address : 0x%p\n", ntdllBase);

我们传递要定位其基地址的DLL的名称(在本例中为ntdll.DLL),函数返回其基地址。以下是GetDll()函数的代码

PVOID GetDll(PWSTR FindName){  _PPEB ppeb = (_PPEB)__readgsqword(0x60);  ULONG_PTR pLdr = (ULONG_PTR)ppeb->pLdr;  ULONG_PTR val1 = (ULONG_PTR)((PPEB_LDR_DATA)pLdr)->InMemoryOrderModuleList.Flink;  PVOID dllBase = nullptr;
ULONG_PTR val2; while (val1) { PWSTR DllName = ((PLDR_DATA_TABLE_ENTRY)val1)->BaseDllName.pBuffer; dllBase = (PVOID)((PLDR_DATA_TABLE_ENTRY)val1)->DllBase; if (wcscmp(FindName, DllName) == 0) { break; } val1 = DEREF_64(val1); } return dllBase;}

上面的函数使用内在的__readgsqword()从gs寄存器中读取0x60字节。这将为我们提供指向PEB(过程环境块)的指针

从PEB结构中,我们可以找到Loader数据或Ldr的地址

然后,我们使用Ldr遍历加载的模块,以获得所需的ntdll基础

通过Loader数据提取加载的模块

demo

https://github.com/dosxuz/PerunsFarthttps://github.com/optiv/Freeze

0x02 api hook的不同杀软分析

天擎的hook

tq对于api的hook分析

这里研究天擎hook从何而来?首先看一个程序的dll列表:







请到「今天看啥」查看全文