序
2010年,反病毒(AntiVirus)与反-反病毒(Anti-AntiVirus)不论是从技术的深度、涉及的方方面面,又上升了一个层次。
行为防御、云安全技术等一些新技术不断的加入反病毒的行列,这让很多习惯基于特征码免杀的朋友(包括笔者在内)措手不及。记得冰血封情前辈在a1pass免杀一书<黑客免杀入门>的 序 写到:
然而,狼的存在,让鹿开始选择锻炼奔跑,自然选择会让孱弱的个体在生存竞争中被淘汰,留下的狼和鹿都越来越矫健……
自然的法则,使反病毒技术和免杀技术互相对抗过程中,双发都得到了很大的提高。这是可见的。
然而某天,狼的四肢开始强健时,你还等什么呢?
开源使免杀的思路得以最大限度的扩展,它的好处是不言而喻的,有了它我们可以改变程序运行的流程、功能实现的方式等等。但,很多时候我们仅有的只是一个编译好的可执行文件,那么,我们又该如何依靠的自身或者借助其它方面的力量来帮住我们的木马突破行为防御呢?
本文就以 瑞星杀毒软件、360安全卫士7.1正式版 这两款系统安全软件作为实验对象,来浅析下它们的内部Something;以及,使用INF文件突破主动防御安装服务。
正文
INF在Windows系统中随处可见,尤其被大量的应用在软件、程序安装的安装过程当中。还有病毒、木马的利用,比如前几年很火的利用autorun.inf来感染各个磁盘的根目录,使其双击即可达到运行指定木马的效果。但是如今已经被反病毒软件所查杀。
而笔者今天所讲的,也是利用INF文件安装服务,使木马突破360安全卫士、瑞星的主动防御。
要灵活地使用INF文件,那么我们还需稍微的了解下INF文件的相关信息:
INF文件
(由于内容过于繁多,此文只介绍需要用到的INF文件信息,如需查看更详细的内容,请查阅:百度百科。以下内容均来自百度百科,由笔者节选、修改)
INF文件简介
INF是Device INFormation File的英文缩写,是Microsoft公司为硬件设备制造商发布其驱动程序推出的一种文件格式,是Windows操作系统下用来描述设备或文件等数据信息的文件。
INF文件是一个由标准ASCII组成的文本文件,您可以用任何一款文字编辑器查看修改其中的内容。一般我们总是认为INF文件是系统设备的驱动程序,其实这是错误的认识,Windows之所以在安装某些硬件的驱动时提示需要INF文件是因为INF文件为该设备提供了一个全面描述硬件参数和相应驱动文件(DLL文件)的信息。就好比我们看着说明书安装电脑硬件一样,我们就是Windows系统,说明书就是INF文件。
INF文件结构
在Windows系统下,您可以用任何文本编辑软件查看、修改其中的内容。INF文件有一整套编写规则,每一个INF文件都是严格按照其规则来编写的。
规则一:INF是分节的,由许多节组成,节名使用方括号包含。某些节名由系统定义,也可以是用户来定义。每一个节名最长为255个字符(Windows 2000/XP/2003操作系统中)或28个字符(Windows 98操作系统中)。节与节之间没有先后顺序的区别,另外,同一个INF文件中如果出现两个同样的节名,则系统会自动将这两个节名下面的条目合并到一起。
规则二:INF文件中节与节之间又包含条目,节可以是由很多条目组成。每个条目等号后面的值用半角的双引号包含,如果每一个条目的等号后有多个值,则每一个值之间用“,”号分隔开。
规则三:INF文件不分大小写。
规则四:INF文件使用“;”来注释
规则五:如果一个条目的内容过多,在一行无法完全书写,则用“\”将一行内容书写为多行。
了解INF文件的规则后,接下来我们剖析下INF文件的结构。
1、Version
每个INF文件都应该包含Version节。该节中描述的条目主要是描述此INF文件支持的设备类型和适用的操作系统。
该节中包含了一个由系统定义的条目 Signature,其取值可为以下两种:
$CHICAGO$:表示该INF文件适用于Windows 98之后的操作系统。
$WINDOWS NT$:表示该INF文件适用于Windows 2000/2003/XP操作系统。
2、DestinationDirs
INF文件会指示安装程序在安装过程中,将复制文件的到硬盘上,或者删除某些文件,重命名文件等。该节的条目包含了目标文件的路径。
3、String
当某些字符串频繁的出现在该INF文件中,可以在String下增加一个字符串变量。与编程中的变量概念等同。
4、Defaultinstall & Install
这一节中描述了设备驱动程序与硬件设备的实际属性。默认情况下,首先执行DefaultInstall节,该节指定了相关操作:比如写注册表、删除文件、复制文件等等。同时又包含指向其他节的指针。
为了使文字更加具体化,下面贴出一个简单的INF文件例子,来使大家更加熟悉INF文件:
[Version]
Signature="$WINDOWS NT$" ;该INF文件适用于Windows 2000/2003/XP系统
[DefaultInstall]
DelFiles=InfDeleteFile ;DelFiles为系统定义的操作,而后面DeleteFile则是我们所定义的节。
[DestinationDirs]
InfDeleteFile=01 ;将要操作的节的目录指示为当前路径
[InfDeleteFile]
1.txt,,,1 ;删除当前目录下的1.txt文件
将以上内容保存为del.inf文件,再新建一个test.txt文本文件。右键点击"del.inf" -> 单击"安装",可以看到的结果是"test.txt"已经被删除了。
实战
纸上谈兵还不如踊跃一试。
众所周知,无论是使用ActiveX方式启动、还是安装服务启动,其本质还是其向注册表中写入相关键值来实现的。但如今360安全卫士在注册表监控方面显得非常J8。
实践过程
但是利用INF文件写RunOnce注册表不会有任何提示(写Run的话会提示),以下是思路及实践。
提示:
Run -- 运行 Once -- 一次 RunOnce -- 运行一次
RunOnce与Run同样为一个启动键值,但与Run不同的是,在启动一次(开机)后便会删除其中的键值。
如果某木马的服务端采用了写RunOnce键值来自启动,那么计算机重启一次后,我们的木马就成为一块废铁无法使用了。
是这样吗?难道真的是如此吗?非也,我提示一个关键字:do while.
什么意思呢?学过计算机编程的朋友可以知道,do while语句和while语句的不同在于do while语句至少会被执行一次!我们可以抓住“至少”这个重点词汇来分析,而结果就是:写RunOnce注册表项可以使服务端至少运行一次。
我们来想象下这个过程:
服务端运行、inf写RunOnce注册表项 -> 重启 -> 服务端运行 -> 系统删除RunOnce注册表项 -> 重启。
很清楚的可以看出结果,这个循环就到此结束了。如果在服务端中加入自动写RunOnce注册表项,如此一来,让我们的联想下……
服务端运行时调用reg写RunOnce注册表项 -> 重启 -> 系统删除RunOnce注册表项 -> 服务端运行时调用reg写RunOnce注册表项 -> 重启 …………
Bingo,一个无限循环!
高兴的同时,新的问题出现了:很多时候我们仅仅拥有的是一个编译好的可执行文件,如何加入自动调用inf安装文件来执行写入RunOnce注册表功能呢?
很多朋友已经想到了,你们的答案是否与笔者的一样:反汇编。
是的,我们可以使用反汇编来完成这么一个过程。
需要的工具:OD、PEID、LoadPE
需要的指令:PUSH(压栈指令) & Call(子程序调用指令) & JMP (无条件跳转指令)
我们以一个MD5Check来当做实验的例子。
1、使用PEID查询程序的基址、0区域信息:
这里我们选择.text区段里的0区域作为我们的实验战场。
2、使用OD载入,待程序分析完后自动停止下来,我们记录其程序的入口点:
经过上面2个步骤,我们得到如下信息:
3、使用OD载入MD5Check,按Ctrl + G,输入计算得到的0区域的内存地址,程序自动来到了一片00区域:
结果:
4、向下寻找一块00区域,依次填入:
Push 0 ;即WinExec函数参数中的SW_HIDE
Push 00407AAF ;00区域的首地址,也就是字符串的首地址
Call WinExec ;调用Kernel32.dll中的WinExec函数
JMP 00402282;为了使程序在完成我们所添加的功能后,还要执行原有的功能,因此要跳回程序的原入口并记录Push的内存地址。
5、选中被修改的区域,右键 -> 复制到可执行文件 -> 选择,把程序保存为Test.exe,关闭OD:
6、用LordPE打开Test.exe文件,在<入口点>中填入程序新的入口点。
(计算公式:新入口点内存地址 - 镜像基址 = 入口点,即00407ACC - 00400000 = 00007ACC)
点击保存,关闭LordPE。
7、然后创建一个call.bat文件,放到与test.exe同目录,其内容如下:
rundll32.exe setupapi,InstallHinfSection DefaultInstall 128 C:\inst.inf
在C盘根目录下创建一个inst.inf文件,内容如下:
[Version]
Signature="$CHICAGO$"
[DefaultInstall]
AddReg=test
[test]
HKCU,Software\Microsoft\Windows\CurrentVersion\RunOnce,test,0,"C:\test.exe" ;这里指向服务端的路径
到这里,基本的工作就算完成了,为了验证其效果,我们运行一下test.exe,经过修改后的MD5Check成功写入了注册表:
下面是一个安装服务的INF文件实例,安装后会创建一个名称为“Darkst”,描述信息为“Tested By Miku_fl0”的服务,内容已经做了详细的注释。
[Version]
Signature="$WINDOWS NT$"
[DefaultInstall.Services]
AddService=Darkst,,Add_Evil_Service ;服务名称
[Add_Evil_Service]
DisplayName=Darkst ;显示名称
Description=Tested By Miku_fl0 ;服务描述
ServiceType=0x10 ;服务类型
StartType=2;启动类型
ErrorControl=0 ;错误控制
ServiceBinary=C:\windows\rav.exe ;服务要加载的exe文件路径
以上方法依然可以过瑞星的主动防御和行为防御。
把<文件监控>、<系统加固>、<木马行为防御>、<木马入侵拦截>均调到最高等级,把inst.inf文件复制到C盘根目录下,在cmd下输入:
rundll32.exe setupapi,InstallHinfSection DefaultInstall 128 C:\inst.inf
瑞星行为防御提示:发现未知木马
然而我们调用的是system32目录下的rundll32.exe,此文件为系统文件。
偶然间想起360的文件名检查模式,那么我们来尝试改文件名,将rundll32.exe复制到C盘根目录,重命名为rav.exe,在cmd下输入:
rav.exe setupapi,InstallHinfSection DefaultInstall 128 C:\inst.inf
瑞星没有任何反应。
再使用reg文件写RunOnce启动项时,瑞星提示:发现未知木马病毒
而我们调用的却是系统的reg命令。
笔者的电脑除了日常使用的黑软之外,其它均无感染或者其属性木马病毒。那么,是否可以得出行为防御就不存在特征码呢?
当然,仅仅凭这一点来做出结论是很鲁莽的。毕竟反病毒软件的内部机制方方面面,我们无法仅仅通过一面来确定它所拥有的全部。
但是话说回来,行为防御,行为、行为?从字面的意思就可以很好的理解,行为即指程序运行时所做的动作。再结合全部的字面意思我们再来理解下,木马行为防御,可以用一句话来高度概括:从木马运行时本身会做的动作进行识别、判断。
如果这样的概括是对的,那么如此一来,就可以知道,木马的行为本身就是特征码,比如正常文件是不会自动删除的,而木马则会在安装后进行自删除。但是网络上的程序如此之多,不能仅仅依靠自删除这一项来判断是否为木马。
行为都是有时间顺序的,我们从再木马本身的角度出发,可以在脑海中显现出一个木马安装过程的图示:
运行 -> 读取配置信息(文件操作) -> 写入注册表启动项(注册表操作) -> 拷贝文件到指定目录 -> 运行服务端 -> 自动删除 -> 与某个IP连接并开始通信(还有其它操作:比如注入进程、加载某文件等等等)
以上是木马安装的一个大概流程图,或许,木马行为防御的"特征码"由以上与普通程序非常不一样的行为所构成。那么,只要破坏其中一个或多个流程,使它们顺序不一样,或者删除一个或多个流程,那么,是否可以破坏掉行为防御呢?如果上面的猜测为真,那么在考虑突破行为防御时,就要从木马自身出发,来进行免杀实验了。
(以上仅仅为笔者的猜测,未进行任何实质性的实验)
由于"行为"这个词高度概括了程序运行时具体的指令,其针对性是非常小的,这样就不需要繁杂的病毒特征码库来识别。显然这样做的好处是显而易见的,其缺点相信朋友们也有目共睹了,误杀……(可怜的reg.exe和rundll32.exe)
总结
其实在反汇编中完全可以使用echo这个命令写入inf和bat,接着进行调用,再使用del命令删除,这样可以使文件数不会过于繁多。但实际上笔者只给出了一个简单的示例,因为笔者认为,屏幕前聪明的你一定可以举一反三,由笔者抛的砖,引出你们的玉。
孙子曰:知己知彼,百战不殆。
免杀正式如此,只有了解反病毒软件的工作原理,在当中寻找出反病毒软件的破绽,然后通过对自身的提高,才能见到胜利的曙光!
实际上这么一个过程,都是摸索着过来的,虽然艰难,但也快乐!
以上就是笔者实践的一个过程、实践后的思考,如有误区,请明指出。