Rootkit进程隐藏与检测技术研究

2016-05-14 22:04孟晨宇阮阳王佳伟周洁康晓凤
软件导刊 2016年5期

孟晨宇 阮阳 王佳伟 周洁 康晓凤

摘要:进程(Process)是操作系统进行资源分配和调度的基本单位,是Windows系列操作系统结构的基础。进程隐藏虽然能够为计算机取证提供便利,但是增加了检测系统中运行的恶意代码的难度。在深入研究Windows进程隐藏技术的基础上,针对常用进程隐藏技术的特点,提出几种Windows操作系统下检测隐藏进程的方法。这些方法能够准确、快速地检测操作系统中隐藏的进程。

关键词:系统内核安全;进程隐藏;进程检测;Rootkit

DOIDOI:10.11907/rjdk.161009

中图分类号:TP306+.2

文献标识码:A 文章编号:1672-7800(2016)005-0188-03

0 引言

Rootkit是一个功能强大的工具包。它由一些小程序组成,能够使攻击者持续隐蔽地访问计算机上的“root”用户。即Rootkit是能够持久、隐蔽、且可靠地运行于计算机上的一组程序或代码。在上述Rootkit描述中关键词是“隐蔽”,即隐藏代码和数据,其中进程隐藏是Windows Rootkit技术中典型的一种。对于一些计算机取证工具来说,进程隐藏能够为其带来便利,同时将系统中的防护进程隐藏起来,也可以阻止恶意程序对于杀毒软件的干扰,使防护效果更加有效。但是进程隐藏技术也是一把双刃剑,它能够使恶意代码潜行在内核中,不被发现,当隐藏技术被用于恶意代码时,会给安全带来毁灭性的打击。所以,准确检测出系统隐藏进程十分必要。

1 进程隐藏技术

Rootkit所采用的大部分技术和技巧都用于在计算机上隐藏代码和数据。绝大多数Rootkit都可实现文件、目录和进程等信息的隐藏[1]。从隐藏时采用的手段看,进程隐藏技术机理主要归结为两类:一是通过修改程序执行,截获所有访问隐蔽资源的请求,称为修改程序执行路径(Modify Execution Path,MEP)技术;二是直接修改操作系统用于监控系统资源的数据,称为直接内核对象操作(Direct Kernel Object Manipulation DKOM)技术。这两种机理分别对应拦截挂钩隐藏技术及直接修改内核数据隐藏技术。

1.1 拦截挂钩(MEP)隐藏技术

所谓拦截挂钩技术即通过挂钩系统函数或相关处理例程,使其先转向事先编写好的函数处理,实现过滤参数、修改目标函数处理结果、删除特定进程信息,从而实现进程隐藏。按照挂钩位置不同,挂钩拦截技术可分为用户态挂钩和内核态挂钩两类。用户态钩子属于Windows操作系统3环(用户态)下的拦截。一般情况下,3环进程使用CreateToolhelp32Snapshot等函数查询进程列表信息。Rootkit针对此类函数设置API钩子,在API钩子中删除被挂钩函数返回的特定进程信息,从而隐藏特定进程[2]。Windows平台下的应用程序一般都会调用Kernel32.dll中的相应函数,接着再跳转到Ntdll.dll中的相关函数,最后由Sysenter 或 int 2E指令使调用跳转到内核层,具体执行过程如图1实线部分所示。通过分析Windows API调用过程得知,也可以通过挂钩Ntdll.dll中的ZwQuerySystemInformation更好地实现进程隐藏[3]。在Windows系统中,要列出系统正在运行的所有进程信息,3环下的程序最终都会调用Ntdll.dll中的ZwQuerySystemInformation,因此在所有进程中均对Ntdll.dll中的该函数挂钩即可实现进程隐藏。该方法几乎是用户态挂钩最有效的进程隐藏方式。

内核态挂钩常用的方法是挂钩系统服务调用表(System Service Dispatch Table)即Hook SSDT,SSDT[4]表中的第一项是系统服务的索引号,第二项是索引对应系统服务函数在Ntoskrnl.exe 进程空间中的地址。ZwQuerySystemInformation在SSDT中的索引号为0xAD,通过该索引找到对应的函数地址,并将其修改为可过滤特定进程信息的函数地址,即可实现进程隐藏。

1.2 修改内核数据(DKOM)隐藏技术

挂钩的隐藏技术非常容易被检测到,而DKOM直接操纵内核数据隐藏进程极难检测,是现阶段隐藏进程最有效的方法。正常环境下,更改进程或者令牌等内核对象时需要深入到内核对象管理器中,而DKOM绕过对象管理器,从而绕过所有关于对象的常规检测。Windows NT系列的操作系统利用可执行对象EPROCESS[5]描述进程信息。进程对象EPROCESS中有LIST_ENTRY结构成员,它包含指针FLINK和BLINK。这两个指针分别指向当前进程描述符的前方进程和后方进程,该结构将所有进程的EPROCESS结构连接成一个双向链表。通过遍历EPROCESS结构中的双向链表,将需要隐藏进程的EPROCESS从链表中摘去,即可实现特定进程在操作系统中的隐藏[1]。从图2定位进程链表路径图中可以看出PsGetCurrentProcess找到当前正在运行进程的ETHREAD指针,从ETHREAD结构沿着KTHREAD结构中的指针可以找到当前进程的EPROCESS结构,然后遍历双向链表,通过进程标识符(Process Identifier,PID)或进程名定位特定进程的EPROCESS结构,以达到定位进程路径的目的,然后再将此进程的EPROCESS从双向链表中摘除,摘除后该特定进程的运行不会受到特殊影响,直接使用操作系统提供的服务已无法发现该进程。

无论是挂钩隐藏技术,还是直接操纵内核数据隐藏方式,都有一定弊端。现阶段,高效的进程隐藏方案往往结合挂钩和直接操纵内核数据两种方法,通过交叉使用用户态与内核态的技术,并利用其它辅助手段,如抹掉窗口标题等,从而实现进程隐藏。总之,隐藏进程技术的最终目的是使进程隐匿于系统之中,并对进程检测造成一定干扰。

2 隐藏进程检测技术

对于Windows平台下的进程隐藏检测技术,常用的检测方法有枚举进程窗口、遍历当前进程的句柄表、遍历csrss.exe进程句柄指针和遍历PspCidTable的句柄表等。

2.1 常规检测技术

2.1.1 直接调用内核函数

用户态挂钩技术通过挂钩系统API函数或者Ntdll.dll中导出的函数,消除相应进程信息,从而实现特定进程隐藏。所以不调用系统在3环下设置的API来发送调用请求就能排除其挂钩干扰[3]。3环直接调用内核API是指不通过Ntdll.dll的跳转直接进入内核,调用相应查询函数,用户态内核请求在Ntdll.dll中通过Sysenter或int 2E指令进入内核。用户态需要使用内核函数枚举系统进程时,可以直接通过Sysenter或int 2E指令伪造请求传入内核,其具体实现方式如图1虚线所示。该方法可以检测所有通过用户态挂钩技术隐藏的进程,但对于内核挂钩及直接操纵内核数据隐藏方法并没有明显效果。

2.1.2 遍历当前进程的句柄表

EPROCESS的地址加上0x0c4,就可以得到当前进程的句柄表。进程句柄表中包含HandleTableList双链指针,遍历双链可以枚举出除 Idle以外的所有进程信息,因此可以通过遍历当前进程 EPROCESS中的句柄表双链指针得到一组进程的映像。

2.1.3 遍历PspCidTable的句柄表

PspCidTable是独立的句柄表,不属于任何进程,是内核未导出的HANDLE_TABLE结构,通过它可以访问系统的任何对象,它保存着所有进程对象指针。该句柄表在NT操作系统下采用动态分配的三层表结构。首先使用一层表结构,如果线程和进程过多,则会启用两层表或三层表结构。定位该表常用的方法是通过PsLookupProcessByProcessId。该函数内部会引用PspCidTable,通过查找此函数的前几十个字节找到 PspCidTable变量,即可找到PspCidTable的地址。此后,可通过EnumHandleProcedure或PsLookupProcessByProcessId遍历该表直接枚举进程,从而检测出被隐藏的进程。

2.2 其它检测技术

2.2.1 挂钩SwapContext函数

Windows系统中每个线程上下文的切换都由内核中的SwapContext函数来实现[6]。执行函数时,ESI中存放的是即将被换出的当前线程指针,EDI中存放的是当前即将被换入的线程的指针。根据该原理,挂钩此函数,在钩子函数中确认EDI所指向的线程中的KTHREAD是否指向一个位于正常双向链表中的EPROCESS结构。若不是,则表明该进程是一个被DKOM隐藏的进程。因为系统切换所有线程上下文都要使用SwapContext函数,所以只要对该函数挂钩,即可检测隐藏进程。

2.2.2 遍历csrss.exe进程句柄指针

Windows操作系统下子进程的服务进程Csrss.exe包含除 Idle、system、smss 以及 csrss 以外的所有进程信息。动态链接库 Csrsvr.dll是其核心,几乎所有与初始化进程相关的工作都是在其中执行的[7]。Csrsvr.dll中拥有一个指针成员CsrRootProcess,该指针指向一个包含ListLink指针成员的结构体CSR_PROCESS,指针ListLink将系统内进程连接起来形成链表,遍历整个链表即可得到所有进程的列表。获取未导出指针CsrRootProcess的一种有效方法是通过函数CsrLockProcessByClientId,执行时会在寄存器ESI中存入其值。导出函数的入口地址可以直接得到,在此基础上加上相应的偏移量就能读出 CsrRootProcess 的地址。

3 结语

Windows平台下的进程隐藏与检测技术是相辅相成的。进程隐藏技术一直致力于抹除操作系统中的进程信息,同时干扰进程检测的正常工作。由于进程与系统之间存在各种各样的内在联系,通过挖掘这种联系,进程检测技术也能够采用相应的解决方案找到隐藏的进程。这两种技术就是在这种矛盾中互相促进,逐步发展完善的。

参考文献:

[1]GREG HOGLUND,JAMES BUTLER.Rootkits——Windows内核的安全防护[M].韩志文,译. 北京:清华大学出版社,2007.

[2]王雷,凌翔. Windows Rootkit进程隐藏与检测技术[J].计算机工程,2010,36(5):144-142.

[3]潘爱民. Windows内核原理与实现[M].北京:电子工业出版社,2010.

[4]BORATE M, DABAK P, PHADKE S. Undocumented Windows NT[M].New York, NY, USA: John Wiley & Sons, Inc., 1999.

[5]RUSSINOVICH M, SOLOMON D. Microsoft Windows internals[M].New York:Microsoft Press, 2005.

[6]林卫亮,王轶骏,薛质.Win32 Rootkit 的进程隐藏检测技术[J].信息安全与通信保密,2009(3):62-63.

[7]张登银,陈召国.Windows平台下Rootkit进程检测[J].计算机技术与发展,2011,21(7):141-144.

(责任编辑:陈福时)