首页
论坛
课程
招聘
[翻译]Ring3/Ring0层Rootkit Hook检测技术(二)
2018-1-4 22:32 8743

[翻译]Ring3/Ring0层Rootkit Hook检测技术(二)

2018-1-4 22:32
8743

IAT挂钩

        描述

        输入地址表(IAT)是一个跳转列表,列表条目形如“jmp dword ptr ds:[address]”。由于dll文件中的函数地址会发生改变,所以应用程序将调用其自身跳转列表中的相关跳转,而不是直接调用一个dll库中的函数。当应用程序执行时,加载器会将一个指向适当位置处的所需dll函数的指针,放入IAT中。

(缺图:输入地址表)

(我并不确定这样做会有什么实际帮助)

        如果一个rootkit程序将自身注入到应用程序中,并修改IAT中的地址,那么它将能够对目标函数的每一次调用过程实施控制。

        绕过方法

        因为每个dll库的输出地址表(EAT)保持完整,因此应用程序可以通过调用GetProcAddress函数来获取每个dll函数的真实地址,从而轻松绕过IAT挂钩方法。为了防止这种简单绕过方法,rootkit可能会挂钩GetProcAddress/LdrGetProcedureAddress函数,并使用它来返回虚假地址。这种挂钩技术可以通过编写你自己的GetProcAddress函数实现代码,并使用它来获取真正的函数地址来绕过。


内部挂钩

        描述

        内部挂钩是在函数被调用时,而又在函数完成自身工作之前实施控制的一种技术。通过修改目标函数的首部几(通常是5)字节,该技术对执行流程进行重定向。标准的实现方式是,使用一条跳转到恶意代码的指令覆盖函数的前5字节,然后恶意代码就可以读取函数参数,并完成它需要完成的工作。如果恶意代码需要使用原始函数(即被挂钩的函数)的执行结果,它可以通过执行所覆盖的5字节指令,然后跳过5个字节进入原始函数,这样就可以绕过恶意的跳转/调用,从而避免无限循环/重定向。

(缺图:内部函数挂钩)

(一个通过内部挂钩跳转到恶意代码,然后执行原始函数的示例)

        绕过/检测方法(Ring3层)

        在用户模式中,内部挂钩通常置于dll库所导出的函数之中。检测和绕过这些挂钩最精确的方法,就是将每个dll库和原始代码相比对。首先,程序需要获取一个包括每个已加载dll库的列表,找到原始文件并读取,将区块载入内存并对齐,然后进行基址的重定位。在dll库的新副本载入内存之后,应用程序可以遍历输出地址表,并将每一个函数与原始dll库中的对应函数进行比对。然后为了绕过挂钩,应用程序可以使用新加载dll库中的代码来替换被覆盖的代码,或者,它可以解析新加载dll库中的导入函数,并转而使用解析结果(需要注意的是,某些dll库在加载多个实例的情况下可能无法正常工作)。

        这种绕过dll库挂钩的方法实际上包括了编写你自己的LoadLibrary函数实现代码,因此它对于新手或者胆怯的人来说并不适合。哪怕我能够编写公布用于完成这项工作的代码,我也不会这样做,因为它可能(并且必将)会被脚本小子们用来绕过用户模式的反病毒沙箱或者与其他的rootkit技术相对抗。

        (我们也可以使用手动的dll库加载技术来检测/修复EAT挂钩,我不会对这方面内容深入讲解,因为EAT挂钩技术非常不寻常)。

        绕过/检测方法(Ring0层)

        在内核模式中,模块之间的跳转很罕见。ntoskrnl中的挂钩通常可以通过反汇编每个函数中的每一条指令,然后寻找指向ntoskrnl模块外部的跳转或调用(转入驱动程序体内,等待)来进行检测。也可以使用用户模式挂钩检测中所介绍的相同方法来实现:一个驱动程序可以从磁盘中读取每一个ntoskrnl模块,将其载入内存,并将指令与原始代码相比对。

        对于驱动程序中的内部挂钩而言,扫描指向驱动程序体外部的跳转/调用指令很有可能得到假阳性结果,然而标准内核驱动内的跳转/调用以非标准驱动为目标则应该引起警惕。也可以从磁盘中读取驱动;由于驱动一般不会导出很多函数,并且IRP主函数指针只在运行时初始化,所以你可能需要对原始驱动和新驱动的整个代码区块进行比对。特别值得关注的是,相对应的调用/跳转在重定位期间很容易受影响而改变,这意味着在原始驱动和新驱动之间本来就存在不同之处,然而相对应的调用/跳转应该指向同一区域。


SSDT挂钩

        描述

        系统服务调度表(SSDT)是一个由多个Zw/Nt函数指针所组成的列表,可以从用户模式进行调用。恶意软件可以用指向其自身代码的指针来替换SSDT中的指针。

(缺图:Windows系统调用路径)

(Nt/Zw函数的调用路径示例)

        检测方法(Ring0层)

        SSDT中的所有指针都应该指向ntoskrnl中的代码,如果任何指针指向了ntoskrnl模块之外,那么它很可能被挂钩了。rootkit程序有可能在内存中修改ntoskrnl.exe(或相关模块中的一个),并将一些代码插入到一个空闲空间中,在这种情况下指针仍然指向ntoskrnl模块范围之内。就我所知,以“Zw”开头的函数会被SSDT挂钩所拦截,但以“Nt”开头的函数不会,因此应用程序可以通过对“Nt*”格式的函数地址和SSDT中的对应指针进行比对,来检测SSDT挂钩。

        绕过方法

        一个绕过SSDT挂钩的简单方法是只调用“Nt*”格式的函数而不调用对应的“Zw*”格式的函数。也可以通过加载ntoskrnl.exe来找到原始的SSDT(这可以通过在用户模式中调用LoadLibraryEx函数来轻易实现),然后找到导出的“KeServiceDescriptorTable”,并用它来计算磁盘镜像中KiServiceTable的偏移位置(用户模式的应用程序可以使用NtQuerySystemInformation函数来获取内核基址),需要一个内核驱动来替换SSDT。


SYSENTER_EIP挂钩

        描述

        SYSENTER_EIP指向使用SYSENTER指令时要执行的代码。用户模式的应用程序使用SYSENTER指令来转换进入内核模式,并调用内核函数(这些函数以“Nt/Zw”开头),它通常指向KiFastCallEntry函数,但是可能会被替换,从而实现挂钩对内核函数的所有用户模式调用。

        检测/绕过方法

        SYSENTER_EIP挂钩技术并不影响内核模式驱动,并且不能从用户模式绕过。为了让用户模式的应用程序绕过该挂钩,内核驱动程序必须将SYSENTER_EIP设置为它的原始值(KiFastCallEntry函数),这可以使用WRMSR指令来实现,然而因为ntoskrnl模块并不导出KiFastCallEntry函数,所以获取该函数地址可能会非常麻烦。


IRP主函数挂钩

        描述

        每个驱动的驱动对象都包含了一个由28个函数指针组成的列表,其他驱动可以通过IoCallDriver函数或其他可选的方法来调用这些指针,这些指针对应于诸如读/写(IRP_MJ_READ/IRP_MJ_WRITE)的操作。另一个驱动可以很轻易地替换这些指针。

        检测方法

        一般来说一个驱动的所有IRP主函数指针应该都是指向驱动地址空间内的代码,并不总是这样的,但通过检测是否将合法驱动的IRP主函数重定向到自身代码来识别恶意驱动,会是个不错的开端。

        绕过方法

        由于IRP主函数指针在驱动程序入口点处(在运行时期间)初始化,因此无法通过从磁盘中读取原始驱动来获取原始值。加载驱动的一个新副本会导致冲突,因此这种方法也不可行。我能想到的绕过这种类型的挂钩的唯一方法是,调用更底层的驱动(驱动一般是以栈的方式架构,上层驱动将数据传递给下层驱动以此类推,如果最底层的驱动没有被挂钩,那么应用程序可以直接将请求发送给最底层的驱动)。


总结

我想不出总结该写点儿啥,所以放一张一个人被海豹追赶的图片吧。:-)

(缺图:不高兴的海豹)




原文地址:http://www.pentestingexperts.com/ring3-ring0-rootkit-hook-detection-2-2/

本文由  看雪翻译小组 木无聊偶  编译

转载请注明来源


[注意] 欢迎加入看雪团队!base上海,招聘安全工程师、逆向工程师多个坑位等你投递!

收藏
点赞0
打赏
分享
最新回复 (5)
雪    币: 583
活跃值: 活跃值 (117)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
supersoar 活跃值 2018-8-12 02:13
2
0
感谢 分享 ,思路总结 好文没人回复啊
雪    币: 1764
活跃值: 活跃值 (125)
能力值: ( LV12,RANK:310 )
在线值:
发帖
回帖
粉丝
木无聊偶 活跃值 4 2018-8-13 08:18
3
0
supersoar 感谢 分享 ,思路总结 好文没人回复啊
谢谢
雪    币: 265
活跃值: 活跃值 (836)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
fengyunabc 活跃值 1 2018-8-13 11:30
4
0
感谢分享
雪    币: 583
活跃值: 活跃值 (117)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
supersoar 活跃值 2020-1-6 02:01
5
0
另外补图:
https://www.malwaretech.com/2013/10/ring3-ring0-rootkit-hook-detection-22.html
雪    币: 1764
活跃值: 活跃值 (125)
能力值: ( LV12,RANK:310 )
在线值:
发帖
回帖
粉丝
木无聊偶 活跃值 4 2020-2-22 20:55
6
0
supersoar 另外补图: https://www.malwaretech.com/2013/10/ring3-ring0-rootkit-hook-detection-22.html
感谢感谢
游客
登录 | 注册 方可回帖
返回