目前流行木马病毒技术原理及防范概观
由于时间匆忙,有不少错误及疏漏之处,感谢轩辕小聪指出.
已经修改都分内容.
Lightning(kxsystem@163.com)
引言:
现在木马/病毒考验的不仅仅是杀毒软件,更多的则是用户的安全意识与手工杀毒的能力。随着木马品种的增多以及手法的翻新,我们必须不断地在实践中学习,以提高自己的计算机安全水平。在这篇文章里,我将给大家介绍一些较为高级的病毒/木马检测与防范技术,同时也“推销”一下自己的Freeware.
本文适合于有一定反病毒基础的人群.目前新兴的木马技术:
1. SSDT 修改/恢复
这是一个从古墓中捡来的东西,严格意义上不能算做新技术。记忆中最早的ARK IceSword早在四年前就拥有这项技术了,SSM及几乎所有的HIPS也将它做为法宝。不过有些人出于技术上炫耀的目的,将这些源代码都公开了,结果导致网上现成的源代码一堆一堆的,也方便了像磁碟机这样的玩意儿来乱搞。不过所幸的是,这些源代码的通过性都很差,蓝屏的概率是非常大的。但是对于一般用户而言就不是很好玩了——至少机子反复重启并不是一件令人愉快的事情。
微软做的事情总是那么糟糕,所有的Native API 都会通过SDT来进入系统内核,这本来是为了方便统一接口,结果微软出乎意料地将进入SSDT表的钥匙KeServiceDescriptorTable导出了,结果导致一个extern 语句就让这庞大的工程刹那间暴露出了致命的漏洞。
那这样一说,SSM等HIPS不就不安全了么?是的,在很多人眼中SSM是那样的完美,但是我们仍然将遗憾地宣布,SSM的监控几乎完全基于SSDT HOOK,一但SSDT被复原,SSM将成为一个空壳,在SSM启动时它会悲哀地向你诉苦:“我的驱动丢失了,怎么办啊,快帮我找找”。
当然驱动并没有丢失,safemon.sys仍然好好地躺在%system%\Drivers\目录下,只不过它HOOK的SSDT表项被恢复了,它便如此地堕落了下去,甚至没有勇气再次修改SSDT,将钩子重新挂上。
不过对于以上的描述,没有必要过于心惊胆战。因为SSDT表是处于高地址空间的(一般为0x80000000~0xFFFFFFFF,当然开了3GB后也可能为0xC0000000~0xFFFFFFFF),一般修改这里面的数据需要Ring0权限。Ring3下的程序无法利用kernel32.dll导出的API WriteProcesssMemory来直接操作这块内存,但是它可以通过调用一些特殊的API来操作它们,比如说ZwOpenSection,ZwSystemDebugControl,(这些东西一会我们再说),或者直接加载驱动以达到目的。
但是几乎所有公开的进Ring0技术都被SSM堵了个死,原因当然是进Ring0也需要直接或者间接地调用Native API,而这些API会被SSM拦截并报警。
接下来的事情就是用户的了,如果用户不能根据自己的反病毒经验而阻止病毒/木马加载驱动,那么SSM的“坚固”防线将宣告终结。
正如上面所说,防御恶意木马SSDT HOOK 恢复必须从进Ring0时将其按倒,不能有丝毫手软,至于HIPS的使用,请参考各自的手册。
2. FindWindowA/FindWindowExA + SendMessageA/PostMessageA
FindWindowA可以查找标题为特定字符串的窗口,或者指定的窗口类名,SendMessageA可以向找到的窗口发送消息,这本来为是多进程软件而服务的,结果也成了木马的伎俩。这好比计算机内部的“垃圾邮件”。
怎么说呢,FindWindow这个API可算是基本上没有起到多少好的作用,反而是个病毒几乎被会调用它来查找安全工具的窗口,调用它成功找到窗口后,直接一个SendMessage(hWnd,WM_CLOSE,0,0);,可爱的安全工具就这样被自己的关闭功能关闭掉了。当然也有不少病毒喜欢发一些垃圾消息.
但是IceSword等工具在经历了熊猫烧香的“垃圾邮件”折磨后,作者PJF终于将签有他大名的标签“pjf(ustc)”去掉了。其它安全工具也不断进行了防范。但是许多杀毒软件不并不能像IceSword那样使用随机的窗口名,所以被FindWindow搜索到依然是一个令人头痛的问题。
要解决这个问题,估计还得靠杀毒软件产商自己的努力,用HIPS保护杀毒软件毕竟不是长久的办法。
3. CreateFile,ZwOpenSection,ZwSystemDebugControl,ZwSetSystemInformation.
这些API的功能十分强大,甚至有些可以直接操作物理内存或者驱动器。以CreateFile为例,在管理员账户下使用它几乎可以打开所有的设备,如果向这些设备写入垃圾码,则会造成相当严重的后果,比如MBR被破坏等等。
HIPS对这些的防范已经不错了,对于HIPS提出的“底层XX读取/写入”用户一定不能掉以轻心,对于未知程序像读取物理内存,读取物理磁盘的行为一定要坚决阻止。
4. Autorun.inf
在驱动器目录下的Autorun.inf可以在双击打开驱动器的时候被执行,因此许多木马/病毒喜欢不断地创建和监视Autorun.inf,以确保它重启后依然被激活。
有许多工具可以动态监视并清除它们,像DelBox之类的,平时中毒后不要双击打开硬盘,要先使用杀毒软件进行查杀。
5. 镜像劫持
说起来比较可怕,其实仅仅是修改注册表的一处而已,这些东西会在CreateProcess的调用链(可以在stack中查看)执行时在用户态进行重定向,可以破坏很多杀毒软件。但是对于绿色的安全工具却无能为力,因为它们的名字可以任意更改,逃过镜像劫持的追杀。因此镜像劫持可以算做是技术含量不高,效果却很惊人的感染方式。
当然镜像劫持可以轻松地被HIPS监控,也很容易被注册表编辑软件删除。
当然也有很多其它的XX方法,不过不算十分典型,这里就不列举了。
这里简单地介绍防御上述手法的方法:(注:由于受SSM的局限,许多防御并不彻底)
以SSM为例:
1.右击SSM图标,规则中启用除网络功能之外的所有监控(如果你没有安装防火墙,也可以启用“网络”监控)。
2.打开主界面,规则 = 》 程序,右击应用程序=》特别权限,如果看到“底层磁盘读取,物理内存存取”被打勾并且你没有把握确定这个程序是好是坏,那么请设置为“询问”。
3.注册表 =》添加针对"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options"的规则,如二楼图。
4.添加针对安全工具Sreng,IceSword,Autoruns,DelBox等的规则,保护其合法权益。如三楼图。
下面的内容针对有一定计算机编程基础的人群:
可定制PE文件扫描工具
对于目前病毒越来越具有规模化,越来越喜欢制作多个副本的情况,偶写了一个小程序:FileScanner,使用它可以自定义特征码,然后对PE文件进行扫描。可以快速地定位病毒并将其统统删除。
点击这里下载:
http://aegisys.googlegroups.com/web/KsFileScanner(1.05).rar?gda=HdBWF0wAAADGskCzVeeKIBOls76S9nfM-G6moTAgTG4EJ9jNy1geJGG1qiJ7UbTIup-M2XPURDSYe5Kt6HRmm_YIzs_r3PYSlbbRNqx2f4jV8kqnPAwvRg压缩包里的KsScanLib.kvr是特征码文件,你可以用记事本打开它来添加特征码,保存后重启主程序即可使用.
特征码的格式为:
<pCode=nStart-nEnd:pLinkCode|...!dwScore#Info>
其中pCode的为开头特征(最少2字节),然后nStart-nEnd为开头特征匹配后搜索的代码范围。比方说如果开头特征匹配,FileScanner将会搜索距开头指令nStart~nEnd的区间,pLinkCode为特征的二进制数据,如果匹配成功则会再搜索下一个特征,同样,下一个特征也是以nStart-nEnd:pLinkCode的形式添加的。特征之间可以用|隔开。
特征写完后,!后面的内容为可疑分数,当然你也可以理解为其它什么的。#info后为显示的信息。
下面以查Aspack1.12壳为例.首先用OD打开一个用Aspack加过壳的EXE
这是开头的一些反汇编代码:
(没有去花)
0048D001 > 60 PUSHAD
0048D002 E8 03000000 CALL FileScan.0048D00A
0048D007 - E9 EB045D45 JMP 45A5D4F7
0048D00C 55 PUSH EBP
0048D00D C3 RETN
将0048D002地址处用NOP填充一个字节,就可以看到真正的代码
// 实际代码,By 轩辕小聪
0048D002 E8 03000000 CALL FileScan.0048D00A; 这个CALL到了0048D00A
0048D007 NOP; // 原来这里是E9
0048D008 EB 04; JMP SHORT 0048D00E; 跳到这段代码后接着运行
0048D00A 5D POP EBP; 注意是跳到这里来的,先CALL再POP定位自身地址
0048D00B 45 INC EBP
0048D00C 55 PUSH EBP
0048D00D C3 RETN; 跳回到了0048D008
几乎所有的ASPACK壳的开头都差不多是这个样子,而且基本上只有ASPACK1.12里才会出现这样的代码,我们于是可以很简单地写过滤代码,即二进制数据.
1.先写60E803000000,这些东西在aspack1.12加过的壳中是不会改变的.
2.在一定的范围内,会出现E9花指令,因而可以在基于上一条规则的2-8字节偏移处查找E9,如果找到则继续.
3.注意到PUSH EBP 和 RETN 指令,这两条指令相当于JMP EBP,一般的程序不会这样写,但是Aspack会,因此我们也把它作为特征.即55C3,在上一特征2-8偏移内寻找.
最终写出特征:
<60E803000000=02-08:E9|02-08:55C3!10#Aspack2.12>
例子:(查壳用)
KsScanLib.kvr
<60E803000000=02-08:E9|02-08:55C3!10#Aspack2.12>
<60E8=02-04:0000|02-04:EB|02-04:87DB!10#Aspack2.10>
<60E9=00-04:3D040000!10#Aspack2.11>
<60BE=06-08:8DBE|06-08:5783CDFFEB!10#UPX Shell>
<8725=06-08:619455A4B680|06-16:33C9!10#FSG 2.0>
<89085045436F6D70=08-12:63743200!10#PECompact 2.x>
<558BEC6AFF=10-30:535657!5#Microsoft Visual C++ 5.0/6.0@>
<5589E583EC08=10-30:8DB426000000005589E5!5#Bloodshed Software Dev-C++ 4.9.9.2@>
图为全功能版的KsSuperSword中的KsFileScanner.