frkngksl/Shoggoth

GitHub: frkngksl/Shoggoth

基于 AsmJit 的多态加密工具,可对 shellcode、PE 和 COFF 文件进行多层加密并生成可直接执行的位置无关代码,用于对抗静态和动态特征检测。

Stars: 782 | Forks: 99

# Shoggoth
**发表于** - [BlackHat Europe 2022 Arsenal](https://www.blackhat.com/eu-22/arsenal/schedule/index.html#shoggoth-asmjit-based-polymorphic-encryptor-29588) - [ 演讲记录](https://www.youtube.com/watch?v=ECbQnbPxz5g) # 简介 ## 描述 Shoggoth 是一个基于 C++ 和 asmjit 库的开源项目,用于对给定的 shellcode、PE 和 COFF 文件进行多态加密。 Shoggoth 将生成一个输出文件,以混淆的形式存储 payload 及其相应的 loader。由于输出的内容是位置无关的,因此可以直接作为 shellcode 执行。在 payload 执行时,它会在运行时自行解密。除了加密例程外,Shoggoth 还会在例程之间添加不会改变任何状态的垃圾指令。 我开始开发这个项目是为了研究不同的动态指令生成方法、汇编实践以及特征检测。我计划定期使用我学到的新知识来更新这个代码库。 # 功能 当前的功能列表如下: - 仅支持 x64 输入 - 能够将 PIC COFF Loader 与 COFF 或 BOF 输入文件合并 - 能够将 PIC PE Loader 与 PE 输入文件合并 - 使用 RC4 算法的流密码 - 使用随机生成运算的块密码 - 垃圾指令生成 ## 执行流程 Shoggoth 针对输入文件的一般执行流程如下图所示。您可以观察到这是默认配置下的流程。 基本上,Shoggoth 首先根据所选的模式(COFF 或 PE 文件)将预编译的 loader shellcode 与输入文件合并。然后,它将生成的多条垃圾指令添加到此合并后的 payload 中。包含 loader、垃圾指令和 payload 的 stub 首先使用 RC4 加密,然后再通过将相应的解密器组合起来,使用随机生成的块加密进行加密。最后,它会向生成的代码块中添加一条垃圾指令。 ## 机器码生成 当 Shoggoth 为垃圾 stub 或加密例程随机生成指令时,它使用了 [AsmJit](https://asmjit.com/) 库。 AsmJit 是一个用 C++ 语言编写的轻量级机器码生成库。它可以为 X86、X86_64 和 AArch64 架构生成机器码,并支持基准指令和所有最新的扩展指令集。AsmJit 允许指定操作码、寄存器、立即数、调用标签,并可以将任意值嵌入到代码内的任何偏移量位置。在使用 AsmJit 生成某些汇编指令时,只需使用 Assembler 类中汇编操作数的值,调用与所需汇编操作相对应的 API 函数即可。对于每次 API 调用,AsmJit 都会在其内部的 CodeHolder 结构中保存代码和重定位信息。在调用完所有要生成的汇编命令的 API 函数后,可以使用其 JitRuntime 类将代码从 CodeHolder 复制到具有可执行权限的内存中并进行重定位。 在寻找代码生成库时,我偶然发现了 AsmJit,并且看到它被许多流行的项目广泛使用。这就是为什么我决定使用它来满足我的需求。我不知道 Shoggoth 是否是第一个在红队背景下使用它的项目,但我相信它可以作为未来实现的参考。 ## COFF 和 PE Loader Shoggoth 可用于对给定的 PE 和 COFF 文件进行加密,得益于预编译的位置无关 loader,它们都可以作为 shellcode 执行。我只需使用 *C to Shellcode* 方法,就可以获得我为我以前的项目修改过的著名 PE 和 COFF loader 的 PIC 版本。在编译方面,我使用了 [HandleKatz](https://github.com/codewhitesec/HandleKatz) 项目中的 Makefile,这是一个 PIC 形式的 LSASS 转储工具。 基本上,为了通过 C to Shellcode 技术获取 shellcode,我移除了 loader 源代码中的所有全局变量,将所有字符串存入栈中,并通过在运行时加载和解析必要的 DLL 来获取 Windows API 函数的地址。随后,我通过链接脚本确定了入口点,并使用 MinGW 结合各种编译标志对代码进行了编译。我提取了生成的可执行文件的 .text 节并获得了 loader shellcode。由于按上述方式编辑代码后生成的可执行文件不包含 .text 节以外的任何节,因此该节中的代码可以作为位置无关代码使用。 这些的源代码可以在 [COFFLoader](https://github.com/frkngksl/Shoggoth/tree/main/COFFLoader) 和 [PELoader](https://github.com/frkngksl/Shoggoth/tree/main/PELoader) 目录中查看和编辑。此外,这些源代码编译后的版本可以在 [stub](https://github.com/frkngksl/Shoggoth/tree/main/stub) 目录中找到。目前,如果你想编辑或更改这些 loader,你必须遵循其函数签名并替换 stub 目录中的预编译二进制文件。 要将参数传递给 BOF,请使用 '--coff-arg' 选项。Shoggoth 期望接收一个包含打包参数的预格式化十六进制字符串,这可以使用 TrustedSec 的 beacon_generate.py 脚本来创建。该脚本的一个副本已作为 COFFArgGenerator/beacon_generate.py 包含在内。(非常感谢 @Octoberfest7) ## RC4 密码 Shoggoth 首先使用流密码之一的 RC4 算法来加密其获取的 payload。在随机生成此处使用的密钥后,它使用该密钥对 payload 进行加密。在运行期间解密 payload 的解密器 stub 是通过使用 AsmJit 动态创建和汇编的。stub 中使用的寄存器在每个样本中都是随机选择的。 对于我在 Shoggoth 中使用的 RC4 算法的实现,我参考了 Nayuki 的[代码](https://www.nayuki.io/page/rc4-cipher-in-x86-assembly)。 ## 随机块密码 在执行第一次加密之后,Shoggoth 使用第二次加密,即随机生成的块密码。通过第二次加密,它同时加密 RC4 解密器,以及(可选的)包含 payload、垃圾指令和使用 RC4 加密的 loader 的 stub。它将要加密的数据块划分为 8 字节的块,并对每个块使用随机生成的指令。这些指令包括 ADD、SUB、XOR、NOT、NEG、INC、DEC、ROL 和 ROR。这些指令的操作数也是随机选择的。 ## 垃圾指令生成 生成的垃圾指令逻辑深受 Ege Balci 出色的 [SGN](https://github.com/EgeBalci/sgn) 项目启发。Shoggoth 可以基于跳过随机字节、无副作用的指令、虚假函数调用以及有副作用但保留初始值的指令来选择垃圾指令。所有这些指令都是随机选择的,并通过调用 AsmJit 库的相应 API 函数来生成。此外,为了增加大小和不同的组合方式,这些生成函数是以递归方式调用的。 在 Shoggoth 的第一个版本中,有很多可以放置垃圾指令的地方。例如,我们可以在块密码指令或 RC4 密码指令之间插入垃圾指令。然而,出于演示目的,为了避免生成的 payload 出现额外的复杂性,我将它们留给了后续版本。 # 用法 ## 环境要求 我没有编译主项目。这就是为什么你必须自己编译。或者,如果你想编辑 PE loader 或 COFF loader 的源代码,你的机器上应该装有 MinGW,以便使用提供的 Makefile 编译它们。 - Visual Studio 2019+ - (可选) MinGW 编译器 ## 命令行参数 ``` ______ _ _ / _____) | _ | | ( (____ | |__ ___ ____ ____ ___ _| |_| |__ \____ \| _ \ / _ \ / _ |/ _ |/ _ (_ _) _ \ _____) ) | | | |_| ( (_| ( (_| | |_| || |_| | | | (______/|_| |_|\___/ \___ |\___ |\___/ \__)_| |_| (_____(_____| by @R0h1rr1m "Tekeli-li! Tekeli-li!" Usage of Shoggoth.exe: -h | --help Show the help message. -v | --verbose Enable more verbose output. -i | --input Input path of payload to be encrypted. (Mandatory) -o | --output Output path for encrypted input. (Mandatory) -s | --seed Set seed value for randomization. -m | --mode Set payload encryption mode. Available mods are: (Mandatory) [*] raw - Shoggoth doesn't append a loader stub. (Default mode) [*] pe - Shoggoth appends a PE loader stub. The input should be valid x64 PE. [*] coff - Shoggoth appends a COFF loader stub. The input should be valid x64 COFF. --coff-arg Set argument for COFF loader. Generate this string using COFFArgGenerator/beacon_generate.py. example: --coff-arg 0a0000000600000068656c6c6f00 Only used in COFF loader mode. (Thanks to @Octoberfest7) -k | --key Set first encryption key instead of random key. --dont-do-first-encryption Don't do the first (stream cipher) encryption. --dont-do-second-encryption Don't do the second (block cipher) encryption. --encrypt-only-decryptor Encrypt only decryptor stub in the second encryption. ``` # Shoggoth 是什么意思?



Shoggoth 是克苏鲁神话中的一种虚构怪物。这些生物在 H. P. 洛夫克拉夫特的十四行诗组诗《来自尤格斯的真菌》(1929-30)中被顺便提及,后来在他的中篇小说《疯狂山脉》(1931)中得到了详细描述。它们能够形成手头任务所需的任何器官或附肢,尽管它们通常的状态是一团由眼睛、嘴巴和蠕动触手组成的翻腾物。 由于这些生物在洛夫克拉夫特的描述中就像一团有自我塑造能力的凝胶状 sentient 肉块,并且没有固定的形状,因此我想将这个名字赋予一个多态加密器工具。 :slightly_smiling_face: # 参考 - https://github.com/EgeBalci/sgn - https://github.com/asmjit/asmjit - https://www.pelock.com/articles/polymorphic-encryption-algorithms - https://github.com/codewhitesec/HandleKatz - https://github.com/vxunderground/MalwareSourceCode - https://www.nayuki.io/page/rc4-cipher-in-x86-assembly - https://www.deviantart.com/halycon450/art/Shoggoth-914584713 - https://www.artstation.com/burakkrtak (Logo 设计师) - https://github.com/trustedsec/COFFLoader/blob/main/beacon_generate.py
标签:Asmjit, BlackHat Europe, BOF, C++, COFF文件加载, EDR绕过, Gophish, PE文件加载, PIC, RC4算法, shellcode加密, x64架构, 中高交互蜜罐, 代码混淆, 位置无关代码, 动态指令生成, 块密码, 垃圾指令, 多态加密, 恶意软件开发, 数据展示, 数据擦除, 欺骗防御, 汇编指令生成, 流密码, 签名规避, 红队, 红队武器化, 运行时解密, 高交互蜜罐, 黑帽大会