瑞星卡卡安全论坛技术交流区反病毒/反流氓软件论坛 【参赛】【原创】目前流行木马病毒技术原理及防范概观

123   1  /  3  页   跳转

【参赛】【原创】目前流行木马病毒技术原理及防范概观

【参赛】【原创】目前流行木马病毒技术原理及防范概观

目前流行木马病毒技术原理及防范概观

由于时间匆忙,有不少错误及疏漏之处,感谢轩辕小聪指出.
已经修改都分内容.

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.

附件附件:

下载次数:706
文件类型:image/pjpeg
文件大小:
上传时间:2008-3-2 13:33:24
描述:
预览信息:EXIF信息



最后编辑2008-04-05 16:53:11
分享到:
gototop
 

图:

附件附件:

下载次数:623
文件类型:image/pjpeg
文件大小:
上传时间:2008-3-2 15:43:27
描述:
预览信息:EXIF信息



gototop
 

图:

附件附件:

下载次数:642
文件类型:image/pjpeg
文件大小:
上传时间:2008-3-2 15:45:24
描述:
预览信息:EXIF信息



gototop
 

学习了!
希望以后多多指教、多发些这类好帖子。

10分
gototop
 

有些看不懂,不过文章可读性、可操作性很强,给10分……
gototop
 

“微软出乎意料地将进入SSDT表的钥匙KeServiceDescriptorTable导出了,结果导致一个extern 语句就让这庞大的工程刹那间暴露出了致命的漏洞。”

所以我就说磁碟机作者相当白痴(见http://forum.ikaka.com/topic.asp?board=28&artid=8418945&page=1第8楼),既然要加驱动了,在驱动里一下就能定位SSDT,何必还用那么辛苦的办法去找ntoskrnl.exe的重定位表呢?
不过我当时说是找ntoskrnl.exe,其实也不太准确,因为实际上磁碟机当时是用ZwQuerySystemInformation(SystemModuleInformation)来得到内核驱动列表,来确定第一个加载的内核模块的映像名。敢情它还考虑到CPU为AMD系列时加载的不是这个。

“FindWindowA可以查找标题为特定字符串的窗口”

严格来说,应该是“可以查找标题或窗口类名为特定字符串的窗口”。同样以磁碟机为例,为什么IceSword还是被制了呢?因为它查的还是IceSword主窗口和子窗口采用的特殊的类名,以此定位IceSword。当然,磁碟机其实是用EnumWindows,在其回调函数里做这些判断的,但效果和FindWindowA类似。

另外,不一定SendMessage发WM_CLOSE,再次以磁碟机为例,发送垃圾消息也是个“好办法”(详见http://hi.baidu.com/yicong2007/blog/item/ac9205389f02daf6b311c770.html

“这些东西会在CreateProcess执行时在用户态进行重定向”

具体来说,是在CreateProcessInternalW中,通过调用ntdll.dll导出的LdrQueryImageFileExecutionOptions来检测。(详见我之前的粗略分析“系统对Image File Execution Options的检测流程小探”,链接http://hi.baidu.com/yicong2007/blog/item/53cf343ffd52bfef55e7234a.html

以上提到一些具体的细节问题,给出一些我以前相关的心得,也可以让读者们更好地理解闪电这篇文章。
gototop
 

好人啊

学习咯

这样的贴才叫好啊

真希望后面各贴还有精彩
gototop
 

“这是开头的一些反汇编代码:

0048D001 > 60 PUSHAD
0048D002 E8 03000000 CALL FileScan.0048D00A
0048D007 - E9 EB045D45 JMP 45A5D4F7
0048D00C 55 PUSH EBP
0048D00D C3 RETN”

……
反汇编结果不对!
0048D002 E8 03000000 CALL FileScan.0048D00A
0048D007 - E9 EB045D45 JMP 45A5D4F7
这明明是花指令干扰的结果……

这是一段入口点混淆的代码,正确的反汇编结果应该是:

0048D001 > 60 PUSHAD
(下面开始入口点混淆)
0048D002 E8 03000000 CALL FileScan.0048D00A; 这个CALL到了0048D00A
0048D007 DB 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

运行顺序: 0048D002->call到0048D00A->0048D00D,RETN回0048D008->跳到0048D00E

从0048D002-0048D00D之间这段内容,作用其实就是最后又跳到其下面一行代码,即0048D00E去运行了。

所以把0048D002-0048D00D这段内容全改为nop的话,也不会影响其运行。

之所以要有这段代码,是壳用来混淆入口点,对抗反汇编,尤其是静态反汇编的,要的就是闪电帖子里那个错误的反汇编结果。其实单步一下就知道是怎么回事了。

所以:
“2.在一定的范围内,会出现E9跳转,因而可以在基于上一条规则的2-8字节偏移处查找E9,如果找到则继续.”

实际上这里的E9只是个花指令,不是真正的跳转。
gototop
 

【回复“轩辕小聪”的帖子】
多谢点评!
学习了.
gototop
 

“Ring3下的程序无法利用kernel32.dll导出的API WriteMemory来直接操作这块内存”

kernel32.dll没有导出一个API叫WriteMemory,只有WriteProcessMemory(内部调用ntdll.dll导出的NtWriteVirtualMemory),WriteProcessMemory传入的句柄参数如果是GetCurrentProcess得到的自身进程句柄的话,那实际上就是在操作自己进程的内存空间。所以这里应该属笔误。
gototop
 
123   1  /  3  页   跳转
页面顶部
Powered by Discuz!NT