对 Metasploit 框架的metsrv.dll 的Windows Defender 签名进行逆向工程

逆向工程 艾达 调试 二元分析 数据库 反汇编者
2021-06-10 08:26:04

作为咨询机构的渗透测试员,在信息系统上获得代码执行后“逃避”防病毒是我们工作的一部分。确实有必要证明漏洞被利用,而不是简单地报告它们。如果 AV 检测到我们使用的工具,客户通常会忽略该漏洞,因为他们不相信它造成的风险。

我们注意到 Windows Defender 从内存中的 Metasploit Framework 中检测到 metsrv.dll 并杀死我们的 shell。检测由 mpengine.dll 完成,或者通过模拟二进制文件上的某种标准完成,或者是 DLL 中的字节模式。

现在问题的上下文已经很清楚了,下面是实际问题:我如何才能准确地指出该文件的签名是什么?

在你回答之前,这里是我已经得出的结论:

  • Windows Defender 的扫描引擎会在 Metasploit 加载到内存时检测到metsrv.dll。
  • 我可以使用 Taviso 的loadlibrary在 GNU/Linux 上静态重现检测,使用以下命令:

./mpclient metsrv.x64.dll main(): Scanning metsrv.x64.dll... EngineScanCallback(): Scanning input EngineScanCallback(): Threat HackTool:Win64/Meterpreter.A!dll identified.

  • 我使用 GNU拆分实用程序和“二进制搜索”方法将样本大小从 200 kb 减少到 13 kb :样本被分成两部分,两部分都提供给 Windows Defender,然后检测到的部分被拆分还有两个部分。重复直到可能,以最小化测试用例。
  • 反汇编mpengine.dll不是很有用,因为里面有IDA Pro发现的3万多个函数。
  • 使用 Pin 进行代码覆盖率分析可以将这个集合减少到 3k 个函数,这对于静态分析来说仍然太多。
  • mpengine.dll 可以在 gdb 中调试。我在字符串“Win64/Meterpreter.A!dll”上放置了一个观察点,看看我是否能找到一个有趣的函数,可以在这个位置读取,可能是在接近判决时间的时候。仍然因为代码的大小而丢失,即使观察点被触发了两次。
  • GitHub 上一个名为 avwhy.py 的脚本允许通过一次更改一个字节并记住影响 AV 判决的字节来推断来自 AV 的签名。运行 16 多个小时后,该工具将整个文件作为签名的一部分返回给我,这看起来像是一个错误的结果:使用 split 实用程序我不可能找到确切的签名,因为我希望要么有太多字节或从签名中删除了有用的字节。

如您所见,我已经在这方面花费了数小时。目标是找到确切的签名,而不是通过对metsrv.dll应用某种转换来逃避它我认为这是一个有趣的逆向工程挑战,但我现在被困住了。

为了实现我的目标,我需要采取哪些步骤?

编辑:为了澄清我想要做的事情,这是 Tavis Ormandy 自行发表的论文:Sophhail:对 Sophos Antivirus 的批判性分析

在第 3 页,他显示了文件“注意 629”的签名。我正在努力达到同样的结果。当然,我可以攻击 3k 函数并从这里开始工作,但我认为 Tavis 有更智能的方法,这就是我正在寻找的答案类型。

2个回答

您可能考虑的一种方法是编译metsrv.dll源代码的不同版本,然后观察哪些被检测到哪些未被检测到。例如:

  1. 注释掉一半的代码main并检查是否检测到生成的 DLL。由于您的目标是逃避静态检测,因此现在 DLL 的功能不完整并不重要。
  2. 如果未检测到,取消注释第一次注释的代码的前半部分并重新检查检测。否则,注释掉上一步中使用的代码的后半部分并重新检查检测。
  3. 重复这种二分搜索方法,直到您将其缩小到导致检测的特定函数为止。
  4. 对该函数的代码和任何进一步嵌套的函数调用重复步骤 1-3。最终你应该达到一个点,没有进一步的函数调用,注释掉一行代码会改变文件的检测状态。
  5. 检查与最后一行代码对应的字节模式(机器代码),并尝试对其进行变异以测试mpengine的检测标准的稳健性

您还可以考虑对原始代码使用不同的编译器或构建选项(例如,使用调试符号或不同的优化级别进行编译),以查看是否会使检测消失。如果是这样,将两个二进制文件与fc其他工具进行比较可能会指出检测的原因。

我通过对引擎执行带外攻击并在大量变异文件的帮助下找到了所有签名。还有很多逆向工程。我不得不对大量误报进行分类,并且需要手动工作,因此这仍然不是理想的方法,但显然比其他建议的方法更具可扩展性。

我已经与 Rapid7 团队分享了一些发现,你可以在这里看到:https : //github.com/rapid7/metasploit-framework/issues/10815

以下是为了遵守本论坛规则的复制粘贴:

假设您有一个 FUD stager 并且您对 STAGES 进行编码。Windows Defender 仍然可以检测到您的 Meterpreter 会话,因为它有一个内核回调来检测图像何时加载到内存中(就像每个竞争 AV 一样)。这是通过 PsSetLoadImageNotifyRoutine &co 完成的。

在发生这些事件时,Windows Defender 会扫描加载图像的内存区域并搜索 STATIC 签名(远离机器学习和行为分析......)

常见的检测到的工件是:

  • 诸如字符串之类的常量(“[*] 尝试将用户 %s 添加到域控制器 %s 上的组 %s”)=> 如此高的分数,它几乎是一个 EICAR 测试,尽管 WD 检查它属于一个文件遵循PE格式。
  • 大整数(例如 ReflectiveLoader.h 中的 0x6A4ABC5B,这是一个 rot13 哈希值,用于定位每个人复制粘贴多年的 API);
  • 硬编码的shellcode片段(base_inject.c中的每一个,例如x48\xC1\xE8\x20);
  • DLL 导出(例如,WD 和卡巴斯基都会搜索导出“ReflectiveLoader”)。

有些字符串的分数非常低,但在判决中仍然很重要。如果您具有上述任何元素,您肯定会被标记,并且删除低分的元素不会产生任何影响。这种字符串的一个例子是“scheduler_insert_waitable”。

总而言之,“隐藏你的妻子隐藏你的字符串”......