English | 中文
在初次使用Gonut之前,您需要先了解:“Donut是什么?”。
Donut 是一种与位置无关的代码,可以在内存中执行 VBScript、JScript、EXE、DLL 文件和 .NET 程序集。
Donut 创建的模块可以从 HTTP 服务器暂存,也可以直接嵌入到加载器本身中。
该模块可选择使用 Chaskey 分组密码和 128 位随机生成的密钥进行加密。
文件在内存中加载并执行后,原始引用将被删除以阻止内存扫描。
生成器(Generator)和加载器(Loader)支持以下功能:
- 使用 aPLib 或通过 RtlCompressBuffer的 LZNT1、Xpress、Xpress Huffman 压缩输入文件。(注:在Donut v1.0版本中暂时移除了对 Xpress Huffman 的支持。)
- 使用熵进行 API 哈希和字符串生成。
- 文件的 128 位对称加密。
- 覆盖 PE 头。
- 将 PE 文件存储在 MEM_IMAGE 内存中。
- 修补反恶意软件扫描接口 (AMSI) 和 Windows 锁定策略 (WLDP)。
- 修补 Windows 事件跟踪 (ETW)。
- 修补 EXE 文件的命令行。
- 修补与退出相关的 API 以避免宿主进程终止。
- 多种输出格式:C、Ruby、Python、PowerShell、Base64、C#、Hex(十六进制字符串)和 UUID 字符串。
提供Linux 和 Windows 的动态和静态库,可以将它们集成到您自己的项目中。还有一个 Python 模块,您可以在构建和使用 Python 扩展中阅读有关该模块的更多信息。
* 以上内容译自: https://github.com/TheWover/donut#1-introduction
* 想要更详细的了解什么是Donut
,以及Donut
是如何运作的可访问:https://github.com/TheWover/donut
Generator(生成器)
Generator根据输入的参数将 VBScript、JScript、EXE、DLL 文件和 .NET 程序集等格式的文件压缩、加密后与加载器的Shellcode进行拼接,最后生成最终要使用的Shellcode。
Loader(加载器)
Loader相当于一个Shellcode模板,在内存中执行时会根据Generator在生成时所用到的参数解密、解压原始payload(vbs、js、exe、dll等)到内存并执行payload。
绕过AMSI、WLDP、ETW等操作均由Loader来执行。
如果您正确理解了前面所述的大部分内容,您可以不必理会本段的内容,否则您可以简单的将Donut当成一个PE转Shellcode的工具,并相比其他工具(如pe_to_shellcode等)多了加密,压缩,绕过AMSI、WLDP、ETW,隐蔽调用系统API等功能,并且比那些工具能更好的规避AV、EDR的内存检测与行为检测。
Gonut是Donut的Generator的跨平台实现,纯Go编写,无CGO,支持大部分主流系统(Windows、Linux、macOS等)与架构(i386、amd64、arm、Apple silicon等)。
请再次注意:Gonut仅仅是Donut的Generator的跨平台实现,不含Donut的Loader。
- Donut的Generator仅可运行在Windows与Linux系统下。
- Donut的Generator在Linux系统下的行为与在Windows系统下的行为不完全一致(#45)。
- Donut的Generator在Linux系统下不支持LZNT1、Xpress的压缩功能。
- 目前无法在在Arm架构的Windows、Linux下编译Donut。
- Donut的Generator在macOS(M系列芯片)下无法使用。
- 让更多人了解到Donut这个被严重低估的项目。
为了解决上述问题,就有了Gonut。
- 在各个系统下(Windows、Linux、macOS等)的行为与Donut在Windows系统下的行为一致(压缩功能除外,详见Gonut与Donut的Generator的区别)。
- 更好的使用体验。
- 由于Gonut是完全依赖于Donut的Loader的,所以不会添加Donut所没有(或明确表示不支持)的功能。
Donut官方还推荐了两个第三方实现的Generator:
但是这两个项目均已很久未更新,不支持最新版Donut(v1.0)的Loader,且均不支持Decoy、ETW Bypass、压缩、指定输出格式等常用功能。
- 压缩功能的区别:由于Donut使用的是非开源的aPLib压缩功能,和微软提供的RtlCompressBuffer功能,这两者均无法在非Windows系统下完美复现,所以目前Gonut仅能做到尽量模拟这两者的压缩算法与压缩格式。
- 在Donut原本支持的输出格式上又添加了:Golang、Rust等输出格式。
出于各种原因,Gonut目前不打算提供预编译的二进制文件,这意味着如果您想使用Gonut将需要安装最基本的Golang开发环境或Docker运行时环境。
git clone https://github.com/wabzsy/gonut
cd gonut
docker build -t gonut . -f Dockerfile-cn
# docker run --rm -it -v `pwd`:/opt gonut -h
go install -v github.com/wabzsy/gonut/gonut@latest
git clone https://github.com/wabzsy/gonut
cd gonut/gonut
go build -v
与Donut的用法大致相同,下表为命令行版本Gonut的所支持的参数:
选项 | 参数类型 | 描述 |
---|---|---|
-n, --modname | string | Module name for HTTP staging. If entropy is enabled, this is generated randomly. |
-s, --server | string | Server that will host the Donut module. Credentials may be provided in the following format: https://username:[email protected]/ |
-e, --entropy | int | Entropy: 1=None 2=Use random names 3=Random names + symmetric encryption (default 3) |
-a, --arch | int | Target architecture: 1=x86 2=amd64 3=x86+amd64 (default 3) |
-o, --output | string | Output file to save loader. (default: loader.[format]) |
-f, --format | int | Output format: 1=Binary 2=Base64 3=C 4=Ruby 5=Python 6=Powershell 7=C# 8=Hex 9=UUID 10=Golang 11=Rust (default 1) |
-y, --oep | int | Create thread for loader and continue execution at <addr> supplied. (eg. 0xdeadbeef) |
-x, --exit | int | Exit behaviour: 1=Exit thread 2=Exit process 3=Do not exit or cleanup and block indefinitely (default 1) |
-c, --class | string | Optional class name. (required for .NET DLL, format: namespace.class) |
-d, --domain | string | AppDomain name to create for .NET assembly. If entropy is enabled, this is generated randomly. |
-i, --input | string | Input file to execute in-memory. |
-m, --method | string | Optional method or function for DLL. (a method is required for .NET DLL) |
-p, --args | string | Optional parameters/command line inside quotations for DLL method/function or EXE. |
-w, --unicode | Command line is passed to unmanaged DLL function in UNICODE format. (default is ANSI) |
|
-r, --runtime | string | CLR runtime version. MetaHeader used by default or v4.0.30319 if none available. |
-t, --thread | Execute the entrypoint of an unmanaged EXE as a thread. | |
-z, --compress | int | Pack/Compress file: 1=None 2=aPLib [experimental] 3=LZNT1 (RTL) [experimental, Windows only] 4=Xpress (RTL) [experimental, Windows only] 5=LZNT1 [experimental] 6=Xpress [experimental, recommended] (default 1) |
-b, --bypass | int | Bypass AMSI/WLDP/ETW: 1=None 2=Abort on fail 3=Continue on fail (default 3) |
-k, --headers | int | Preserve PE headers: 1=Overwrite 2=Keep all (default 1) |
-j, --decoy | string | Optional path of decoy module for Module Overloading. |
-v, --verbose | verbose output. (debug mode) | |
-h, --help | help for gonut | |
--version | version for gonut |
与Donut一致,详见Payload Requirements
与Donut一致,详见Disclaimer
我们对任何滥用该软件或技术的行为不承担任何责任。 Gonut 是通过 shellcode 演示 CLR 注入和内存加载,以便为红队人员提供一种模拟对手和防御者的方法,为构建分析和缓解措施提供参考框架。这不可避免地存在恶意软件作者和威胁行为者滥用它的风险。然而,我们认为净收益大于风险。希望这是正确的。如果 EDR 或 AV 产品能够通过签名或行为模式检测 Gonut,我们不会更新 Gonut 以对抗签名或检测方法。为了避免被冒犯,请勿询问。