作为咨询机构的最后一个工作,在信息系统上获得代码执行之后,“逃避”防病毒是我们工作的一部分。确实有必要证明对漏洞的利用,而不是仅仅报告它们。如果AV检测到我们使用的工具,客户端通常会忽略此漏洞,因为他们不相信该漏洞所引起的风险。

我们注意到Windows Defender从Metasploit Framework的内存中检测到metsrv.dll,杀死我们的壳。检测是由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 split实用程序和“二进制搜索”方法将样本大小从200 kb减小到13 kb:将样本拆分为分为两部分,都输入到Windows Defender,然后将检测到的部分分成另外两部分。重复直到有可能,以最大程度地减少测试用例。
反汇编mpengine.dll并不是很有帮助,因为IDA Pro在其中发现了超过30k的函数。
用Pin进行代码覆盖率分析允许将此设置缩减为3k函数,这对于静态分析而言仍然太多了。
可以在gdb中调试mpengine.dll。我在字符串“ Win64 / Meterpreter.A!dll”上放置了一个监视点,以查看是否可以找到一个有趣的函数在此位置读取数据,也许是在接近判决时间的时候。即使观看点被两次触发,由于代码的大小仍然丢失。影响AV的判决。运行16个小时后,该工具将整个文件作为签名的一部分返回给我,这看起来像是错误的结果:使用split实用程序不可能找到确切的签名,因为我希望这两个签名太多了个字节或从签名中删除了有用的字节。

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

要实现我的目标我需要采取哪些步骤? Tavis Ormandy发表的论文:Sophail:Sophos Antivirus的批判分析

在第3页上,他显示了“ Attention 629”文件的签名。我试图达到相同的结果。当然,我可以攻击3k功能并从此处开始工作,但是我想Tavis有一种更智能的方法,那就是我正在寻找的答案类型。

评论

欢迎来到SEE。那13K是二进制的哪一部分?码?数据?标头数据?

没错,我忘了提到那13K是PE标头,并且是.text部分的一部分。

您是否看过Alexei Bulazel的Windows Defender研究? mpengine.dll已在某种程度上进行了分析。您不必从头开始。他的工具在这里:github.com/0xAlexei/WindowsDefenderTools

是的,我有。但是,像大多数黑帽子说话者一样,阿列克谢只发布了他的研究的一小部分。如果您浏览他的仓库,您会发现他保留了必要的代码和工具作为“读者练习”。此外,他从mpengine.dll的调试符号中受益,我无法动手调试。另外,我不想逃避仿真器,而是找到静态签名/检测模式。

我认为您是在问一个错误的问题。当然,您可以像Alex一样花半年的时间来反转检测。但是,您将回到原来的问题:如何逃避检测。实际上,您可能无需知道第一个的确切答案就可以实现第二个(即使可能会给您一些提示),所以我个人将直接从规避开始。

#1 楼

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


注释掉main中的一半代码,并检查是否检测到生成的DLL。由于您的目标是逃避静态检测,因此DLL不能完全正常运行现在不重要。
如果未检测到,请取消注释第一次注释的代码的前半部分,然后重新检查检测。否则,请注释掉上一步中使用的代码的后半部分,然后重新检查检测。
重复此二进制搜索方法,直到将其范围缩小到导致检测的特定函数为止。
重复步骤1-3,获取该函数的代码以及任何其他嵌套函数的调用。最终,您应该到达一个位置,不再进行任何函数调用,并且注释掉一行代码即可更改文件的检测状态。
检查对应于最后一行的字节(机器代码)的模式代码并对其进行突变以测试mpengine的检测标准的鲁棒性。

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

评论


@UnitedCoconut您对这个答案的异议是毫无根据的。在这种情况下,可伸缩性和对源代码的访问显然不是问题,因为我们正在处理单个开源二进制文件。此外,您的问题未提及您在这里的担忧。请不要粗鲁。无论如何,我不确定您的期望。这里没有魔术或秘密技巧-无法逆转mpengine.dll。

– julian♦
18-10-25在23:25

@United Coconut如果您甚至不愿意在源代码可用时在几行源代码中四处寻找答案,那么当没有答案时您有什么希望呢?

–Samantha
18-10-26在3:03

@SYS_V如果我听起来很粗鲁的话,请放心,这不是我的意图。可伸缩性是一个问题,因为由于获得这些结果所需的时间量,我宁愿获得持久的结果,而我的告诉我mpengine.dll在metsrv.dll中找到了多个签名。萨曼莎(Samantha):我愿意随意摆弄代码,但是这样做可以使我的工作可重用并且具有长期弹性。我将根据您的评论澄清我的答案。

–plowsec
18-10-26在7:03

#2 楼

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

我与以下人员分享了一些发现:您可以在此处看到Rapid7团队:https://github.com/rapid7/metasploit-framework/issues/10815

下面是复制粘贴内容,用于遵守该论坛的规则:

假设您有一个FUD分级器,并且对阶段进行了编码。 Windows Defender仍然可以检测您的meterpreter会话,因为它具有内核级回调,可以检测何时将图像加载到内存中(就像每个竞争性AV一样)。这是通过PsSetLoadImageNotifyRoutine&co。

完成的。在这些事件上,Windows Defender会对加载图像的内存区域执行扫描,并搜索STATIC签名(这远非机器学习和行为分析...)

检测到的常见工件有:


常量,例如字符串(“ [*]试图将用户%s添加到域控制器%s上的组%s中” )=>如此高的分数,几乎可以说是EICAR测试,尽管WD会检查它是否属于遵循PE格式的文件中。用于查找每个人复制粘贴多年的API);
硬编码的shellcode片段(每个在base_inject.c中,例如x48 \ xC1 \ xE8 \ x20);
DLL导出(用于例如WD和Kaspersky都搜索了导出文件“ ReflectiveLoader”。

有些字符串的得分很低,但在判决中仍然很重要。如果您具有上述任何一个元素,那么您将得到肯定的标记,删除低分不会有任何影响。这样的字符串的一个示例是“ scheduler_insert_waitable”。

总而言之,“隐藏哟妻子隐藏你的弦” ...