自动重构Meterpreter绕过杀软

前言此文章记录了我们对杀毒软件某些方面的研究,以及我们如何设法自动重构Meterpreter以绕过我们所遇到的每个AV / EDR 。虽然下面详细介绍了每种技术的思想和字符串混淆过程的实现,但我们决定在以后的文章中发布有关API导入隐藏/系统调用重写的详细信息,以使此内容尽可能简短 。源代码位于https://github.com/scrt/avcleaner
大多数公司通常采取防御措施来保护其信息系统免受攻击,在这些措施中,杀毒软件或EDR等安全软件通常是必不可少的工具集 。尽管过去几年来绕过任何类型的恶意软件检测机制非常容易,但如今这样做无疑需要付出更多的努力 。
另一方面,在POC本身被反病毒软件阻止的情况下,与漏洞相关的风险交流变得更具有挑战性 。尽管理论上可以说有可能绕过检测并保留它,但实际上这样做可能会增加强度 。
鉴于此,需要能够绕过杀毒软件 。使事情稍微复杂化的是,在SCRT,我们尽可能地使用公开可用的开源代码工具,以展示我们的工作可以被任何熟练使用它们的人复制,并且不依赖于昂贵的私人工具 。
 
问题现状现在的社区通常喜欢将任何防病毒的检测机制归类为静态或动态 。通常,如果在恶意软件执行之前触发了检测,则将其视为一种静态检测 。但是,值得一提的是,杀软也可以在恶意软件执行期间调用静态检测机制(例如签名),以响应诸如进程创建,内存中文件下载等事件 。无论如何,如果我们想对任何类型的安全软件使用旧的Meterpreter,我们都必须对其进行修改,使其满足以下要求:

在文件系统扫描或内存扫描时,绕过任何静态签名 。绕过“行为检测”,这种行为通常与绕过用户界面API hooking有关 。
但是,Meterpreter包含几个模块,整个代码库总计约700’000行代码 。此外,它会不断更新,这意味着运行项目的私有分支肯定会导致扩展性很差 。简而言之,我们需要一种自动转换代码库的方法 。
 
解决方案经过多年绕过防病毒软件的实际经验,我们发现恶意软件检测几乎都是基于字符串,API hooks或两者的结合 。
即使对于实施机器学习分类的产品(例如Cylance),一个没有字符串,API导入和可挂钩API调用的恶意软件也可以像足球射门一样穿过Sergio Rico的防御网络 。
Meterpreter具有成千上万个字符串,不会以任何方式隐藏API导入,并且可以使用用户界面API hook轻松拦截敏感的API,例如WriteProcessMemory 。因此,我们需要以自动化的方式对此进行补救,这将产生两个潜在的解决方案:
源到源代码重构LLVM在编译时混淆代码库 。
显然,后者将是首选方法,这是许多流行的研究得出相同的结论 。主要原因是,转换遍历可以只编写一次,而可以独立于软件的编程语言或目标体系结构重复使用 。
自动重构Meterpreter绕过杀软

文章插图
 
但是,这样做需要有用Visual Studio以外的编译器编译Meterpreter的能力 。尽管我们已于2018年12月发布了一些更改工作,但在一年多之后,正式代码库的采用仍然是一个需要持续的过程 。
同时,我们已决定不顾一切成本的实施第一种方法 。在对源代码重构的最新技术进行了彻底的回顾之后,libTooling(Clang / LLVM工具链的一部分)似乎是解析C / C ++源代码并对其进行修改的唯一可行的选择 。
注意:由于代码库高度依赖Visual Studio,因此Clang无法解析Metepreter的很大一部分 。但是,仍然有可能以一半的概率绕过目标防病毒软件 。在这里,我们可能遇到源到源转换相对于编译时转换的唯一优势:那就是编译时转换要求整个项目进行编译而没有任何错误 。而源到源转换可以允许成千上万的编译错误 。而你只会得到一个不完整的抽象语法树,这非常好 。
 
字符串混淆在C / C ++中,字符串可能位于许多不同的上下文中 。libTooling并不是一个足够好的工具,因此我们应用了帕雷托法则(也即二八定律),将研究范围限制在Meterpreter代码库中最可疑的字符串出现的代码上:
【自动重构Meterpreter绕过杀软】函数参数列表初始化
 
函数参数例如,我们知道,在以下情况下,ESET Nod32将标记字符串ntdll为可疑:
ntdll = LoadLibrary(TEXT("ntdll"))但是,用以下方式重写此代码段将成功绕过检测:
wchar_t ntdll_str[] = {'n','t','d','l','l',0};ntdll = LoadLibrary(ntdll_str)


推荐阅读