常见的防病毒软件(据我所知)使用一种蛮力类型的方法,他们获取文件的哈希值并将其与数千个已知病毒的哈希值进行比较。只是他们拥有具有超快 SSD 的服务器,并且他们将哈希上传到该服务器并进行非常快速的搜索,还是我对它们如何工作的理解完全错误?
杀毒软件怎么这么快?
披露:我为反病毒供应商工作。
因为大多数反病毒引擎都是为了保护端点而诞生的,即使现在对其中许多来说,端点保护也是业务的主要部分,所以现代反病毒引擎针对扫描端点进行了优化。这种优化包括很多东西,例如:
不扫描不包含可能感染您计算机的感染的文件;
记住扫描了哪些文件,除非文件被修改,否则不会再次扫描它们;
尽可能优化文件类型的扫描 - 例如,在扫描可执行文件时,只需要扫描其中的某些部分。这最大限度地减少了磁盘读取,并提高了性能。
一个常见的误解是 AV 引擎使用哈希。他们通常不这样做,原因有以下三个:
- 首先是绕过哈希检测非常容易,根本不需要修改实际的恶意代码;
- 其次,使用哈希不允许您实施任何类型的主动保护——您将只能检测到您看到的恶意软件;
- 计算哈希需要读取整个文件,而对于某些文件(例如可执行文件),这不是必需的。并且读取非 SSD 硬盘驱动器上的整个文件是一项昂贵的操作 - 大多数 AV 引擎应该比计算哈希值更快地扫描一个大型干净的可执行文件
常见的防病毒软件(据我所知)使用一种蛮力类型的方法,他们获取文件的哈希值并将其与数千个已知病毒的哈希值进行比较。仅仅是他们拥有具有超快 SSD 的服务器,并且他们将哈希上传到该服务器并进行非常快速的搜索,还是我对它们如何工作的理解完全错误。
我认为您正在考虑那些仅进行散列的在线“防病毒软件”,与 SmokeDispenser 提到的(更有效和先进的)基于启发式和基于规则的防病毒软件相比,它们的性能相当差。
对于一个用例,散列是一个不错的选择,您将一个病毒文件发送给很多人,并且您使用的 AV 引擎会经常更新,以便在您遇到病毒之前接收并存储散列。例如,在这种情况下,您可以立即将电子邮件附件标记为病毒/网络钓鱼/勒索软件/特洛伊木马等,并且您可以以最少的计算成本做到这一点。如果您无论如何都必须阅读整个文件并且您有良好的连接(这两件事都是因为您是一个邮件服务器),那么额外的I/O 费用可以忽略不计。
由于这是所有用例中的一小部分,因此(好的)防病毒软件不会(仅)使用哈希。
但是,检查哈希真的非常非常快。您根本不需要 SSD 或任何复杂的硬件。
想象一下(即使它不完全那样工作)你有一个十六进制哈希值,比如“baadc0debaadbaad”,并且想要验证它是否存在于包含一千亿个哈希值的存档中。
创建存档时,您在硬盘上创建了 256 个目录,并将它们命名为“00”到“ff”(十进制为 0 到 255)。在其中的每一个中,您都创建了 256 个目录,其名称又从 '00' 到 'ff'。在每个目录中再次放置 256 个目录,在 AB/CD/EF 形式的每个第三级目录中放置所有以“abcdef”开头的哈希,分为 256 个文件,从“00.txt”到“ ff.txt”。
所以哈希'baadc0debaadbaad'最终出现在一个文件“C:/ba/ad/c0/de.txt”中,内容如下:
...
baadc0de81f872ac Ebola virus
baadc0debaadbaad Dark Avenger virus
baadc0debf31fe11 known clean file
...
该文件中有多少个哈希?如果哈希是均匀分布的,只需将一千亿除以文件数即可。有256个文件夹有256个子文件夹有256个子文件夹有256个文件,所以文件数是256*256*256*256 = 4294967296。
一千亿除以这个数字大约是二十四。这就是该文件中预期的散列数(平均)。
因此,如果给您一个哈希,并要求您在这千亿哈希之间手动找到它,您只需单击相应的一级文件夹,单击第二级,单击第三级,打开相应的文件并读取二十四个哈希值。您可能会在不到 30 秒的时间内完成,“显然”每秒检查了 30 亿个哈希值。用手。由你自己。这似乎是不可能的,这只是很好的数据组织。
计算机可以更有效地做同样的事情。
基于规则的扫描
一个更复杂的情况是如何在您(最初)一无所知的文件中扫描已知和分析过的病毒。
在这种情况下,操作系统必须执行病毒,因此病毒不能出现在任何地方——它必须是操作系统主动寻找它的地方。通常,病毒会通过隐藏某处(例如,在数据区域中)并将其可执行区域的开头替换为对其自身的调用来感染可执行文件。这意味着在大多数情况下,您只需要扫描可执行区域并确保它是干净的(当然,病毒总是以巧妙的方式隐藏在不太可能的地方,所以现实比我刚才说的要复杂一些)。
防病毒软件会查找相同的位置,在这种情况下会对文件执行基于规则的分析。这类似于哈希搜索:您检查在敏感区域遇到的第一个字节,并根据它的值在其他地方查看另一个字节。执行这种操作的算法有时称为自动机。例如,查看文本字符串是否为“Hello, World!” 或“黎明攻击”,你会检查第一个字母;如果是 H,您将忽略“黎明攻击”的所有检查。
对于程序,多态性和自加密使这变得更加复杂——事实上,两个不同的代码(比如 2+2 和 2*2)可能会产生相同的结果,所以你需要更多的检查(“如果第一个单词是你好,你好,还是好...”),以便确定您发现了可怕病毒Salutations, Cosmos 的变体!. 对于自加密代码,您可能需要找到一种算法来破解代码(如果它在很短的时间内可行)或专注于识别自解密例程,否则病毒将无法使其自身可执行由系统。
但是,通过仔细选择选择树,您将能够快速收敛到单一可能性(病毒名称)或确信不存在已知病毒。
启发式
这是最复杂(也是最慢)的一种分析,但也是最强大的,因为它可以让您强烈怀疑是否存在一种前所未有的病毒。您可以将启发式算法视为许多基于规则的小型识别器;体积小可以提高速度,抵消它们的数量多。每个识别器都会识别一段代码执行一个动作,例如解密代码、试图获得系统特权、打开和写入文件、挂钩系统调用、重写内存中的代码、渗透操作系统等等。许多合法程序做所有这些事情中的一项或多项,或者看起来这样做(例如解密和解压缩)看起来会非常相似。还有一些程序被加密以保护知识产权,而不是隐藏恶意代码)。为每个操作建立一个“分数”,超过一定阈值的可执行代码可能被视为可疑。
启发式引擎的具体细节当然比这复杂得多;他们需要平衡速度、可靠性(当他们说它可疑时,它必须是可疑的)和敏感性(当它可疑时,他们需要能够说它是可疑的)。
实际上,它们非常复杂,通常被杀毒公司严格保密,并且经常被吹捧为“智能”到“人工智能”。
需要不断更新规则(仍然寻找十年前已经灭绝的病毒毫无意义),以及不那么紧迫但同样重要的调整启发式方法,这就是为什么防病毒质量的一个重要参数是它的更新频率(即使在某种程度上,一个出色的启发式引擎可能允许不那么频繁的更新,而一个不可能完美的启发式引擎可能根本不需要)。
优化
如果您是防病毒软件,并且能够加载到操作系统内核中以拦截任何磁盘写入操作,并且确定在不激活您的代码的情况下无法启动操作系统(即您不能是蓝色的),那么在您不知情的情况下,磁盘上的任何文件都不能被修改。此时,您可以跟踪哪些文件已被扫描并发现是干净的,并且只扫描自上次扫描以来修改过的文件,这只是总数的一小部分(您可能甚至忽略未受感染进程执行的磁盘写入;只要您允许这样一个事实,即用例如 Javascript 编写的病毒可以通过某种方式请求另一个进程(例如 WSCRIPT)代表它写入磁盘)。
虽然防病毒软件可能会上传样本进行分析(见下文),但这并不是检测的工作方式。
此外,基于签名的系统越来越不常见(因为它们很容易被规避)。它们也不会按照您期望的方式工作。
签名建立在特定区域或二进制文件的一部分之上。如果位置未知,则让签名窗口在二进制文件中“滑动”。所以这比你想象的中间产品更复杂,并且生成的样本要多得多。
尽管如此,搜索这些签名并不慢,但也不是很快。使用防病毒软件时通常会有明显的延迟。
尽管如此,这样做并不需要大量的磁盘空间或 RAM(尽管有一些)——当 4K 视频被解码以显示时,还有很多事情要做。
除了签名之外,还有启发式和行为分析正在发生,因此有问题的二进制文件会被沙盒化并分析其行为。如果采取的措施可疑,则此类二进制文件可能会被阻止——此时样本可能会被发送给反病毒供应商进行进一步分析。
总结:
它不是那么快。但是这些操作并不复杂,它们需要服务器并且不能由工作站自己完成。
顺便说一下,这样的服务器基础设施必须是巨大的。如果工作对工作站来说很辛苦,那意味着一台强大的服务器可能会为少数客户提供服务,而供应商可能有 3 亿份副本来支付和运营数百万台服务器。