6.木马查杀之进程篇
(1)进程的隐藏与自我保护
进程是一个程序运行所必须的,因此检查进程也就成了查杀木马的关键环节,我们知道这一点,木马的作者们当然更知道,所以,如何隐藏自己的进程,就成了养马人处心积虑要实现的。在 Windows 系统下一个程序一定、确定以及肯定的会有一个进程,没有进程是不可能的。
而“无进程木马”:
(1)第一种无进程木马是 L DLL 注入型木马:DLL 是动态链接库,当某一进程需要实现某一功能时,此功能可能是放在某一动态链接库文件中的,所以,当进程需要使用时就要将动态库文件加载到自己的进程中。这个 DLL 是利用服务来加载的,在注册表中还有很多位置可以让一个 DLL 加载到其它进程中。但是,通过注册表来加载是可以的,但却不是唯一的,还可以通过另一个进程,来打开现有的进程,来将 DLL 注入到被打开的正常进程中,然后,执行注入的进程退出,这样,在进程列表中仍然看不到木马的进程。
(2)第二种无进程木马是线程注入型的木马。
什么是线程呢?程序就像一个工厂工人工作的流程表,而进程就是将流程真正的运行起来。线程注入,就是木马程序将一个恶意线程放到了正常进程的线程序列中去执行,就像在工厂中多增加了一组自己的工人负责制造炸弹,这一组工人与其它的正常的几组工人没有什么关系,但却借用了人家的工厂去从事着非法的勾档。线程注入与 DLL 注入的区别是,线程注入只是增加了一组工人,这组工人是在以工厂的名义在工作,对外的名义也是工厂的名字,出了问题是由工厂负责的。而 DLL 注入呢,是外包,可能会增加一组工人也可能会增加多组,是以 DLL 自己的名义在工厂内工作的,出了问题是由 DLL 来负责的。当然了,如果问题
大了,工厂也会受牵连的。
(在狙剑的进程列表中,选中一个进程按鼠标右键,选择“查看线程”就可以查看此进程中的每一个线程,也就是查看每组工人的情况,还可以对某个线程执行暂停运行、结束运行等操作。看线程列表,最后一列,显示了一些 DLL 的名字,还有一个是 EXPLORER.EXE,EXPLORER.EXE 就是进程名字,查看的就是EXPLORER.EXE 进程的线程列表。ntdll 有三组线程在工作,那是 ntdll 在完成外包业务所需要的自己的三组工人;EXPLORER.EXE 有一组,那是工厂自己的工人,如果存在线程注入,那么就会多出一个 EXPLORER.EXE线程。但是需要注意的是,有多个 EXPLORER.EXE 并不代表就一定有线程注入,因为一个工厂也可以同时存在多条流水线。但只有一个 EXPLORER.EXE 那么通常情况下就是没有线程注入,因为一个进程肯定会有至少一个线程的存在,也就是说,一个工厂必定至少要有一组工人,皮包公司在 Windows 世界是不允许的。(皮包公司就是没有固定资产、没有固定经营地点及定额人员,只提着皮包,从事经济活动的人或集体。)
了解了什么是 DLL 注入型木马、什么是线程注入型木马后,查杀他们显然就很容易了。
DLL 注入型的,查起来很简单,用上面说的方法“查看某一进程的模块列表---再隐藏无微软签名的项”,就可以查出单个进程中被注入的模块;如果在全系统范围内查找,则使用“搜索无微软签名的模块”就可以将注入到其它进程中的模块找出来,而大多数工具都提供了“卸载模块”的功能,卸载后就可以删除了,或直接用“卸载后删除”的功能,但有一点是需要注意的,如果该木马使用了防卸载的技术,那么卸载此模块时就会发生异常,对此也不必担心,我们还有其它方法清掉它,比如:清除其自启动项,不让他有注入的机会;或直接删除其磁盘文件等。相比较起来,查杀线程注入型的木马,就比较困难了,线程注入的没有自己的文件,只是一段注入的代码。也就是说他只是混入工厂内的一组工人,并没有自己的工厂也没有自己招牌,想把他与正常的工人区分开,是很困难的。编写线程注入的测试程序,运行后,会打开一个窗口,但你却在进程列表中找不到有新增加的进程,那窗口是如何来的呢?这就是由注入到 Explorer.exe 中的线程创建的。这时你再查看 Explorer.exe 的线程列表,会发现多出来了一个线程,而线程的“模块”那一列标的名字就是 Explorer.exe,这时线程列表中已经有两个名字为 Explorer.exe 的线程了,但哪一个是好的,哪一个是后来注入的呢?通常情况下看“基址”那一列,基址数值较大的那一个一般是起动起来较晚的,就是后来加入的了,选中那一个线程选择“结束线程”,那个窗口被关闭,(注意:如果是用狙剑查看的,那么在线程注入后,查看新线程时,要重新刷新进程列表,不然会发现不了新注入的线程)
真正查杀起线程注入型的木马来,用上面的方法显然是不行的,首先,我们不知道他注入到了哪一个进程中。其次,即使一个进程中有多个以进程名为名字的线程我们也无法确定那多出来的线程就是木马线程。所以,我们仍然要从自启动项入手来禁止线程注入。
(3)第三种无进程木马是纯驱动型木马
驱动型木马:就是全部功能放到了驱动程序中去完成(当然了,纯驱动型的并不多见,大多驱动型木马都是配了一个程序。)什么又叫驱动程序呢?驱动程序顾名思义就是驱使设备动起来的程序,其作用是让特殊的硬件和 Windows 操作系统可以交换数据。驱动程序由于其特殊性,使得它在系统中有着超越一切的权力,而且有着优先加载执行的优势,它是做为操作系统的一部分来运行的。“系统的权限分为两种 R0 与 R3,一般的程序全部为 R3 权限,其行为受到了很多限制;而操作系统与驱动则为R0 权限,拥有对整个计算机的全部权力,可以为所欲为”,又叫“虚拟设备驱动程序”。
杀软与木马的斗争,一个不好惹来的就是蓝屏死机、系统崩溃。
如何知道系统加载了哪些驱动呢?又如何知道哪些驱动是正常的系统驱动,哪些是木马的驱动呢?
在桌面我的电脑图标上按右键,依次选择“属性---硬件---设备管理器”就可以打开上面的窗口了,再勾选上“查看---- 显示隐藏的设备”就可以看到“非即插即用驱动程序”。除了非即插即用外,其它的同级项目都是机器上的硬件及它们的信息、资源、驱动等,他们是根正苗红的正经设备。由于这些都与硬件有关,所以,木马动它们的可能性很小,必竟木马也不想你的机器崩溃啊。因此,大多数木马驱动都隐藏在“非即插即用驱动程序”下面,而这里面的则是那些虚拟设备了(注:非即插即用驱动程序并非就是虚拟设备驱动程序,但大多都是虚拟设备驱动程序)
选中某一个项点鼠标右键,再选属性,“是否能停止驱动程序的运行,还要看这个驱动程序是否愿意停止运行”,我们只需要了解一点就够了,这个驱动的状态是“已经启动”。接下来要看的是“驱动程序详细信息”这一栏。这里面的就是驱动程序对应的文件了,至于下面的提供商、版权什么的,参考一下也就得了,
(依次选择“开始”---“所有程序”---“附件”---“系统工具”---“系统信息”就可以打开系统信息窗口。这里面列出了所有进程加载的所有模块)
想来木马是不会愿意被卸载吧,那就从自启动程序入手,禁止它的加载;或强制删除它的文件。那驱动级木马是不是就是真正的无进程呢?进程列表中找不到任何一个驱动程序的进程,而它也不像模块与线程一样,在其它进程内能够找到,那这些驱动在哪个进程里呢?那就是 System 进程,它们是做为系统的一部分来运行的。
(4)第四种无进程木马就是利用技术手段隐藏进程的木马,这显然就不属于无进程了,上面说的三种,的确是没有自己的进程,只是利用了其它的进程。而利用技术手段隐藏进程的木马,则是有自己的进程,但是如果你破解不了他的隐藏技术,那你就看不到它的进程。同时,需要注意的是,隐藏进程的技术同样适用于隐藏 DLL 模块程序、隐藏驱动程序,Windows 系统给我们的开发人员提供了几种列出系统中所有的进程、模块、与驱动程序的方法,最常见的也是最常用的方法就是调用系统 API:CreateToolHelp32Snapshot、EnumProcess、EnumProcessModules等,他们是获取进程列表的第一层手段,我们调用这几个其实就是在告诉系统,我们需要进程列表,然后系统就会将列表返回给我们。而这几个 API 在接到请求后他们会调用ZwQuerySystemInformation,
ZwQuerySystemInformation 会调用 KiSystemService 切入内核进入 R0 权限,然后自 SSDT 表中查取得NtQuerySystemInformation 的地址,并调用其指向的实际代码,而 NtQuerySystemInformation 的作用则是自系统的数据结构中取相应的数据,再顺原路返回去。在中间任何一个环节进行拦截都可以实现隐藏进程的目的,这种拦截有一个名字叫做“HOOK”,在切入内核进入 R0权限前进行 HOOK,称为应用层 HOOK,而在之后进行 HOOK 则是内核 HOOK,后者需要用驱动才能实现了。
SSDT表就像是一个路标,指明了什么样的工作应该由哪一个部门负责处理。应用层 HOOK ,就像是服务员被木马偷偷的替换了,当我们提出要求时呢,他会检查是否对他有害,或将对他有害的信息去掉,比如我们想查看进程,那他在将结果交给我们时,却把木马的进程自结果中抹去了,这样,我们自然是看不到木马进程了。而最常见的内核 HOOK,则是 HOOK-SSDT,上面说了 SSDT 就是一张表,标明了什么工作应该由什么部门负责。而 SSDT HOOK 也就是木马将表上的内容给改了,本来交给 A 部门负责的工作被改成了交给由木马负责,这样,服务员在上报我们的请求时,一查表发现查看进程的工作是由木马负责的,他就把这请求交给木马了,而木马呢?他可是知道表中原来的内容是什么的呀,他只是对请求进行一下过滤,发现没有对自己有害的,就直接转交给原部门了,对自己有害的,自然也就视情况滤掉或涂改了。而 Inline-HOOK :他并没有更改表的指向,查找进程的工作在表中仍然指向了负责查找进程的部门。但是呢,木马却把那个部门中的人员替换了,这样仍然能达到它的目的。Inline-HOOK 更加的复杂、更加的邪恶、也更加的不稳定,而应用范围却是更加的广泛,查找起来更加的困难。要知道,对比 SSDT 表中的指向是否正确,是否指向了正确的部门,要简单一些,不就是一张表么,拿原来的表对比一下就知道了。但 Inine-HOOK 却是替换的公司人员,Windows 就像一个大公司,有成千上百的人,天知道他替换了哪一个。IceSword.exe 是另一款知名的安全程序“冰刃”的主程序,当试图在任务管理器中结束 IceSword.exe 的进程时,就会出来“无法中止进程”的对话框。但是,当检查 SSDT 表时,却发现,它并没有对 SSDT 进行 HOOK
Inline-HOOK如何实现进程不被结束:(选择狙剑--- 扩展功能--- 内核代码扫当然了,正常情况下,列表应该是空的,但当运行起 IceSword.exe(冰刃)后,再检查,就会出来 7 个 Inline-HOOK 项了。内核代码扫描,是对内核代码中的 Inline-HOOK 进行检查,并列出被 InlineHOOK 的项。IceSword.exe 的驱动 IsDrv122.sys,HOOK 了 7 个函数,前六个的功能分别是“结束线程、结束进程、创建进程、创建线程、打开线程、打开进程”后面的那个与进程无关我们不去理它。选中这些 Inline-HOOK 项,然后再在 Inilne-HOOK 的列表中按右键,选则“恢复选中的 Inline-HOOK”,然后,你再打开任务管理器,试试结束 IceSword.exe 的进程,就可以结束了)
(可以用阻剑查看 SSDT 到底是什么样子:依次选择狙剑--- 扩展功能---SSDT 检查--- 筛选可疑项,就可以看到一个 SSDT表,从左到右依次是序号、当前地址、所在模块、HOOK 类型、原地址、函数名。上面都是狙剑自己对 SSDT 的 HOOK,当前安全软件很多也用到了 SSDT-HOOK 技术来实现对系统的安全防护。
这是狙剑本身对 SSDT 的一个 HOOK,用的技术就是 HOOK,HOOK 的函数是用于增加进程权限的。HOOK 这个的目的是“在木马进程为自己增加权限的时候进行拦截,提醒用户注意”。每一个函数都实现了某一种功能,比如:结束进程是由 NtTerminateProcess 来完成的,如果 HOOK 了这个,那么在进程结束前,就有机会更改结果了,可以拒绝被结束。
当你试图在任务管理器中结束狙剑的进程时,系统会拒绝你的操作,其实这并不是系统拒绝的,而是狙剑自己,由于狙剑 HOOK 了 SSDT,所以,结束进程的工作服务员都交给他去做了,他一旦发现结束的就是他自己,那他直接告诉服务员这个进程不能结束,然后服务员就把这个结果给我们了,其实我们的这个请求
并没有真的到达应该送交的部门。而上面提到的查看进程用的 NtQuerySystemInformation 也在这里面,注意找一找就会发现了,如果想隐藏进程就可以把这个给 HOOK 了。
总结:程序就像是为了实现某一目的而定的计划书 ;进程:就是组织工人分配资源开始执行这份计划 ;而 Windows 操作系统:就是一个为我们管理电脑也是管理这些执行计划的工人的服务管理公司 ;我们有什么要求,就交给服务员将我们的要求提要给 Windows , 由Windows 来组织工人执行我们的要求 ,并将结果返回给我们 。如果木马替换了服务员 、 更改了 T SSDT 表 、 或替换了 s Windows 服务公司某职能部门的人员 , 我们得到的可能就是一个错的结果 , 或我们的要求得不 到执行 , 就像结束进程一样 。如果不替换任何人员,也不更改 SSDT 表,那就要更改系统的数据结构来隐藏进程
如果木马只是抹去了活动进程链中的数据,那么还可以从窗口、线程、句柄、对像、Csrss.exe 中等许多地方找到它的信息。当然了,木马也会尽力的把自己的痕迹全部抹去,并且已经有马儿这么做了。
于是,基于线程调度链的进程枚举技术就出现了,什么叫线程调度链呢?在系统中 CPU 的时间分配是以线程为单位的,一个程序要想得到执行,必须要有线程存在于这个线程调度链中,不然,他得不到时间的分配,也就得不到执行的机会。而这关键的他无法抹去的资料也就是系统中的“线程
调度链”,抹去了,他自己活不下去。




