WindowsRootkit进程隐藏与检测技术
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
如图 1 所示,从 API 的调用过程来看,挂钩动态连接库 ntdll.dll 中的 stub 函数比挂钩 API 更好。stub 函数和内核中 相对应的 Native API 的名字完全相同,调用的 stub 函数能实 现对同名内核函数的调用[3-4]。如图 1 中实线箭头所示,Win32 程序的调用一般会被转向到 Windows 子系统库 Kernel32.dll 中的相应函数,再被转换到 Ntdll.dll 中的 stub 的函数中,由 int 2E 或 sysenter 指令使调用陷入到内核。
EPROCESS 结构中的域 Active process link 域是一个 LIST_ENTRY 结构,它将所有进程的 EPROCESS 结构连接成 了一个双向链表。ZwQuerySystemImformation 函数通过遍历 这个链表来获取需要查询的信息。只要把需要隐藏进程的 EPROCESS 结构从链表中剥离出去,该进程就会从系统的视 线中消失。
王 雷,凌 翔
(wenku.baidu.com子科技大学通信抗干扰技术国家级重点实验室,成都 610054)
摘 要:进程隐藏是 Rootkit 技术的一种典型应用,隐藏运行的恶意代码威胁到计算机的安全。为此,通过分析 Windows 系统中利用 Rootkit 技术对进程进行隐藏的原理,针对用户模式和内核模式 2 种模式下进程隐藏技术的特点,提出几种不依赖于系统服务的隐藏进程检测技术。 此类检测方法直接利用系统底层的数据结构,检测能力强。 关键词:Rootkit 技术;进程隐藏;进程检测;系统内核
系统中的每个线程上下文的切换由内核进程中的 SwapContext 函数来实现。该函数执行时,寄存器 EDI 中存 放的是指向即将被换入的线程的指针;而寄存器 ESI 中存放 的是将被换出的当前线程的指针。利用此特点,使用内联钩 子钩住该函数,在钩子函数中验证寄存器 EDI 所指向的即将 被换入的线程的 KTHREAD[1]是否指向一个位于正常双向链 表中的 EPROCESS 结构。如果不是,则说明该进程是一个被 DKOM 隐藏的进程。
—140—
条件跳转指令。它克服了 IAT 钩子在动态链接库显式加载时 会失效的缺陷,适应能力更强。
通 常 情 况 ,用 户 态 进 程 使 用 CreateToolhelp32Snapshot 等 API 获取进程列表。Rootkit 针对这些函数设置 API 钩子, 在钩子函数中删除原始 API 返回结果中特定进程的信息实现 进程隐藏。
无论在用户模式还是内核模式,仅依靠一种技术已经不 足以将进程完美隐藏。高效的进程隐藏方案往往将 2 种模式 下的技术结合在一起,配合内核中多种数据结构,甚至利用 一些非 Rootkit 范畴的技术。例如 hook 内核 Shadow SSDT 结 构以及抹掉窗口标题等辅助隐藏手段,防止通过枚举窗口探 测进程。归根结底,进程隐藏就是要让进程隐匿在系统之中, 并在最大程度上给检测制造技术障碍。
利 用 PsGetCurrentProcess 函 数 定 位 到 System 进 程 EPROCESS 构成。然后,沿着 LIST_ENTRY 结构指向遍历整 个链表,通过 PID 等信息定位到需要隐藏的进程,将它的 EPROCESS 脱链。脱链之后,该进程的正常运行不会受到本 质的影响。但直接使用系统提供的服务已经不能够发现该进 程了。
3.1 常规检测方法 在用户态可以通过枚举进程窗口、分析进程打开的句柄
表等方法得到进程列表;而内核态列举进程有直接遍历 EPROCSS 双向链表、检查 SSDT 是否被挂钩等方法。下面 2 种是常规方案中强度较高的。 3.1.1 用户态的直接内核函数调用
如前文所述,用户态 Rootkit 通过干扰的 API 函数或者 stub 函数使得程序不能得到正确的信息。只要不通过系统在 用户态提供的函数来发送系统服务请求就能不受干扰。所谓 的用户态直接调用内核函数是指不通过 NTDLL 的帮助直接 进入内核。
一般情况下,在用户态实现进程监控最终都会调用 stub 函数 ZwQuerySystemInformation。因此,在系统上所有进程 中挂钩模块 Ntdll.dll 中的该函数就能实现进程隐藏。这种方 法不再依赖预先对目标进程所使用的 API 函数信息的获取, 适应性更强。它几乎是用户态上最有效的进程隐藏方式。
2.2 内核模式下的进程隐藏技术 Rootkit 进入内核后运行在权限最高的 Ring0 级上,拥有
同内核同等的地位,并能操作内核代码,为隐藏进程提供了 极大方便。 2.2.1 Hook SSDT
在 NT 系 统 中 , 大 多 数 系 统 服 务 都 是 在 内 核 进 程 Ntoskrnl.exe 中实现的。在 Ntoskrnl 初始化的过程中,会先为 它所提供的各种服务创建系统服务分派表(SSDT)[5]。表中的 第 1 项是系统服务的索引号,第 2 项是与索引号相对应的服 务函数在 Ntoskrnl.exe 进程空间中的地址。进程通过服务号 查找需要使用的系统服务函数。
进程 Csrss.exe 的核心是动态链接库 csrsvr.dll,几乎所有 与初始化进程相关的工作都是在其中执行的。它包含很多不 被公开的未导出符号。其中,CsrRootProcess 是一个指向结 构体 CSR_PROCESS 的指针。CSR_PROCESS 这个结构体中 的 域 ClientId 包 含 了 进 程 PID 信 息 ; 而 域 ListLink 是 LIST_ENTRY 结构。包含不同进程信息的 CSR_PROCESS 结 构通过这个域连接起来形成链表。遍历整个链表,可以得到 一份包含几乎所有进程的列表。获取未导出的符号 CsrRootProcess 的 一 种 可 行 方 法 是 利 用 导 出 函 数 CsrLockProcessByClientId,这个函数在执行中会将其值存入 寄存器 ESI 中。导出函数的入口地址可以直接得到,在此基 础上加上相应的偏移量就能读出 CsrRootProcess 的地址。
3 隐藏进程检测
在隐藏进程的检测中,一种简单而有效的思想就是做对 比:用可能被修改过的进程列表同正确的列表做对比;如果 结果不一样,那么不同之处就是存在隐藏的地方。有的文献 称这种方法为 cross-view。一般而言,用户态 API 函数得到 的进程列表可能不含部分进程。要利用对比法得出结论,最 关键的是得到正确的进程列表。
由于线程的上下文切换都要用到 SwapContext 函数,因 此只要把守住该函数就能得到真实的进程列表,找出被隐藏 的进程。 3.2 另类检测方法
进程 Csrss.exe 是 Windows 子系统进程[4]。由于每个进程 在创建初期都会通知 Windows 子系统进程以便能够进一步完 成创建工作,因此 Csrss.exe 中包含了除 Idle, System, Smss.exe 和 Csrss.exe 之外所有进程的信息(前 2 个属于内核,SMSS 是 CSRSS 的父进程)。
函数 ZwQuerySystemInformation 的服务号是 0xAD。隐 藏进程时,Rootkit 在 SSDT 中找到服务号为 0xAD 的服务函 数地址,把它替换为 Rootkit 中可过滤进程信息函数的地址。 2.2.2 直接内核对象操作
基于钩子技术的隐藏技术通常容易被检测到,而直接内 核对象操作(DKOM)技术可以在不依赖钩子的前提下,实现 对进程的隐藏。在 NT 内核的 Windows 操作系统上,每一个 进程在内核中都由内核对象 EPROCESS 结构对其拥有的地 址空间、描述符、线程等信息进行描述[4]。
图 1 显示了用户态的内核服务请求在 NTDLL 中由 int 2E 或 sysenter 指令传入内核。根据 stub 函数的工作原理,仿造 一个发起系统调用请求的函数,当需要使用系统内核服务函 数枚举进程的时候在本进程中直接使用仿造的 stub 函数发起 内核服务请求,如图 1 中虚线所示。该方法可以无视用户态 的一切 hook 得到一个完整的进程列表,对所有用户态隐藏都 有效,但只能应对少数内核态隐藏。 3.1.2 挂钩 SwapContext 函数
【Abstract】Process hiding is a typical application of Rootkit technique. Hidden malicious codes are threats to computer security. By analyzing the Windows Rootkit technology used for process hiding both in the user mode and kernel mode, this paper puts forward several hidden process detection technologies which do not depend on the system services. These detection methods directly use the underlying data structure of the system, and have relatively strong detection ability. 【Key words】Rootkit technique; process hiding; process detection; system kernel
1 概述
Rootkit 是 20 世纪 90 年代出现的一种新兴的计算机技术 技术。它是长期可靠地潜行于计算机上的一组难于检测的程 序或代码[1]。进程隐藏是 Rootkit 技术中典型的一种。它利用 代码及编程手段令特定进程的信息无法为其他进程获取。对 杀毒软件、防火墙等安全软件而言,隐藏关键进程可以排除 恶意软件的干扰,使安全防护效果更佳。同时隐藏进程也可 为计算机取证等工作带来便利。但是隐藏的进程极具危险性, 它意味着代码可以在完全不被察觉的状态下悄然运行。这样, 恶意程序可以在目标主机中长期潜伏,窃取信息而不被发现, 造成极大危害。因此,能够检测出被 Rootkit 隐藏的进程更显 得十分重要。
Win32 子系统
OS/2子系统
OS2.exe
Kernel32.dll
ntdll.dll int 0x2E (sysenter)
用户模式 内核模式
KisystemService ntoskrnl.exe
hal.dll
图 1 API 调用过程
作者简介:王 雷(1983-),男,硕士研究生,主研方向:计算机信 息安全;凌 翔,副教授 收稿日期:2009-10-15 E-mail:l_go@163.com
Process Hiding and Detection Technique of Windows Rootkit
WANG Lei, LING Xiang
(National Defense Key Lab of Anti-Interference Communication Technology, University of Electronic Science and Technology of China, Chengdu 610054)
2 Rootkit 进程隐藏技术
进程隐藏的目标是在保证特定进程正常运行的前提下使 其信息不能被进程监控软件列举出来。用户模式 Rootkit 通过 修改工作在用户态的可执行文件和链接库达到隐藏目的;内 核模式 Rootkit 一般是以驱动程序的形式载入内核,通过对内 核数据的修改实现隐藏。 2.1 用户模式下的进程隐藏技术
第 36 卷 第 5 期 Vol.36 No.5
计算机工程 Computer Engineering
2010 年 3 月 March 2010
·安全技术·
文章编号:1000—3428(2010)05—0140—03 文献标识码:A
中图分类号:TP316
Windows Rootkit 进程隐藏与检测技术
受运行权限的限制,用户模式实现进程隐藏主要依赖的 是钩子(hook)技术[2]。Rootkit 通过设置钩子,钩住进程监控 软件所调用的某些函数,并篡改这些函数的返回结果,特定 进程的信息将不被察觉。
按 照 实 现 方 式 钩 子 可 分 为 导 入 地 址 表 (IAT) 钩 子 和 内 联 钩子(Inline Hook)2 类。IAT 钩子通过注入目标进程空间的代 码对内存中目标进程 PE 格式[3]进行分析,找到并替换 IAT 中目标 API 函数的地址为钩子函数的地址。而内联钩子通常 直接把目标函数的前 5 个字节改写为一个转向钩子函数的无
EPROCESS 结构中的域 Active process link 域是一个 LIST_ENTRY 结构,它将所有进程的 EPROCESS 结构连接成 了一个双向链表。ZwQuerySystemImformation 函数通过遍历 这个链表来获取需要查询的信息。只要把需要隐藏进程的 EPROCESS 结构从链表中剥离出去,该进程就会从系统的视 线中消失。
王 雷,凌 翔
(wenku.baidu.com子科技大学通信抗干扰技术国家级重点实验室,成都 610054)
摘 要:进程隐藏是 Rootkit 技术的一种典型应用,隐藏运行的恶意代码威胁到计算机的安全。为此,通过分析 Windows 系统中利用 Rootkit 技术对进程进行隐藏的原理,针对用户模式和内核模式 2 种模式下进程隐藏技术的特点,提出几种不依赖于系统服务的隐藏进程检测技术。 此类检测方法直接利用系统底层的数据结构,检测能力强。 关键词:Rootkit 技术;进程隐藏;进程检测;系统内核
系统中的每个线程上下文的切换由内核进程中的 SwapContext 函数来实现。该函数执行时,寄存器 EDI 中存 放的是指向即将被换入的线程的指针;而寄存器 ESI 中存放 的是将被换出的当前线程的指针。利用此特点,使用内联钩 子钩住该函数,在钩子函数中验证寄存器 EDI 所指向的即将 被换入的线程的 KTHREAD[1]是否指向一个位于正常双向链 表中的 EPROCESS 结构。如果不是,则说明该进程是一个被 DKOM 隐藏的进程。
—140—
条件跳转指令。它克服了 IAT 钩子在动态链接库显式加载时 会失效的缺陷,适应能力更强。
通 常 情 况 ,用 户 态 进 程 使 用 CreateToolhelp32Snapshot 等 API 获取进程列表。Rootkit 针对这些函数设置 API 钩子, 在钩子函数中删除原始 API 返回结果中特定进程的信息实现 进程隐藏。
无论在用户模式还是内核模式,仅依靠一种技术已经不 足以将进程完美隐藏。高效的进程隐藏方案往往将 2 种模式 下的技术结合在一起,配合内核中多种数据结构,甚至利用 一些非 Rootkit 范畴的技术。例如 hook 内核 Shadow SSDT 结 构以及抹掉窗口标题等辅助隐藏手段,防止通过枚举窗口探 测进程。归根结底,进程隐藏就是要让进程隐匿在系统之中, 并在最大程度上给检测制造技术障碍。
利 用 PsGetCurrentProcess 函 数 定 位 到 System 进 程 EPROCESS 构成。然后,沿着 LIST_ENTRY 结构指向遍历整 个链表,通过 PID 等信息定位到需要隐藏的进程,将它的 EPROCESS 脱链。脱链之后,该进程的正常运行不会受到本 质的影响。但直接使用系统提供的服务已经不能够发现该进 程了。
3.1 常规检测方法 在用户态可以通过枚举进程窗口、分析进程打开的句柄
表等方法得到进程列表;而内核态列举进程有直接遍历 EPROCSS 双向链表、检查 SSDT 是否被挂钩等方法。下面 2 种是常规方案中强度较高的。 3.1.1 用户态的直接内核函数调用
如前文所述,用户态 Rootkit 通过干扰的 API 函数或者 stub 函数使得程序不能得到正确的信息。只要不通过系统在 用户态提供的函数来发送系统服务请求就能不受干扰。所谓 的用户态直接调用内核函数是指不通过 NTDLL 的帮助直接 进入内核。
一般情况下,在用户态实现进程监控最终都会调用 stub 函数 ZwQuerySystemInformation。因此,在系统上所有进程 中挂钩模块 Ntdll.dll 中的该函数就能实现进程隐藏。这种方 法不再依赖预先对目标进程所使用的 API 函数信息的获取, 适应性更强。它几乎是用户态上最有效的进程隐藏方式。
2.2 内核模式下的进程隐藏技术 Rootkit 进入内核后运行在权限最高的 Ring0 级上,拥有
同内核同等的地位,并能操作内核代码,为隐藏进程提供了 极大方便。 2.2.1 Hook SSDT
在 NT 系 统 中 , 大 多 数 系 统 服 务 都 是 在 内 核 进 程 Ntoskrnl.exe 中实现的。在 Ntoskrnl 初始化的过程中,会先为 它所提供的各种服务创建系统服务分派表(SSDT)[5]。表中的 第 1 项是系统服务的索引号,第 2 项是与索引号相对应的服 务函数在 Ntoskrnl.exe 进程空间中的地址。进程通过服务号 查找需要使用的系统服务函数。
进程 Csrss.exe 的核心是动态链接库 csrsvr.dll,几乎所有 与初始化进程相关的工作都是在其中执行的。它包含很多不 被公开的未导出符号。其中,CsrRootProcess 是一个指向结 构体 CSR_PROCESS 的指针。CSR_PROCESS 这个结构体中 的 域 ClientId 包 含 了 进 程 PID 信 息 ; 而 域 ListLink 是 LIST_ENTRY 结构。包含不同进程信息的 CSR_PROCESS 结 构通过这个域连接起来形成链表。遍历整个链表,可以得到 一份包含几乎所有进程的列表。获取未导出的符号 CsrRootProcess 的 一 种 可 行 方 法 是 利 用 导 出 函 数 CsrLockProcessByClientId,这个函数在执行中会将其值存入 寄存器 ESI 中。导出函数的入口地址可以直接得到,在此基 础上加上相应的偏移量就能读出 CsrRootProcess 的地址。
3 隐藏进程检测
在隐藏进程的检测中,一种简单而有效的思想就是做对 比:用可能被修改过的进程列表同正确的列表做对比;如果 结果不一样,那么不同之处就是存在隐藏的地方。有的文献 称这种方法为 cross-view。一般而言,用户态 API 函数得到 的进程列表可能不含部分进程。要利用对比法得出结论,最 关键的是得到正确的进程列表。
由于线程的上下文切换都要用到 SwapContext 函数,因 此只要把守住该函数就能得到真实的进程列表,找出被隐藏 的进程。 3.2 另类检测方法
进程 Csrss.exe 是 Windows 子系统进程[4]。由于每个进程 在创建初期都会通知 Windows 子系统进程以便能够进一步完 成创建工作,因此 Csrss.exe 中包含了除 Idle, System, Smss.exe 和 Csrss.exe 之外所有进程的信息(前 2 个属于内核,SMSS 是 CSRSS 的父进程)。
函数 ZwQuerySystemInformation 的服务号是 0xAD。隐 藏进程时,Rootkit 在 SSDT 中找到服务号为 0xAD 的服务函 数地址,把它替换为 Rootkit 中可过滤进程信息函数的地址。 2.2.2 直接内核对象操作
基于钩子技术的隐藏技术通常容易被检测到,而直接内 核对象操作(DKOM)技术可以在不依赖钩子的前提下,实现 对进程的隐藏。在 NT 内核的 Windows 操作系统上,每一个 进程在内核中都由内核对象 EPROCESS 结构对其拥有的地 址空间、描述符、线程等信息进行描述[4]。
图 1 显示了用户态的内核服务请求在 NTDLL 中由 int 2E 或 sysenter 指令传入内核。根据 stub 函数的工作原理,仿造 一个发起系统调用请求的函数,当需要使用系统内核服务函 数枚举进程的时候在本进程中直接使用仿造的 stub 函数发起 内核服务请求,如图 1 中虚线所示。该方法可以无视用户态 的一切 hook 得到一个完整的进程列表,对所有用户态隐藏都 有效,但只能应对少数内核态隐藏。 3.1.2 挂钩 SwapContext 函数
【Abstract】Process hiding is a typical application of Rootkit technique. Hidden malicious codes are threats to computer security. By analyzing the Windows Rootkit technology used for process hiding both in the user mode and kernel mode, this paper puts forward several hidden process detection technologies which do not depend on the system services. These detection methods directly use the underlying data structure of the system, and have relatively strong detection ability. 【Key words】Rootkit technique; process hiding; process detection; system kernel
1 概述
Rootkit 是 20 世纪 90 年代出现的一种新兴的计算机技术 技术。它是长期可靠地潜行于计算机上的一组难于检测的程 序或代码[1]。进程隐藏是 Rootkit 技术中典型的一种。它利用 代码及编程手段令特定进程的信息无法为其他进程获取。对 杀毒软件、防火墙等安全软件而言,隐藏关键进程可以排除 恶意软件的干扰,使安全防护效果更佳。同时隐藏进程也可 为计算机取证等工作带来便利。但是隐藏的进程极具危险性, 它意味着代码可以在完全不被察觉的状态下悄然运行。这样, 恶意程序可以在目标主机中长期潜伏,窃取信息而不被发现, 造成极大危害。因此,能够检测出被 Rootkit 隐藏的进程更显 得十分重要。
Win32 子系统
OS/2子系统
OS2.exe
Kernel32.dll
ntdll.dll int 0x2E (sysenter)
用户模式 内核模式
KisystemService ntoskrnl.exe
hal.dll
图 1 API 调用过程
作者简介:王 雷(1983-),男,硕士研究生,主研方向:计算机信 息安全;凌 翔,副教授 收稿日期:2009-10-15 E-mail:l_go@163.com
Process Hiding and Detection Technique of Windows Rootkit
WANG Lei, LING Xiang
(National Defense Key Lab of Anti-Interference Communication Technology, University of Electronic Science and Technology of China, Chengdu 610054)
2 Rootkit 进程隐藏技术
进程隐藏的目标是在保证特定进程正常运行的前提下使 其信息不能被进程监控软件列举出来。用户模式 Rootkit 通过 修改工作在用户态的可执行文件和链接库达到隐藏目的;内 核模式 Rootkit 一般是以驱动程序的形式载入内核,通过对内 核数据的修改实现隐藏。 2.1 用户模式下的进程隐藏技术
第 36 卷 第 5 期 Vol.36 No.5
计算机工程 Computer Engineering
2010 年 3 月 March 2010
·安全技术·
文章编号:1000—3428(2010)05—0140—03 文献标识码:A
中图分类号:TP316
Windows Rootkit 进程隐藏与检测技术
受运行权限的限制,用户模式实现进程隐藏主要依赖的 是钩子(hook)技术[2]。Rootkit 通过设置钩子,钩住进程监控 软件所调用的某些函数,并篡改这些函数的返回结果,特定 进程的信息将不被察觉。
按 照 实 现 方 式 钩 子 可 分 为 导 入 地 址 表 (IAT) 钩 子 和 内 联 钩子(Inline Hook)2 类。IAT 钩子通过注入目标进程空间的代 码对内存中目标进程 PE 格式[3]进行分析,找到并替换 IAT 中目标 API 函数的地址为钩子函数的地址。而内联钩子通常 直接把目标函数的前 5 个字节改写为一个转向钩子函数的无