Waffles Crypt 是一款多功能的 C/C++ 工具,用于加密和混淆 shellcode。它支持 XOR、RC4 和 AES 加密,具有自定义的 MAC、IPv4 和 IPv6 反混淆功能,不依赖于 Windows API。您可以对密钥进行 XOR 加密并在运行时对其进行暴力破解,无需存储它们。它还允许您结合这些技术以实现最大程度的规避!
简介
我开始这个项目是为了练习我在 Maldev Academy 学到的加密和混淆技术。我的目标是创建一个工具,它不仅允许我结合这些技术,而且每次都能生成独特的、随时可用的代码,确保它只需简单的复制和粘贴就能按预期运行。
以下是可用的选项:
Waffles Crypt 使用
如前所述,您可以灵活地执行简单的加密或混淆,也可以组合使用多种技术,例如 AES 加密和 IPv4 混淆。您甚至可以同时应用所有可用方法,如上图所示!
该程序生成包含解密和反混淆所需函数的文件,如下所示:
以下是 AES 解密文件的片段,使用运行时 XOR 密钥强制破解和混淆:
你可以直接将此代码复制到你的 Visual Studio 项目中,它将与新加密的 shellcode 无缝协作:
让代码像乐高一样模块化
我的目标是使代码尽可能模块化,以便于重复使用。
例如,我将所有 AES 解密函数存储在名为 的字符串中。这样,每当脚本使用 AES 解密时,aes_functions我只需添加该字符串即可。aes_functions
另一个示例是带有运行时暴力破解密钥选项的 AES 加密。我添加了xor_functions和bruteforce_key_functions字符串,它们对于在运行时暴力破解密钥和解密密钥都至关重要。
这种模块化方法对于整合反混淆所需的功能也被证明是有用的,如下所示:
使用结构存储菜单选项
为了让界面更加人性化,我选择了菜单而不是命令行参数。然而,这使得将用户选择的选项存储在变量中变得很困难。
在处理项目中的大量单个文件时尤其如此,正如我所做的那样:
我开发的解决方案是使用 C 结构来存储用户选择的所有选项。这样我就可以将结构作为单个参数传递,而不是多个变量:
创建自定义反混淆函数
如前所述,我开发了用于 shellcode 反混淆的自定义函数。
例如,在对 IPv4 混淆的 shellcode 进行反混淆时,您通常可以使用 WinAPI 函数RtlIpv4StringToAddressA。这简化了反混淆过程,因为您只需要提供 IPv4 地址,它就会转换回 shellcode。
然而,依赖此类 API 函数可能会引起怀疑,因为 EDR 可以轻松检测到你正在将 IP 地址转换为 shellcode,而这种操作在合法应用程序中并不常见
为了避免这种情况,同时保留 shellcode 混淆的好处,我创建了自定义反混淆函数,这些函数实现起来并不特别困难。
我用 C/C++ 编写了这些函数,这增加了一些复杂性。但是,使用GeeksforGeeks等资源,您可以轻松创建自己的函数。
理论上,如果您了解混淆过程,将 IPv4 地址转换回 shellcode 非常简单。
例如,要将 shellcode 转换0x12 0x13 0x14 0x15为 IPv4 地址,您可以转换0x12为其十进制等效值并使用sprintf如下方式存储它:
// Function takes in 4 raw bytes and returns them in an IPv4 string format
char* GenerateIpv4(int a, int b, int c, int d) {
char* Output = (char*)HeapAlloc(GetProcessHeap(), 0, 32);
sprintf(Output,""%d.%d.%d.%d"", a, b, c, d);
return (char*)Output;
}
这将输出 IPv4 地址18.19.20.21。
要逆转此过程,您可以使用GeeksforGeeks教程将地址按点分开。然后,将数字字符串转换为整数,atoi()并将它们存储在整数数组中,如下所示:
int main()
{
char str[] = "18.19.20.21";
// Returns first token
char *token = strtok(str, ".");
int temp_array[4];
// Keep printing tokens while one of the
// delimiters present in str[].
while (token != NULL)
{
temp_array[index] = atoi(token);
token = strtok(NULL, ".");
}
return 0;
}
// temp_array = {18,19,20,21}
接下来,你只需要将整数转换为十六进制并将其存储在无符号字符数组中。如下所示:
sprintf(temp_char, "0x%02X", temp_array[i]);
使用此方法,您可以创建自己的自定义反混淆函数!
了解逃避技术如何影响二进制熵
这个项目还帮助我了解哪些技术可以降低二元熵的水平。
二进制熵可以作为文件是否恶意的指标。恶意软件通常包含大量 shellcode,这些代码具有高度随机性,因此与良性代码相比,其熵值较高。相比之下,包含结构化数据(例如英文文本)的文件由于其模式更可预测,因此熵值较低。
下面是来自《实用安全分析》的一张图片,演示了如何使用文件熵进行威胁检测和搜寻。
因此,维持“良好”的熵值对于保持隐秘至关重要。
以下是使用 AES 加密的各种技术的熵值。
有趣的是,在运行时强制密钥的技术具有最低的熵。这可能是由于涉及的代码量较少。在较大的程序中,混淆 shellcode 或结合多种技术可能会产生更好的结果。
另一个发现是 RC4 通常具有较低的熵。这是有道理的,因为 TinyAES 需要三个十六进制代码数组(sbox、rsbox和rcon)以及加密的 shellcode、密钥和 IV;每个都有助于提高熵水平。
结论
总而言之,这个项目不仅非常有趣,而且也是一次宝贵的学习经历。它帮助我提高了我的 C/C++ 编程技能,让我更清楚地了解了各种加密和混淆技术,以及如何战略性地组合它们以获得更好的结果。
虽然由于项目代码可能需要签名而无法分享完整的项目,但我希望这次分解能给你一个坚实的起点,或者至少能为你自己探索加密/混淆技术提供一些想法。
感谢您的关注,祝您黑客愉快!:)
原文始发于微信公众号(Ots安全):Waffles Crypt:C/C++ 中 Shellcode 加密和混淆的模块化方法
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论