很多安全软件都靠挂钩SSDT中的函数来检测恶意代码,就拿卡巴举例吧,他挂了NtCreateKey来检测注册表的创建,NtCreateThread和NtResumeThread/NtWriteVirtualMemory来检测远程注入, 等等,这些钩子让我们后期的动作很可能暴露,怎么样才能为所欲为呢?
我这里提一种方案:
1. 首先在用户态读取NTOSKRNL.EXE,找出原始的SSDT的位置,提交到内核驱动中,内核保存起来以便使用
2. 在用户态勾住Ntdll中的NtCreateThread,
3. 当调用NtCreateThread,直接将NtCreateThread的参数以及SSDT索引号通过DeviceIoControl传递到自己的驱动中,在自己的驱动手动压栈并根据对应的SSDT索引号来调用相应的函数,最后将返回值传递到应用层, 这个只是针对NtCreateThread的特例,其他的可以照搬, 不过不用担心必须针对任何一个函数都要在驱动做特定的措施,可以写个通用的,这个就自己想办法了,我倒是早就实现了一个,不过感觉有点黄and暴力,就不贴代码了.
经过我们这番处理之后,流程的变化我简单描述一下:
干净的系统创建线程的流程:
CreateThread->NtCreateThread->(2000通过int 2e进入内核)->原始的SSDT表中的NtCreateThread->
安装安全产品后的创建线程的流程:
CreateThread->NtCreateThread->(2000通过int 2e进入内核)->被挂钩的SSDT表中的NtCreateThread(这里安全软件开始检测)->原始的SSDT表中的NtCreateThread->
经过我们处理后的流程:
CreateThread->NtCreateThread->(通过DeviceIoControl进入内核)->直接调用原始的SSDT表中的NtCreateThread->
可能有人说那还不如直接恢复SSDT来的痛快, (那还不被发现了哦! 呵呵,要低调低调)