一. 招摇过市的流氓与木马
中国的网络从来都是与各种蠕虫、木马、漏洞扫描器一起运作的,而国民对计算机木马和病毒的敏感反应是很重的,但是防范意识却又是最低的,于是在这样的环境里,越来越多的人参与到了木马病毒的制造行业,稍有手段的则打着正义旗号推出各种“便民服务”的网络工具,并且为了将便民服务进行到底,大部分此类工具都是一旦装上,则无法卸载的爷们,使用这种铁腕手段强驻的工具则被称为“流氓软件”或者“恶意软件”,最终在各方流氓软件制作者和木马制造兜售者和努力下,中国一跃成为世界上最主要的恶意软件和垃圾邮件发源地。
提到木马或者病毒,大家都会是一脸憎恶且避而远之的态度,恨不得自己一辈子都不用跟这些东西打交道,但是现实却是残酷的,根据一份调查报告指出,在如今这个时代里,国内用于家庭和企业的平民电脑,平均每十台就有至少一台感染了后门,染毒途径除了移动媒介扩散以外,最常见的就是网络途径——被植入木马的网站、网络中爬行的蠕虫、即时聊天系统传输的文件、系统漏洞导致的入侵植马和带毒电子邮件等,可以说,各种途径都可能使你的计算机受到感染,即使你只是打开了几个网站页面看看当天的时事新闻。
然而木马和病毒并非我们所面对的唯一黑手,那份报告遗漏了一个同样重要的统计,那就是,在剩下的九台电脑里,至少有五台都“自愿”安装了“上网辅助软件”,在现行法律里,它们是合法的,因为目前还没有对应的立法,而且许多电脑用户也并没有什么不适感。这就是恶意软件的最初形式,棍棒加糖果主义。通常,它们都具备一些能够辅助用户的功能,从而形成了一定的用户群,而且这些用户到最后会因为无法卸载这些工具而感到困惑:是我潜意识里离不开它还是它不想离开我了?可是当初我只是糊里糊涂的点了一个“是”啊?
这种强行安装且无法卸载的软件就是所谓的“恶意软件”,与各种后门木马的意图不同,恶意软件的立场是自家公司的利益,它们一般不会携带破坏性质的代码(但不代表没有),通常还会拥有一些号称“服务大众”的功能,这些功能或许可以让它得到一些用户的拥戴,但是这种光环并不能掩盖其“服务大众”背后的暴利黑幕。首先,恶意软件可以轻易收集到用户信息,任何一台被安装了“X手X霸X猪X搜”的计算机都不再与“个人隐私”这个词语有缘。其次,恶意软件可以借用广大计算机作为它无偿弹出公司广告的殖民地,如果每条广告都能给该软件背后的公司带来一点利润,那么一年下来这个公司就已经从广大用户群的身上搜刮到一大笔可观的钱财了。天下并没有免费的午餐,在你使用这些软件提供的“快捷服务”时,你就已经付出了代价。
如果说最初的恶意软件都是偷偷耍手段诱惑用户安装的话,那么今天横行网络的恶意软件,就已经和木马没什么两样了,你不仅找不到它们给你带来的什么功能,而且它们也不提供哪怕只是做做样子的卸载程序了,即使你发怒直接删除了它们,重启后你会发现它们仍然安然无恙的在你系统里呆着,这样子的恶意软件,已经被划分为木马了。
在这样的环境下,谁来还我们一个干净清洁的系统环境呢?答案,只能是我们自己。
二. 隐藏技术的演变
由于颇为强大的木马和最初的流氓软件均已不是最初那种简单的形态,所以最普通的EXE可运行文件和简单的隐藏技术并不是这些工具会采用的形态和手段,而是直接跳过了第一代木马形态,而采用DLL文件形态和线程注射技术,而一部分流氓软件还会携带着EXE,毕竟流氓软件不能算是纯粹的“木马”,它们还要以辅助工具的身份和用户发生交互的。
线程注射的全称是“远程线程注射”(RemoteThread Injection),通常情况下,各个进程的内存空间是不可以相互访问的,这也是为程序能够稳定运行打下基础,这个访问限制让所有进程之间互相独立,这样一来,任何一个非系统关键进程发生崩溃时都不会影响到其他内存空间里的进程执行,从而使NT架构的稳定性远远高于Win9x架构。但是在一些特定的场合里,必须让进程之间可以互相访问和管理,这就是“远程线程”技术的初衷,这个技术实现了进程之间的跨内存空间访问,其核心是产生一个特殊的线程,这个线程能够将一段执行代码连接到另一个进程所处的内存空间里,作为另一个进程的其中一个非核心线程来运行,从而达到交换数据的目的,这个连接的过程被称为“注射”(Injection)。远程线程技术好比一棵寄生在大树上的蔓藤,一旦目标进程被注射,这段新生的线程就成为目标进程的一部分代码了,只要目标进程不被终止,原进程无论是否还在运行都不会再影响到执行结果了。
曾经,线程注射技术成为摆在用户面前的一道难题,因为一旦它加载运行,一般的手段就无法对其造成伤害,但是随着时代变迁,它的“弊端”也开始暴露得越来越明显了,例如在安全模式下,由于载体EXE的启动项无法被调用运行,这些木马自然也就失去了作用。而一部分流氓软件是以浏览器BHO形式出现的,只要“Windows外壳”Explorer.exe程序被加载,它就随之启动了,虽然它使用这种方法实现了在一般的安全模式里也能保持运行,但是在更进一步的“命令提示符的安全模式”里,由于它的依赖载体Explorer.exe并不会被调用(该模式里使用CMD.EXE作为外壳),在有经验的用户面前,这种保护模式也就被破解了。
于是开发者必须寻求一种更高级更保险的手段来确保自己的作品不受破坏,最终他们把眼光投向了系统底层——Ring 0,这里运行着系统核心模块和各种驱动程序模块,而且也只能运行这些以驱动文件为形态的代码。为了达到目的,后门作者把作品写成符合WDM规范(Windows Driver Model)的驱动程序模块,把自身添加进注册表的驱动程序加载入口,便实现了“无启动项”运行。一般的进程查看器都只能枚举可执行文件EXE的信息,所以通过驱动模块和执行文件结合的后门程序便得以生存下来,由于它运行在Ring 0级别,拥有与系统核心同等级的权限,因此它可以更轻易的把自己隐藏起来,无论是进程信息还是文件体,甚至通讯的端口也能被隐藏起来,在如此强大的隐藏技术面前,无论是任务管理器还是系统配置实用程序,甚至系统自带的注册表工具都失去了效果,这种木马,就是让人闻之色变的Rootkit。
最初,这种技术仅仅为高级的木马所使用,然而到了后期,为了避免自身被用户和恶意软件清理工具卸载,越来越多的恶意软件纷纷加入了这个阵营,到了这个阶段,恶意软件已经彻底成为流氓了,有许多恶意软件甚至结合了多种途径蚕食用户的系统领域,包括驱动形态、线程注射的DLL形态和表面上的EXE——它们只比类似的木马多了一个EXE而已。在多种技术的结合下,这些惹人讨厌的东西越来越难以查杀,于是就出现了开头提到的现象——并非用户不想清理它们,而是因为太多的有心无力。
在这个疯狂的利益时代里,我们——普通用户该如何保全自己不再成为这种进驻到了驱动级别的木马和流氓软件的受害者和摇钱树呢?
三. 与驱动木马过招
与传统木马的发展过程一样,驱动木马也经历了一个进化的阶段,早期的驱动木马虽然采取了驱动形态达到隐藏自己避免查杀的目的,但是在安全模式里它仍然被发现了,这是为什么?因为Windows的“安全模式”不仅仅限于加载用户界面和启动项这些区别,它还包括各种驱动的“安全模式”,在安全模式里,为了确保Windows不会由于某个驱动文件的缺陷而崩溃——毕竟一部分人被迫进入安全模式就是因为遇到了某些设备驱动不兼容或存在问题而导致系统不能正常运行,大部分被标记为“不必要”的驱动在“硬件抽象层(HAL)”的干涉下,是不会被加载的,甚至显卡驱动也不能例外,所以此时Windows是相对安全的基于“默认硬件”运行的界面简陋的系统。操作系统厂商此举其实很好理解,想象一下如果你因为安装了某个设备的驱动程序而导致系统蓝屏,然后你来到安全模式里想要修复它,却不幸的发现安全模式也出现了蓝屏——因为这个驱动被系统加载了,如果这样,安全模式还有什么意义。
于是,在这样的设计思想下,早期的驱动木马到了安全模式,还是很好清理的,因为那个时候,大部分开发者还处于开发Rootkit的试探阶段,谁也不敢贸然绕过这种安全体系。
小知识:硬件抽象层
硬件抽象层(Hardware Abstraction Layer,HAL)是微软公司为了便于操作系统在不同硬件结构上进行移植而提出的将系统底层与硬件相关的部分独立运作的思想,HAL为系统实现了“硬件无关性”,即在不同的硬件平台上,硬件与操作系统的交互也不会有所差异,这样一来,硬件厂商开发驱动的难度便能大大降低,HAL将硬件的接口细节隐藏起来,并为操作系统提供一个标准硬件交互接口,目前所有的硬件驱动都工作在这个层面上,当外界硬件存在指令请求时,驱动程序响应请求并将指令通过HAL转换为系统核心层能理解的指令交给内核执行,如果未找到相应的驱动程序类型,则将其视为“默认硬件”(Default Hardware)处理,什么叫“默认硬件”呢?最简单的例子就是进入安全模式,这时候大部分驱动程序不会被加载,此时的系统便是工作于“默认硬件”上。
然而在经历了一段时间的试炼以后,开发者的技术熟练了,胆子也大了,他们开始修改驱动模块的运行级别——系统的“默认硬件”是根据驱动模块加载入口声明的启动优先级判断的,对于绝对安全的驱动程序,它的优先级被提高了,于是系统无论在什么模式下都会加载它,例如键盘驱动、鼠标驱动、各种基础的系统设备驱动等,如果某个驱动文件的优先级被人为提高,系统就会将其视为必备驱动加载,而这个优先级的提高方法非常简单,只需要改动注册表的驱动模块分支里的一个数据而已。
到了这一步,用户终于真的遇上了赖着不走的狼,即使在加载模块最少的“基于命令提示符的安全模式”里,这些使用了驱动的流氓们照样可以不受阻碍的横行霸道。
使用了这种手段的“辅助工具”,其本质已经属于木马了。
识别驱动木马
大部分驱动木马的驱动模块并不是用来实现入侵行为或者进行浏览器劫持的,而是为真正负责这部分操作的位于用户层的可执行程序本体提供保护功能,因此驱动木马的大部分工作就是拦截相关的系统API调用工作,使得用户无法直接查找到真正的文件本体,或者对它们屡杀不禁,甚至连相关的注册表项目都无法删除,这就是因为它们直接从驱动层拦截了实现这些功能的API。
虽然驱动木马使用的种种手段使得自己可以保全于普通的系统安全检测工具下,但是在基于驱动层的安全检测工具出现后,这个一方独霸的局面被打破了,通过使用国产的几个优秀工具如IceSword和安全巡警专业版(AST Pro),普通用户也能具备发现驱动木马的能力。
那么,如何判断系统是否中了木马,以及是中了驱动木马呢?首先用户要具备基础的系统启动项知识,虽然启动项里的东西会随着用户安装的一些软件而增加,但是实际上系统可以只存在最少的两个甚至一个启动项:用于同步的mobsync、输入法指示器internat(Windows 2000)或高级文字服务ctfmon(Windows XP),默认情况下Windows XP还会出现一些IMG或IME开头的启动项,这些都是无关紧要的。
有用户会提问,如果我一直没有养成记录系统启动项的习惯,也没有过检测木马的经验,我该如何去判断一个启动项是否木马呢?这个问题很难用固定的思维回答,但是用户可以采取一个笨而实用的方法来测试,虽然它很烦琐,但是却比较直观。
首先运行“系统配置实用工具”msconfig.exe,在它的“启动”选项卡里面把所有启动项取消,然后重启计算机,你会发现系统任务栏右边的托盘区少了许多东西,这时候,再次运行msconfig,边把当前的启动项名称记录在笔记上并勾上第一个启动项,然后确定重启,通过观察系统启动后托盘区里是否多出了图标就可以判断出这个启动项的大概作用了,如果托盘区出现了图标或者直接就出现了一些窗口界面如QQ的登录对话框,就可以确认这是个正常的启动项,在笔记上对应的启动项名称前打勾。然后再次运行msconfig,取消第一个启动项的勾,勾上第二个启动项,再次重启,直到所有启动项都分别独立开启了一次为止,最后看看你记录下来的笔记里有多少个项目是打了勾的,而剩下那些未被勾选的项目,有80%的几率就是一般的木马。
这个方法最保险,也最烦琐,所以用户需要记住一条规律,如今有许多木马的文件名和启动项名称都是很混乱或者很“系统”的,如看到“48ED0A5E”、“svchost”、“svohost”、“services”、“ssdt”、“ssodl”这样的启动项,那就不必怀疑了,它绝对是木马。
用户的疑问又来了,这方法的结尾说,这只是测试“一般的木马”而已,那我该如何判断系统是否感染了“驱动木马”呢?其实,如果用户的机器已经感染了驱动木马,那么在刚才的测试里它就已经暴露了,细心的用户应该不难发现,他们的机器里有一个甚至多个启动项,即使刚才在msconfig里已经取消,重启后却发现它仍然是选中的状态,如果用户是使用具备实时刷新功能的第三方工具管理启动项,甚至会发现自己刚取消了这个启动项就马上被自动恢复了,而这些始终不肯放弃自启动权利的项目,就是我们要找的驱动木马的用户层本体——不要高兴,它并不是驱动木马的真正危害部分,这个只是驱动木马千方百计要保护的对象而已。这个方法正是利用驱动木马的保护特性,让它自我暴露。
揪出幕后真凶
如果用户的机器出现了上述无法删除的启动项,请在安全模式里尝试删除这个项目一次,观察它是否会立即再度出现,或者在重启系统后出现,如果不幸它仍然无法删除,“DLL线程木马实时重写启动项”的疑因就可以排除了,你面对的是不折不扣的驱动木马。如果在安全模式里它无法立即恢复,然而到了正常模式它又出现,这就是一个早期的普通驱动木马,在安全模式里可以轻易的将其狙杀;如果安全模式里它仍然保持活动状态,那么这就是一个相当棘手的高优先级驱动木马了。
在驱动木马面前,系统自带的或者第三方开发的未涉及驱动层的任何环境检测工具都是无能为力的,我们必须使用具备驱动检测的安全工具,在这方面,国产的IceSword和超级巡警专业版是不二之选。
首先在正常模式的系统里运行IceSword,点击“进程”,观察里面是否存在被标记为红色的进程,这就是被驱动木马保护的用户层执行体,尝试用右键将其关闭,然后立即刷新一次进程,观察它是否再次出现,即使它再次出现也不要慌张,这是只是判断驱动木马对其保护到什么级别而已,记录下它的具体文件位置,然后在“查看”列表里选择“SSDT”,从顶端翻阅到尾部,将标记为红色的项目的所在模块记录下来,然后重启计算机进入“基于命令提示符的安全模式”,在命令提示符界面下分别依次输入以下命令:
cd %windir%/system32/drivers/
这条指令的作用是进入系统驱动文件目录,然后我们需要查看具体的驱动文件名确认其是否存在,输入这个命令:
Dir 刚才在SSDT里记录的红色标记文件名 /a
例如 dir std.sys /a,如果文件存在且没有被系统加载(第一代驱动木马),系统就会将它列出来,这时候输入:
Attrib 刚才在SSDT里记录的红色标记文件名 –h –r –s –a
这是确保将驱动文件的各种文件属性去掉,以便删除,最后我们输入这条指令:
Del 刚才在SSDT里记录的红色标记文件名
这样就把驱动木马的驱动文件本体消灭了,但是事情到这一步还未结束,我们需要验证驱动文件是否真的被删除,再次输入“Dir 刚才在SSDT里记录的红色标记文件名 /a”这条命令,确认系统返回“文件未找到”的提示,这样才能证明驱动文件已经被清理。然后,还记得在IceSword“进程”里列出的红色标记文件名吗?这些文件是驱动木马的用户层,如果将其残留,重启系统后它们就会再次释放驱动木马,我们就前功尽弃了,所以也要将其斩除。使用上面的方法进入相应位置将其删除,只要把文件名和使用cd进入的目录名换为具体的名字就可以,例如删除位于C:/Program Files/Common Files/UPDATE目录里的用户层木马update.exe,需要以下3个命令:
Cd “C:/Program Files/Common Files/UPDATE”
Attrib update.exe –h –r –s –a
Del update.exe
注意,在命令提示符里操作带空格的目录和文件时,需要用英文双引号将其引用,否则会无法达到操作目的。
做完这些事情以后,输入命令msconfig,启动系统配置实用程序,在Windows XP里许多用户会收到系统返回的信息说“msconfig 不是内部或外部命令,也不是可运行的程序”,这是因为微软把它藏到非常规目录里去了,必须输入完整的路径信息才能访问:%windir%/PCHealth/HelpCtr/Binaries/MSConfig.exe
成功运行这条命令后会出现系统配置实用程序,在它的“启动”里取消掉那个会自动恢复的项目,确定退出,不要选中“立即重启计算机”,立即再次进入msconfig查看启动项是否又恢复了,通常情况下它已经不会恢复了,这时候我们就可以重启电脑进入正常模式,再用IceSword查看,大部分已经恢复正常(无红)了,至此驱动木马已被歼灭。
这种驱动木马其实可以直接使用超级巡警专业版(AST)直接在Windows里进行简单快捷的查杀,只需要启动AST,切换到高级界面,然后点击“SSDT”列表,在里面点击鼠标右键,在出现的菜单里选中“仅显示被Hook的函数”,AST就会自动过滤正常的系统函数,用户可以方便快捷的查阅具体什么函数被驱动木马给拦截了,通常驱动木马最喜欢拦截以下函数:NtDeleteKey、NtEnumerateKey、NtQueryKey、NtSetValueKey(注册表API)、NtQueryDirectoryFile、NtDeleteFile(文件操作API)、NtOpenProcess、NtTerminateProcess(进程操作API)等,拦截了这些函数,它们就可以达到无法查看、无法删除、无法终止的目的,这样也就解释了为什么我们取消不了启动项的原因,因为相关的函数已经被拦截了,我们的操作实际上根本就没有影响到这些木马的一切。
但是如果用户遇到的是改良型的高优先级木马或者感染了不止一个驱动木马时,问题就会变得棘手起来,这也是为什么一开始我并没有直接介绍使用AST查杀的原因,早些时候的AST在遇到这种状态的情况下,会无法正常搜集到被Hook的SSDT,而显示“正常”信息,但是用IceSword却能发现异常的Hook数据,在这种情况下由于AST存在bug,用户无法通过它来发现驱动木马的踪迹,我已将此bug反馈给官方,估计下一版本已经修正。
如果用户不幸遇到这种驱动木马,他的查杀过程将会变得复杂起来……
狙杀高优先级驱动木马
在上述的步骤里我们可以查杀一般的在安全模式里无法启动的驱动木马,然而如果用户在安全模式里执行dir操作也无法列出记录下来的驱动文件名时,问题就棘手了:用户遇到了高优先级驱动木马,它们在安全模式里也能被正常加载并实施保护!遇到这种情况,大部分人只能选择彻底格式化重装系统,难道这是唯一的解决之道吗?
虽然在这种情况下,许多查杀手段都已失效,但是天无绝人之路,利用系统的特性,我们依然可以找到一线生机。
同样,首先把检测出来的驱动文件做个记录,然后进入“基于命令提示符的安全模式”里,直到dir的那一步,系统返回“找不到文件”的提示宣布了安全模式下照样运行的驱动木马的存在,不必慌张,沉住气,要记住并不是只有dir这个命令可以查看文件的。输入下面这个命令,你会发现惊喜:
Type 记录下来的文件名
如果这个驱动木马没有猖狂到封锁了某个涉及打开文件的API,用户会发现系统列出了一堆混乱的字符,这个实际上就是我们千辛万苦要找的驱动木马是否存在的依据!但是如果这时候用户继续执行更改文件属性和删除操作,将会发现一切都是前功尽弃,因为即使你执行了del命令,再次使用type或dir时,它又出现了,这是因为它已经hook了NtDeleteFile这个删除文件的API操作!难道我们又陷入困境,只能发现木马存在却无法将其删除吗?并非如此,很多人不知道Windows系统对于驱动文件的处理特性,而正是这个特性,使得我们反败为胜:当一个驱动例程已经被载入运行后,系统将不会继续锁定它的磁盘文件映射关系,也就是说这个时候无论用户是删除还是重命名驱动文件,都不会影响到当前的系统状态,直到下次重启。正是因为这个原因,驱动木马才设法拦截了相关API以保护自身驱动不被删除,即使用户将驱动文件改名,它也会因为检测不到驱动例程文件的存在而立即重新释放一个,这样一来,木马似乎就无敌了。但事实上,要破坏一个文件的方法有很多种,并非是只有“删除文件”这个途径的。
配合系统特性,其实我们只需要一条简单的命令就可以破坏驱动木马设下的完美保护,那就是:
Echo
[email protected] > 记录下来的文件名
这条命令的作用是简单的在字符界面显示一串用户输入的字符,当它配合管道操作符“>”(英文大于号)使用时,则为将用户要显示的字符直接流入指定的文件里,而“>”为覆盖文件内容,“>>”为追加文件内容,执行完这条指令后我们再次使用type命令查阅木马文件,会发现刚才一大堆混乱的字符已经被“
[email protected]”文字替换了,这样一来,驱动文件本体就被破坏,而由于这个操作未涉及删除文件,被拦截的API并不会对此做出反应,下一步,立即重启计算机进入“基于命令提示符的安全模式”,然后再次type检查驱动文件的内容是否被恢复,如果仍然保留着我们刚才输入的字符,则说明操作成功,木马的驱动模块已经被破坏了,这时候位于启动项里的文件由于没有驱动保护,也不会被启动,所以我们可以进一步删除这个启动项和指向的文件,然后删除刚才被我们修改的驱动文件,确认没有再次恢复文件后重启计算机再次进入“基于命令提示符的安全模式”,在命令提示符里输入explorer.exe启动Windows图形界面,然后再次运行IceSword检查是否存在另一个红色标记,如果运气不好,用户会发现出现了另一个文件名的驱动,记录下涉及的文件,重启计算机,继续重复刚才的type、echo等操作,直到SSDT项目里所有函数都不用红色标记标注出现为止,最后重启计算机进入正常模式,再次使用IceSword查看红色标记是否出现,以免漏杀被高优先级驱动木马的“光辉”掩盖的普通驱动木马,这是因为,当多个驱动文件都争取同一个函数拦截操作时,系统是以先后顺序和优先级别判断的,这样就造成了在高优先级驱动木马存在的时候,其它的驱动木马无法分到一杯羹,然而高优先级驱动木马被歼灭后,它们的出头之日就来临了。这时候,直接使用查杀普通驱动木马的方法即可将其全军抹杀。
手工查杀驱动木马是一件非常枯燥且烦琐的事情,用户甚至需要在执行完一个命令后就要重启一次计算机,对付一个高优先级的驱动木马至少就要重启多达3次!因此,查杀病毒始终要以预防为主,而不是亡羊补牢,养成良好的系统使用习惯和勤打补丁是每个人都要做的。
四. 结语
这是个越来越疯狂的网络时代,普通网民的网络安全已经得不到保障,即使你有正版的杀毒软件也无法避免被未知的木马和流氓软件的黑手推上一把,只能在平时加强防范,勤打补丁。
查杀完驱动木马后,用户要做的事情还有很多,首先必须使用其他安全工具如“360安全卫士”、“瑞星卡卡上网助手”等辅助手段加强扫描一次系统,确认没有被植入其他木马和流氓软件,或者将其清理出系统,然后使用360安全卫士的修复系统漏洞功能打上补丁,至此,我们成功狙杀了驱动木马。