Abstract
Keywords
Citation Yao Qing-sheng.简单认识 Anti-RootKit (ZT).FUTURE & CIVILIZATION Natural/Social Philosophy & Infomation Sciences,20240324. https://yaoqs.github.io/20240324/jian-dan-ren-shi-anti-rootkit-zt/

转载自 简单认识 Anti-RootKit (ZT)

from:http://www.debugman.com/read.php?tid=646

现在 RK(rootkit)和 ARK (anti- rootkit) 的斗争已经进行了很久,在印象中最早出来的 ARK 工具是冰刃 (IceSword),从冰刃开始出来到现在 RK 和 ARK 的斗争一直在继续, 目前冰刃还是在流行当中,自己感觉也正是冰刃的出来才带动了当前流行的 RK 和 ARK 的斗争 呵呵,现在很多病毒木马已经广泛的带有驱动,使用一些 RK 的技术和方法使自己更底层些更强大些,当前流行的 ARK 工具主要包括:隐藏进程检测,内核驱动检 测,SSDT 检测,代码 HOOK 检测,注册表隐藏的检测,隐藏文件的检测等一些功能的,下面谈谈自己对一些功能的简单愚见 嘻嘻。

关于进程检测:其实最早在 R3 下隐藏进程的方法已经很早开始流行起来被用到各种软件上来,在 R0 下如断 ActiveProcessLinks 链,擦掉句柄表等等,一步步的发展渐渐的更强大起来一些技巧和方法开始出来和流行起来,如 FUTO,phide_ex 等。。。。。。

检 测隐藏进程的方法可以把一些现在流行的方法组合起来用,首先可以通过进程的 EPROCESS 结构中的进程活动链表 ActiveProcessLinks 来 进行扫描一边,可以通过进程句柄表的枚举通过 EPROCESS 的 HANDLE_TABLE,HANDLE_TABLE 结构中的 HandleTableLis 链表来扫描一边来获得一些 EPROCESS,可以通过定位 PsLookupProcessByProcessId 代码中的 PspCidTable 链表扫描一边获得一些 EPROCESS,PspCidTable 在各系统中枚举是不太一样的,也可以通过先找出 KiWaitInListHead,KiWaitOutListHead 和 KiDispatcherReadyListHead 这些链表然后对这些链表扫 描获得一些 EPROCESS,以上具体的实现代码可以 GOOGLE 之网上实现的代码已经很多了,再者也可以找到内核中的线程切换 SwapContext 函 数进行 HOOK 下的,在自己实现的 SwapContext 函数根据线程的偏移量找出进程的 EPROCESS 结构,把上面获得的所有 EPROCESS 汇集起 来还需要判断下当前进程是否是真正的活着的:)可以通过 EPROCESS 里的标志位 Flags(如 XP 下 0x248)一些标志判断下的,还要注意下对上面这些链表汇集起来是会有重复的进程的,在你自己的汇集函数中根据 EPROCESS 判断下的 废话了,感觉实现了上面的一些方法对付一般的隐藏进程已经足够了的,但厉害的 RK 还是有的,现在存在可以逃过这些方法的 RK 的,在进程 EPROCESS 的 结构里偏移 0x1f8(XP SP2 下)有个 struct  MMSUPPORT Vm 结构:

struct _MMSUPPORT
{
/* off 0x00000000 */    union LARGE_INTEGER    LastTrimTime;
/* off 0x00000008 */    struct  MMSUPPORT_FLAGS    Flags;
/* off 0x0000000C */    unsigned long    PageFaultCount;
/* off 0x00000010 */    unsigned long    PeakWorkingSetSize;
/* off 0x00000014 */    unsigned long    WorkingSetSize;
/* off 0x00000018 */    unsigned long    MinimumWorkingSetSize;
/* off 0x0000001C */    unsigned long    MaximumWorkingSetSize;
/* off 0x00000020 */    struct _MMWSL*    VmWorkingSetList;
/* off 0x00000024 */    struct LIST_ENTRY    WorkingSetExpansionLinks;
/* off 0x0000002C */    unsigned long    Claim;
/* off 0x00000030 */    unsigned long    NextEstimationSlot;
/* off 0x00000034 */    unsigned long    NextAgingSlot;
/* off 0x00000038 */    unsigned long    EstimatedAvailable;
/* off 0x0000003C */    unsigned long    GrowthSinceLastEstimate;
};

在这个结构里 + 0x24 有个    WorkingSetExpansionLinks 他也是个 LIST_ENTRY 链表的,遍例下他可以获得进程的 EPROCESS 的,如
PEPROCESS eprocess, eprocess2
eprocess =PsGetCurrentProcess();
lp=(PLIST_ENTRY)(*(PVOID )((PUCHAR)eprocess+0x1f8+0x24+4));
cur =lp->Flink;
for(;cur!=lp;cur=cur->Flink)
{
eprocess2=(PEPROCESS)((ULONG)cur-0x1f8-0x24);
PVOID session= (PVOID)(*(PULONG)((PCHAR) eprocess2+ 0x170));
if(MmIsAddressValid(session)){
AddProcess(eprocess2);
}
}

再 者在进程 EPROCESS 的结构里偏移 0x0b4(XP SP2 下)存在个 struct _LIST_ENTRY    SessionProcessLinks 结构,他也是个链表的 :)通过遍例他也可以的获得一些 EPROCESS。还有个地方可以的 呵呵 在每个线程对象里(ETHREAD)偏移 0x34 里有个 struct _KAPC_STATE ApcState 结构的在_KAPC_STATE 结构里偏移 0x10,再者也可以通过遍例内存来查找隐藏进程,从内存 MmSystemRangeStart 开始到 System 进程的 EPROCESS 地址就可以了主要是判断这个地址是否是个有效的进程,方法挺多的如判断下是否是进程对象这个地址如果是 EPROCESS 看看 PID,ThreadListHead,ReadyListHead 是否正确有效的等等,很多方法的应该组合起来判断下保证肯定是进 程就可以了,还可以通过 HOOK 一些函数的如 KeUpdateRunTime,KeDispatchInterrupt 等来检测隐藏进程,还可以设置下 PsSetCreateProcessNotifyRoutine 在每次进程创建的时候对线程插入个 APC 的来进行统计检测的,其实我觉得对于检测隐藏进 程的方法技巧还有很多,伟大的 WINDOWS 还需要我们挖掘呀。进程的结束可以通过调用 ZwTerminateProcess 或者调用未公开的 PspTerminateProcess 函数的,关于这个函数在网上已经很广泛了,可以通过遍例进程的每个线程调用 PspTerminateThreadByPointer 的结束每个线程的,这些未公开的函数都需要事先的查找和定位的,还可以使用 RKU (RkUnhooker)的内存清零大法的切换到该进程然后对该进程内存清零 RtlZeroMemory,再者也可以对该进程的每个线程插入 APC 来结束 进程的,最后如果你有时间你也可以通过观看 2K 的代码自己来实现进程的结束。

内核驱动检测首先你可以通过 ZwQuerySystemInformation 的 SystemModuleInformation 功能号来枚举内核驱动的,然后可以通过打开目录对 象,进行枚举代码就略了 GOOGLE 之吧,也可以通过枚举 IoDriverObjectType 和 IoDeviceObjectType 对象类型进行查找 枚举顺便把他们的 DeviceObject 和 AttachedDevice 等也枚举下吧,接着可以通过查找 PsLoadedModuleList 对该链进 行下枚举的,可以对这个目录对象再搜索一边的”\\Driver”。通过对上面这些方法的枚举可以查找到很多驱动对象了,相信现在你的驱动对象链表已经够 多了 嘿嘿,够累吧,接下来,你可以对上面你已经查找到的驱动对象的 0x38 偏移 MajorFunction 查找一边看看他的地址是否在已知的驱动地址范围内, 如不在你知道该怎么办的,再对 MajorFunction 里的每个例程地址找一边的从 0 到 28 也看看他们的地址是否在已知的驱动地址范围内,最后再说一种 的方法的,也可以像进程那样内存枚举的,像进程那样从 MmSystemRangeStart 开始枚举吧,判断下是否是 PE 文件有没有那几个关键 PE 特征 的,如 MZ,PE 等,看看是否存在 PE 文件头是否有效,看看这个地址是否已经是你检测出来的驱动地址的,避免重复的,看看你所检测出来的所有驱动对象的 MajorFunction [X] 和 DriverStartIo 是否有在这个地址,如果有并且这个地址你先前没有检测出来没有重复的他很有可能是个未知的 驱动的,其实和进程内存查找一样的,关键是判断的,需要判断对的,肯定他是某个对象的然后你就可以把他加如到你自己的某个链表里。最后也可以通过对一些关 键函数的 HOOK 如 ExAllocatePool,ExAllocatePoolWithTag 等在自己实现这些函数里记录下 esp+0x24 地址的,对这些地址进行判断 的来看看这些地址是否包含在某些内核模块当中当然还需要判断下他是否就是个 PE 驱动文件,这种方法就是 RKU 用到的方法的。驱动就说这些吧。

前面说得太多了,后面说少点吧 嘿嘿。

关于 SSDT HOOK 的检测,通过定位 ntoskrnl.exe 磁盘文件里 KeServiceDescriptorTable 与内存中的 KeServiceDescriptorTable 对各个服务函数进行比较就可以的。代码网上很多的。

关 于代码 HOOK 检测,我也不想说什么的,可以对内存中 ntoskrnl.exe 的导入函数和导出函数与磁盘文件中的地址进行比较,也可以通过对 ntoskrnl.exe PE 文件里的某些节(section)进行扫描的,再加上对一些关键文件的导入函数和导出函数进行扫描,加上对某些关键驱动(如文件系统驱动)的 MajorFunction 里的每个例程进行扫描,再者对 IDT,GDT 扫描下的。

关于注册表隐藏的检测,首先可以用到把一些注册表相关 的函数 INLINE HOOK 的 SSDT HOOK 的都恢复下再使用的其实所谓的不相关的也需要 UNHOOK 下的,如 badrkdemo 他就 HOOK 了 ObOpenObjectByName 函数组织对注册表的访问的 具体的看情况来吧 哈哈,也可以通过对一些未公开的函数进行使用的 CM 系列函数的,再者可以通过分析 HIVE 文件的来显示注册表各个项的,通过分析 HIVE 文件其实也不是很 难的,了解了 HIVE 文件结构和 HIVE 文件的组织的,就可以读他了,这些资料网上可以找到的,通过读 HIVE 文件来给用户显示当前注册表各个项的可以的 但我并不推荐自己改写系统的 HIVE 文件的,如提供 DELETE MODIFE 等功能的我觉得如改的不好,或结构没有完全清楚的,写到 HIVE 文件里是错误的,那么当再次启动时系统读 HIVE 文件时就不好过了,自己一点 愚见,如果你够强大当然是没有问题的。

关于隐藏文件的检测,现在流行的隐藏文件的 RK 很多的,如 Unreal.A,AK922 等,自己可 以通过在驱动中自己构建 IRP 包自己发送给文件驱动的方法的,还有就是先恢复些关键函数的,像注册表那样的,恢复 INLINE HOOK SSDT HOOK,文件驱动关键例程 HOOK 的,现在流行 HOOK 内核的完成例程的,HOOK 是防不胜防的,还要注意下附加在文件系统上的一些过滤驱动的,还有就 是通过使用 DeviceIoControl 发送一些特殊的 IoControlCode 控制代码给文件系统的,这需要对文件系统的熟悉的,还有就是自己分析 磁盘文件的对 FAT32,NTFS 等格式文件系统自己分析来查找文件的,关于自己分析磁盘文件的,网上的信息和资料也是很多的,首先判断下属于哪个文件系 统,然后根据特定的文件系统格式自己分析的就可以的,其实这些方法的关键是怎么读和写的,读和写做到最底层,把读和写做好我想他检测文件功能是强大的。

够 了,一些 ARK 的功能说到这就可以了,我希望各位搞 RK 的和 ARK 的人看了之后又会作出很多厉害,强大的东西来,希望看了之后会对各位有一点帮助的,希望 可以在当前流行的 RK 和 ARK 中会有更新更强大的东西出现的,来激励我们学习和前进的,引用一位好友的话 “现在感觉大部分木马病毒什么的都是用的老一套东 西的什么 SSDT HOOK 的。。。。。。,希望可以有些新的技术出现的”,其实现在有些 RK 是很牛的,其实都是一个目标的 希望技术和知识可以不断进步的 嘿嘿。一个没有未来的人:)谈谈关于 RK 和 ARK 未来的发展 RK 更底层,ARK 也更底层,攻和防,RK 和 ARK 的斗争会继续的,RK 会出现固化在某个文件里,会在重装系统后还会存在,会写到硬件中。。。。。。,ARK 势必也需要对这些问题关注的。

谢谢各位看完文章的,本人一介小菜知识有限,以上是自己的一点愚见,如有什么错误和不足之处,请各位指教。

本文之中的有些知识是朋友和一些牛人给予帮助,谢谢他们的帮助。

作者:single
2007-10-19

References