很多人用visual studio开发控制台应用程序的时候经常会遇见QVM。在本文中,我们将了解一些背后的原因以及缓解措施。
基本概念
AV/EDR 可能会使用多种不同的方法来分析二进制文件,以便对其做出决定。这包括动态分析(在目标执行时对其进行分析)和静态分析(分析目标的属性)。静态分析可能包括分析导入表以确定目标使用的函数和 DLL、分析嵌入在目标中的字符串和字节序列、目标本身的 MD5 或 SHA256 哈希,还可能包括对目标中熵的分析。这些静态分析用于确定目标是否值得执行。
而我们所讨论的qvm主要涉及静态分析阶段。
让我们测试一下我们的“绝对不可能是恶意”的应用程序
让我们用 C 语言编写一个简单的小程序,然后将它提交到 VirusTotal 来看看我们能得到多少检测报毒。
可以看到即便你只是一个简单的“hello world”也难逃这些过于激进的扫描程序。更别说还有高手,从个人的经验来看,某些玩意儿几乎会将所有visual studio新生成的 PE 文件标记为恶意。
其实以上说法也不尽然,如果你用Debug编译的话,是没问题的
而同样的程序,Release编译立刻就会报毒
Why?
在绕过这种检测之前,先让我们来了解一个叫做“熵值”的概念。
熵是衡量一组数据中随机性程度的指标。在信息论和网络安全的背景下,大多数指的是香农熵。这是一种特定的算法,它返回 0 到 8 之间的值,接近 8 的值表示数据非常随机,而接近 0 的值表示数据非常同源。
一般恶意软件作者倾向于依赖打包、压缩和加密来混淆他们的工具,以逃避基于签名的检测系统。而香农熵可以很好地指示PE文件中是否使用了打包、压缩和加密(这些行为越重,熵值越高)。
So,让我们查看“helloworld“不同发布版本的熵值
Debug
Release
这里.text
节直接飙升到了6.01。
那如果安全解决方案是通过测量文件中的熵值来确定我们的exe文件可能是恶意的,那么如何降低熵呢?
最简单的就是从编译入手
1. 使用动态运行时链接
将运行时从 /MT
(静态链接运行时)切换为 /MD
(动态链接运行时)。动态链接会减少静态运行时库的嵌入量,从而降低熵值。
操作步骤:
打开 Visual Studio 项目。
转到 项目属性 → C/C++ → 代码生成。
将 运行时库 从
/MT
改为/MD
。
2. 禁用编译器优化
编译器优化会生成复杂的代码模式,导致熵值增加:
将优化级别设置为
/Od
(禁用优化)。操作步骤:
转到 项目属性 → C/C++ → 优化。
将 优化 设置为
禁用优化 (/Od)
。
3. 最小化链接的库
静态链接不必要的库会增加熵值:
确保只链接项目真正需要的库。
手动检查项目中引用的
.lib
文件,移除不必要的依赖。
4. 去除调试信息和元数据
调试信息或元数据会显著增加可执行文件的熵值:
在 Visual Studio 中:
在 项目属性 → C/C++ → 常规 → 调试信息格式 中,将选项设置为
无
。
5. 填充和对齐段
通过对可执行文件的段进行填充或对齐,可以降低熵值:
添加
/ALIGN:512
到链接器命令行参数中。
其实之前写过一个更详细的:
完成以上操作重新生成之后,我们再来看熵值
运行