【IT168 编者按】在经济利益诱使之下,病毒、木马日益泛滥。而病毒与反病毒是一对共生体,当病毒泛滥的时候,反病毒机制也越发成熟。UTM等设备的出现,预示着反病毒引擎将不仅应用于杀毒软件(单机版和网络版),病毒过滤体制正在延伸(嵌入)到网络各个层面的设备之上。本文为反病毒引擎应用于更多领域提供了一定的参考。
一、AV 旧逻辑面临的问题
病毒与反病毒产品的长期对抗,使AV技术不仅形成了一套完整的技术体制,也形成了一套逻辑和法理体制。这使反病毒软件的工程规划形成了很多特定的共性原则。这些共性原则首先被从实践中总结形成,回头来又指导着反病毒引擎乃至反病毒工具的设计。
1995年,笔者曾总结了反病毒体制的共性原则44条,目前还作为我们研发的基本内部原则,因此戏称为AV辩证法。基本条目包括:
计算机病毒归根到底是一种程序。
计算机病毒的特征码是从程序体或者程序体的某种处理结果上,选取的可以唯一确定计算机病毒类别的标识。
计算机病毒最根本的判据应该是程序特征码或其他的内容相关特性。
有害或主观有害是一个文件被提取特征加入病毒特征库的唯一原因。
计算机病毒的有害,是指程序包含着用户所不期待的的对信息系统的影响。
一个确定的程序是否应该被反病毒软件检测,是基于明确的标准。
反病毒软件的工作原则是保证数据安全和系统的正常运行。不应因清除功能或完成其他的功能,产生有悖于上述原则的影响。
计算机病毒的清除过程是感染的逆过程
用户对于反病毒产品拥有下列权利:
定义权:反病毒软件可以默认的设置,但用户具有定义进行何种模式的检测以及是否清除的权利。
知情权:用户有权指导反病毒软件在系统中做过什么。
备份权:反病毒工具应该提供用户对带毒文件备份的手段。
反病毒软件应该识别包裹中的病毒,在具有算法授权的情况下,可以清除包裹中的病毒,但不能删除包裹本身。
病毒监控的基本模式应该以阻止带毒文件的运行(获取系统控制权)为目的(即前报原则)
随着应用环境与病毒技术的不断发展,这些总结一部分已经走入了矛盾之中。这些矛盾产生的根本原因是信息系统进一步复杂化和用户要求的复杂化。以下例子可以作为这些矛盾的佐证:
事例一 红色代码(IIS-Worm.RedCode.b)留下的CMD后门。红色代码蠕虫将系统的cmd.exe 复制到IIS默认的scripts目录下,名为root.exe。
问题条目:计算机病毒最根本的判据应该是程序特征码或其他的内容相关特性。
矛盾:传统的反病毒技术解决是与非的问题,判定是非的唯一判据是程序内容。而这里cmd.exe如果在系统目录下则是一个正常程序,而在scripts目录下则变成了一个后门。显然决定它有害、无害的差异,不是内容,而是特定的路径位置和权限。
过去我们可以将是否有病毒的问题为Y=f(C)的问题(Y 是检测的结果,而C是内容),但现在是否变成了y=f(C,P,R,…)的问题,这是需要我们思考的。
事例二:Psexec工具。PS系列工具是sysintel公司出品的一组行命令工具集,但其中的远程注入命令psexec却被大量口令猜测蠕虫所采用,而其中pskill也被一些蠕虫用于删掉病毒监控程序。
问题条目:一个确定的程序是否应该被反病毒软件检测,是基于明确的标准
矛盾:这只是一个比较典型的例子。反病毒软件的手到底应该伸多长。到底应该被反病毒软件检测的标准是什么?目前很多反病毒产品都加入了adware的检测,这是否是合理(法)的?虽然x-file概念应运而生,但并不能从根本上解决判定困惑。
事例三:DIY蠕虫,自身是一个自解压包裹。另外还有一些蠕虫在硬盘大量生成自身的一个zip备份文件。
问题条目:反病毒软件应识别包裹中的病毒,在具有算法授权的情况下,也可以清除包裹中的病毒,但不能删除包裹本身。
矛盾:传统反病毒软件的基本假定是,“包裹文件是正常文件,但包裹中可能含有病毒”。而DIY蠕虫则是一个自解压包裹,他自身就是病毒。这样就影响了检测分支。
而类似bagle这样的蠕虫在硬盘大量生成自身的一个zip备份文件,一些反病毒软件删除不掉不是技术问题,正是逻辑问题。
事例四:民间评测广泛采用了网上的一些“样本包”,实际上这些包的质量很差,多数病毒没有活性,也有一些文件根本就不是病毒。但各公司普遍添加了这些“不是病毒”的文件特征。
问题条目:有害或主观有害是一个文件被提取特征加入病毒特征库的唯一原因
矛盾:病毒公司之间的攀比效应,一个无意义的文件,一家公司添加后,会带动其他公司的添加,而只是为了获得民间评测的高分,这是否有价值?同时,病毒纪录的不断增加也会降低扫描速度,同时如何取舍检测性能与数量?站在一个更进一步的角度,大量没有活性的DOS病毒的特征,是否可以从效率优化的角度从库中摘掉了呢?
事例五:很多蠕虫在系统上开设一些后门,如将guest用户加入administrator组。它留下类似remote administrator之类的工具以便远程控制等等。
条目:计算机病毒的清除过程是感染的逆过程
矛盾:反病毒软件是否是否要负责恢复病毒对系统的所有修改,是否应该负责处理漏洞?谁能保证guest加入admin组一定是病毒行为,而不是用户愿意为之。用户行为与病毒行为的重叠,导致处理后用户行为流失如何处理?同时这是一个收敛的工作吗?
事例六:对行为监控和文件评估的批评。
条目:病毒监控的基本模式应该以阻止带毒文件的运行(获取系统控制权)为目的。(前报原则)
问题:虚拟机和启发式扫描是我们推崇的未知检测机制,其对于未知感染(外壳)型病毒意义比较明显,但对于未知特洛伊木马/后门等程序则几乎没有什么意义。
那么基于行为判定的后报技术是否可以被提倡呢?
事例七:主动遏制的提出与尝试。远程清除dvldr引发的争论。
条目:用户对于反病毒产品拥有的权利…
问题:由于蠕虫的出现,病毒已经从"谁感染谁受害" ,向"谁感染谁害人"演化,那么当节点构成较大网络影响的情况下,是否允许有关部门从远端不经用户许可清除病毒,什么样的手段是可以接受的?技术如果可以实施,相关的法律问题又是什么呢?
对AV的挑战可以分为三类,技术挑战(如加密、变形、EPO等等)、架构挑战(如宏病毒、脚本病毒等等)和逻辑挑战。上述任何一个事例都不是什么技术难题,而是对传统反病毒引擎基本架构和基本逻辑产生了微妙的影响。
二、细粒度处理
在一般技术人员的感觉中,反病毒体系最重要的是引擎和病毒库,但还有一个因素不应该被忽视,那就是配置控制。因为引擎的工作粒度和分支往往是配置决定的。在引擎技术基本稳定前提下,只有库与配置有更大的扩展空间。
图一:AV三要素 |
那么我们看一下传统的病毒库结构,这是某国外反病毒公司产品的库结构,在库中有4种类型的特征纪录。
传统的引擎基于上面的库工作,通过类型三、四的纪录,检测95%的病毒(特征码检测)。通过类型一、二检测剩余5%比较特殊的病毒(独立模块检测)。通过处理参数进行超过80%的病毒处理,通过处理模块处理剩余20%的病毒。
这样的AV引擎需要实现三个配置控制基本点:
- 对象控制:检测哪些对象。
- 行为控制:如何处理,是否清除、是否删除等等。
- 效力控制:检测强度。
最传统、也是应用最广泛的配置方法就是INI控制,下面是一个实际的例子:
对象控制
[object]
Memory=Yes;是否检测内存
Sectors=Yes;是否检测引导扇区
Files=Yes;是否检测文件系统
Packed=Yes;是否脱壳
Archives=Yes;是否检测包裹
MailBases=Yes;是否检测邮件文件
MailPlain=Yes;是否检测编码文件
FileMask=2;扩展名检测范围
UserMask=;用户定制扩展名
Exclude=No;是否不检测定制的扩展名
ExcludeMask=;不检测扩展名的定义
行为控制
[Actions]
InfectedAction=0;是否清除病毒
InfectedCopy=No;是否备份病毒
InfectedFolder=Infected;备份目录
SuspiciousCopy=No;是否备份可疑文件
SuspiciousFolder=Suspicious;备份目录
Report=Yes;是否生成日志
ReportFileName=Report.txt;日志文件名
效力控制
[Options]
Warnings=Yes;近似警告开关
CodeAnalyzer=Yes;代码分析开关
RedundantScan=Yes;多重扫描开关
对于传统的反病毒工具工作环境,这样的控制粒度是足够的,但对于更复杂的环境,已经显现了问题。
下面我将举例说明——
应用案例一 同一个引擎,作为单机反病毒软件使用和邮件服务器反病毒模块的要求显然是不同的。
I-Worm.Nimda.e是一个感染式的蠕虫,在Local处理的时候,应该作为一个PE感染式文件处理,但对邮件服务器,则可以抛弃。
Win95.CIH是一个感染式病毒,当检测到这个病毒,无论对于Local还是邮件服务器,则都需要进行感染式病毒的清除操作,还原出原有文件。
这样区别的性质在于,Win95.CIH没有mail发送自身的特性,如果出现在网上,应该是用户主要发送的可执行程序。而Nimda则反之。这种处理粒度的要求,已经对不同类别的病毒在不同环境下进行不同处理,超出了传统引擎控制粒度的能力。
应用案例二 如果一台网络病毒检测设备,有若干响应模块:
- 消息告知
- 追加式邮件告知
- 反馈式邮件告知
- 断连接
- …
这些响应模块必然要工作与某种策略之下,才能达到比较好的效果。
比如一些邮件蠕虫发件人是随机的,采用反馈式发送不仅毫无意义,反而制造了大量流量,而一些邮件蠕虫的收件人是bot生成的,即使在SMTP中检测到,那么追加式发送的结果也是会造成大量无意义的流量消耗。客观来说,确实有时我们收到莫名其妙的来信,说我们对外发出了病毒。或者收到了病毒。
理性的用户会要求如表一的控制粒度。
表一:邮件蠕虫通知模块控制开关表 |
从这些案例可以看出,工作于复杂环境之下的反病毒引擎,对控制与细粒度处理的能力都超出了传统。
三、细粒度的可嵌入引擎
目前网络安全层次的不断下移,CISCO推出了自防御网络,提高内容过滤、访问控制和身份认证的能力,其中之一就是通过与反病毒厂商合作扩展了流病毒过滤的体制,而winxp sp2对安全特性的强化也值得关注。可以病毒过滤体制正在延伸(嵌入)的各层次设备上。我们必须为反病毒引擎适应更复杂的使用环境的准备。
一个独立的具有合理调用接口的病毒过滤引擎可以有很多种应用,如下表:
表二 可嵌入引擎的应用形态 |
根据我们在一、二中的论述可以看出,嵌入设备或其他应用环境的反病毒引擎是细粒度的引擎。
除了必须具有原有的反病毒产品的能力之外,我们认为这种引擎的最基本的要素是:
1、内存引擎
引擎必须彻底脱离I/O与API,相关IO与API要用外围层封装。才能保证能在不同环节下的有效嵌入。下图对内存引擎,做了一个诠释。可见,与IO有关的文件读取、以及外围处理模块,被放在引擎之外。
图二、内存引擎 |
如下是内存引擎的调用释例:
/* 扫描参数结构 */
typedef struct _AVLF_SDK_SCAN_PARA
{
char * pBuffer; /* 待检测缓冲区指针 */
unsigned long ulSize; /* 待检测内存的大小 */
const char * pDescription; /* 描述信息 */
int bUnpack; /* 是否解包 */
int bKill; /* 是否杀毒处理 */
int bKilled; /* 是否杀毒成功 */
} AVLF_SDK_SCAN_PARA,*PAVLF_SDK_SCAN_PARA;
/* 设置收报人 */
AVLEACHSDK_API int AVLF_SDK_SetReciver(IReportReciver *pReciver);
/* 扫描:返回0未发现病毒,返回1发现病毒,病毒详细信息在收报人类接收 */
AVLEACHSDK_API int AVLF_SDK_Scan(PAVLF_SDK_SCAN_PARA pParamter);
2、递归引擎
现代的反病毒引擎必须从以格式识别模块为先导的分支引擎,演化为递归引擎。
图三、递归引擎 |
关于分支引擎,大家可以参考笔者在2002 xcon会刊中所给出的引擎示意图,在图三所表示的递归引擎中,不再有像过去那种分支引擎的分析器入口和出口的概念。一个递归引擎满足如下的条件:
- 分析器之间是并列的,并没有绝对的先导模块。
- 输出结果有优先性,发现病毒优先级最高,而需要进一步预处理级别最低。
- 原则上,分析器串行工作,结果优先的引擎前置。
- 引擎为单输入、多输出引擎
一个分支的引擎不仅可以避免Mcafee对自解压文件感染病毒检测bug的尴尬,而且可以容易的对抗ArchBomb.zip这样的恶意程序对杀毒软件的“DoS”攻击。
3、可移植引擎
很多优秀的反病毒引擎都是有很强的移植性的,这种移植性建立在obj结构在x86 win平台和unix平台的相似性基础上。但可嵌入引擎工作环境可能是x86架构,也可能是PPC这种非x86架构。那些x86汇编编写的模块是移植的障碍。因此我们需要纯C引擎。
4、高可控引擎
在不同环境下的病毒处理,不仅应该与病毒的感染性有关,而且要与病毒的"特性"相关。这就要求控制粒度可以到达病毒个体,同时病毒库需要提供更多的信息。而病毒库的标志信息产生了特性控制,见下表:
这是一个在传统病毒库上,加入病毒特性信息的例子。这里通过一个int建立8个标志位,用来维护类似收件人是否为构造,发件人是否为真这样的标志,当然位操作会降低程序的速度。这里只是一个简单的demo。
对传统控制层次的第二个必要的补充,是在内部调试控制开关和用户配置开关之间,建立一个中间层。这个中间层,以一组半公开的配置开关构成模版。以适应防火墙、GAP、独立反病毒产品这些不同的工作形态。
5、精确处理引擎
当然这样的引擎的最后要求,是希望引擎实现一个接近完美逆过程的处理。除了传统的感染型病毒、宏病毒操作脚本之外,实现一个更为细腻的系统操作脚本。
下图,我们的一个细粒度可嵌入引擎的模型:
客观来说:AV辩证法不是一成不变的,是发展的动态的规则。不仅需要我们的总结,也需要我们的补充和突破。
细粒度的的可嵌入引擎是我们对于现实的应对,是我们的理想以及我们对AV技术的理解。
附录 Archbomb.zip对AV 软件的DoS攻击:
Archbomb.zip是一个构造的,能够造成反病毒软件停止响应并导致系统资源耗尽的逻辑炸弹。
这是一个五层的zip包裹,大小为42,374 字节,每层中又包括16个包裹,让我们每层只解开1个包裹,来看结构 ——
D:\work\today\ArcBombZIP>tree/f
卷 DATA 的文件夹 PATH 列表
卷序列号码为 0006FE80 4C1D:BFBB
D:.
│ lib 0.zip
│ lib 1.zip
│ lib 2.zip
│ lib 3.zip
│ lib 4.zip
│ lib 5.zip
│ lib 6.zip
│ lib 7.zip
│ lib 8.zip
│ lib 9.zip
│ lib a.zip
│ lib b.zip
│ lib c.zip
│ lib d.zip
│ lib e.zip
│ lib f.zip
│
└─lib 0
│ book 0.zip
│ book 1.zip
│ book 2.zip
│ book 3.zip
│ book 4.zip
│ book 5.zip
│ book 6.zip
│ book 7.zip
│ book 8.zip
│ book 9.zip
│ book a.zip
│ book b.zip
│ book c.zip
│ book d.zip
│ book e.zip
│ book f.zip
│
└─book 0
│ chapter 0.zip
│ chapter 1.zip
│ chapter 2.zip
│ chapter 3.zip
│ chapter 4.zip
│ chapter 5.zip
│ chapter 6.zip
│ chapter 7.zip
│ chapter 8.zip
│ chapter 9.zip
│ chapter a.zip
│ chapter b.zip
│ chapter c.zip
│ chapter d.zip
│ chapter e.zip
│ chapter f.zip
│
└─chapter 0
│ doc 0.zip
│ doc 1.zip
│ doc 2.zip
│ doc 3.zip
│ doc 4.zip
│ doc 5.zip
│ doc 6.zip
│ doc 7.zip
│ doc 8.zip
│ doc 9.zip
│ doc a.zip
│ doc b.zip
│ doc c.zip
│ doc d.zip
│ doc e.zip
│ doc f.zip
│
└─doc 0
│ page 0.zip
│ page 1.zip
│ page 2.zip
│ page 3.zip
│ page 4.zip
│ page 5.zip
│ page 6.zip
│ page 7.zip
│ page 8.zip
│ page 9.zip
│ page a.zip
│ page b.zip
│ page c.zip
│ page d.zip
│ page e.zip
│ page f.zip
│
└─page 0
0.dll
这个攻击的核心在这个0.dll。
D:\work\today\ArcBombZIP\lib 0\book 0\chapter 0\doc 0\page 0 的目录
2004-09-16 11:26 <DIR> .
2004-09-16 11:26 <DIR> ..
2004-09-16 11:26 4,294,972,416 0.dll
可见这个0.dll的大小为4G,其他所有的最低层包都是如此,即如果一个反病毒软件要检测完这个arcbombzip.zip需要 解出 165 =1048576个这样的4G文件,这足够导致反病毒软件扫描到这个文件时进入假死状态,而如果监控程序打开了检测包裹的开关。则av monitor会立即死机。
0.dll有如此高的压缩比,是因为整个文件全部是AA,基于字典压缩自然会取得很高的压缩比。
seg000:00000000 AA AA AA AA AA AA AA AA-AA AA AA AA AA AA AA AA ""
seg000:00000010 AA AA AA AA AA AA AA AA-AA AA AA AA AA AA AA AA ""
seg000:00000020 AA AA AA AA AA AA AA AA-AA AA AA AA AA AA AA AA ""
如果一个反病毒引擎是一个简单的分支引擎,即在offset =0找到char=”PK”,就走入extract Archive模块,则不可避免的导致程序被DoS。而对一个递归引擎来说arcbombzip具有如下的平行特性(2进制数据流,ZIP文件)。根据我们正文中的优先原则,可以被2进制流分析器先行检测。
如图,是通过Saker病毒分析机提取arcbombzip的特征。由于2进制流分析器给出了作为优先特性的病毒特征,因此不会走入extract Archive模块。