对于 C、C++、Rust
等二进制编译语言,可以利用编译时混淆来隐藏子例程和一般指令流的真实行为。
根据语言的不同,可能存在不同的方法。这里选择 C++
,因此会涉及两个:LLVM
混淆和模板元编程。
对于LLVM
混淆,目前最大的公共工具是Obfuscator-LLVM
。该项目是 LLVM
的一个分支,它通过混淆生成的二进制文件来增加一层安全性。当前实现的新增功能如下:
总之,该工具生成的二进制文件通常更难被人类/杀毒软件/EDR
静态分析。
另一方面,模板元编程是一种 C++
技术,允许开发人员创建在编译时生成源代码的模板。这允许在每次编译时生成不同的二进制文件,创建无限数量的分支和代码块等。
有两个可用于此目的的公共框架如下:
andrivet
的 ADVobfuscator
fritzone
的 obfy
对于这个 PoC
,将使用第二个,因为它更容易使用。
此外,对于 PoC
,使用TheD1rkMtr
的 AMSI_patch
作为默认二进制文件进行混淆,因为它是一个非常简单的 C++
项目。
首先来看一下Ghidra
下的基础二叉函数树。
正如所见,分析起来并不难。可能会在第 3 个 FUN_
例程下找到 main
函数。
这看起来很容易分析和理解它的行为(在这种情况下通过 AMSIOpenSession
修补 AMSI
)。
现在看一下混淆后的二叉函数树。
这看起来非常难以静态分析,因为有许多嵌套函数。而且,正如我们所看到的,这些是基于模板引入的功能。
这些都是简单的垃圾函数,但对于隐藏真实行为非常有用。
现在进行最终测试, 在真实 Windows
系统上进行测试POC
。请注意,由于二进制补丁 AMSI
通过 PID
作为参数给定进程,因此 PoC
将与第一种方法非常相似;为当前 PowerShell
会话修补 AMSI
以逃避 Defender
的内存扫描。
而且,正如所见,它起作用了,而且 Defender
没有静态地或在运行时停止二进制文件,从而允许为进程远程打 AMSI
补丁。