Donut:将.NET程序集注入Windows进程
Donut是一个shellcode生成工具,它可以从.NET程序集中创建与位置无关的shellcode
payloads。此shellcode可用于将程序集注入任意Windows进程。给定一个任意.NET程序集,参数和入口点(如Program.Main),Donut就可为我们生成一个与位置无关的shellcode,并从内存加载它。.NET程序集可以通过直接嵌入shellcode从URL或Stageless进行分阶段。无论哪种方式,.NET程序集都将使用Chaskey
block
cipher和128-bit随机生成的密钥进行加密。通过CLR加载程序集后,原始引用将从内存中删除以躲避内存扫描程序检测。程序集将被加载到一个新的应用程序域(AppDomain)
中,以允许在可释放的AppDomain中运行程序集。它可以以多种方式使用。
作为独立工具使用
Donut可用于从任意.NET程序集生成shellcode。同时提供了Windows EXE和Python script(计划用于v1.0版的python)的payload生成。命令行语法如下。
usage: donut [options] -f <.NET assembly>-f <path> .NET assembly to embed in PIC and DLL.-u <URL> HTTP server that will host the .NET assembly.-c <namespace.class> Optional class name. (required for DLL)-m <method> Optional method name. (required for DLL)-p <arg1,arg2...> Optional parameters or command line, separated by comma or semi-colon.-a <arch> Target architecture : 1=x86, 2=amd64, 3=amd64+x86(default).-r <version> CLR runtime version. MetaHeader used by default or v4.0.30319 if none available.-d <name> AppDomain name to create for assembly. Randomly generated by default.examples:donut -f assembly.exedonut -a1 -cTestClass -mRunProcess -pnotepad.exe -floader.dlldonut -f loader.dll -c TestClass -m RunProcess -p notepad.exe -u http://remote_server.com/modules/
从源码构建 Donut
已为包含已编译可执行文件的每个发布版本的donut提供了tags。
v0.9 Beta:https://github.com/TheWover/donut/releases/tag/v0.9v0.9.1 Beta:https://github.com/TheWover/donut/releases/tag/v0.9.1
你也可以使用提供的makefile自行克隆和构建源码。启动Microsoft Visual Studio Developer命令提示符并cd到donut的目录。Makefile(非gcc)可以通过-f Makefile.msvc进行指定。makefile提供以下命令来构建donut:
nmake donut -f Makefile.msvc
nmake debug -f Makefile.msvc
nmake clean -f Makefile.msvc
作为库
对于Linux(.a/.so)和Windows(.lib/.dll),可以将donut编译为动态库和静态库。它有一个简单的API,在docs/api.html中有描述。提供了两个导出函数:int DonutCreate(PDONUT_CONFIG c) 和 int DonutDelete(PDONUT_CONFIG c)。
作为模板 – 重建 shellcode
payload.c包含.NET程序集加载程序,该加载程序应使用Microsoft Visual Studio和MingW-W64成功编译。已为两个编译器提供了make文件,默认情况下,这两个编译器将生成x86-64 shellcode,除非将x86作为标签提供给nmake/make。每当payload.c被更改时,建议在重建donut之前重新编译所有架构。
Microsoft Visual Studio
打开x64 Microsoft Visual Studio构建环境,切换到payload目录,然后键入以下内容:
nmake clean -f Makefile.msvc
nmake -f Makefile.msvc
这将从payload.c. exe2h生成一个64位可执行文件(payload.exe),然后从PE文件的.textsegment提取shellcode,并将其作为C array,保存到payload_exe_x64.h。当重新构建donut时,这个新的shellcode将用于它生成的所有payloads。
想要生成32位shellcode,请打开x86 Microsoft Visual Studio构建环境,并切换到payload目录,然后键入以下内容:
nmake clean -f Makefile.msvc
nmake x86 -f Makefile.msvc
这会将shellcode作为C array保存到payload_exe_x86.h中。
Mingw-w64
假设你在Linux上,并且mingw-w64是从软件包或源码安装的,那么你仍然可以使用我们提供的makefile重新构建shellcode。切换到payload目录并键入以下内容:
make clean -f Makefile.mingw
make -f Makefile.mingw
一旦为所有架构重新编译,就可以重建donut。
绕过
donut包括用于AMSI和其他安全功能的绕过系统。目前可以绕过:
.NET v4.8中的AMSIDevice Guard策略阻止动态生成的代码执行
你也可以在payload/bypass.c中自定义或添加自己的绕过方案。
每个bypass都使用BOOL DisableAMSI(PDONUT_INSTANCE inst)签名实现DisableAMSI功能,并附带相应的预处理器指令。我们有几个#if defined blocks来检查定义。每个block实现相同的bypass功能。例如,我们的第一个bypass称为BYPASS_AMSI_A。如果donut是用定义的变量构建的,则将使用该bypass。
为什么这么做?因为这意味着只有你使用的bypass内置在payload.exe中。因此,其他代码不包含在shellcode中。这减少了shellcode的大小和复杂性,增加了模块化的设计,并确保扫描程序无法在shellcode中找到你实际未使用的可疑块。
这么设计的另一个好处就是,你可以编写自己的AMSI bypass。要使用新的bypass构建Donut,请使用if defined block进行bypass,并修改makefile以添加一个使用定义的bypass名称构建的选项。
如果你愿意,可以扩展我们的bypass系统来添加在加载.NET程序集之前运行的其他预执行逻辑。
这里有一篇有关AMSI bypass研究的详细文章大家可以参考下。
个人建议
以下建议留给大家作为练习:
添加环境键控每次生成shellcode时,通过混淆payload使donut具有多态性将donut作为模块集成到你最喜欢的RAT/C2框架中
免责声明
我们不会针对任何的AV和检测实时更新签名进行对抗。对于任何滥用此软件或技术的行为,我们概不负责!该工具仅作为研究学习使用!
工作原理
Procedure
Donut使用Unmanaged CLR Hosting API来加载公共语言运行时(Common Language Runtime)。如有必要,程序集将下载到内存中。无论哪种方式,都使用Chaskey block cipher对其进行解密。将CLR加载到主机进程后,除非另行指定,否则将使用随机名称创建新的AppDomain。AppDomain准备就绪后,将通过AppDomain.Load_3加载.NET程序集。最后,使用任意指定的参数调用用户指定的入口点。
以上逻辑描述了donut生成的shellcode的是如何工作的。该逻辑是在payload.exe中定义。要获取shellcode,exe2h从payload.exe中的.text segment中提取已编译的机器代码,并将其作为C array保存到C header文件中。donut将shellcode与Donut实例(shellcode的配置)和Donut模块(包含.NET程序集,类名,方法名和任意参数)相结合。
有关未记录的CLR Hosting API的文档,请参阅MSDN:https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/clr-hosting-interfaces
有关CLR主机的单独示例,请参阅Casey Smith的AssemblyLoader存储库:https://github.com/caseysmithrc/AssemblyLoader
有关Donut如何运作的详细博文,可在Odzhan和TheWover的博客中找到。链接位于README的开头部分。
组件
donut.c: donut payload生成器源码donut.exe: 编译为可执行文件EXEdonut.py: 编译为Python script(计划用于v1.0版的python)lib/donut.dll, lib/donut.lib: 在Windows平台将Donut作为一个动态和静态库用于其他项目lib/donut.so, lib/donut.a:在Linux平台将Donut作为一个动态和静态库用于其他项目lib/donut.h: 如果在C/C++项目中使用静态库或动态库,则包含头文件payload/payload.c:shellcode源码payload/payload.exe: 编译的payload。shellcode是从这个二进制文件中提取的。payload/inject.c:一个C shellcode injector,注入payload.bin到一个特定进程用于测试。payload/inject.exe: 编译的C shellcode injectorpayload/runsc.c:一个C shellcode runner,用于以最简单的方式测试payload.binpayload/runsc.exe: 编译的C shellcode runnerpayload/exe2h/exe2h.c: exe2h源码payload/exe2h/exe2h.exe: 从payload.exe中提取有用的机器代码,并将其作为数组保存到C头文件中encrypt.c: 在Counter(CTR)模式下用于加密的Chaskey 128-bit block cipher。hash.c: Maru hash 功能。使用具有Davies-Meyer构造的Speck 64位分组密码进行API散列。
子项目
donut提供了四个配套项目:
DemoCreateProcess:用于测试的.NET程序集示例。采用两个命令行参数,每个参数指定要执行的程序。DonutTest:用于测试donut的简单C# shellcode
injector。shellcode必须是base64编码,并以字符串形式复制。ModuleMonitor:一个概念验证工具,可以检测CLR注入,因为它是由Donut和Cobalt Strike的执行程序集等工具完成。
ProcessManager:一个进程发现工具,攻击者可以使用它来确定注入的内容,防御者则可以用来确定正在运行的内容,这些进程具有哪些属性,以及它们是否加载了CLR。
项目计划
创建一个donut Python C扩展,允许用户编写可以通过编程方式使用donut API的Python程序。它将用C语言编写,但作为Python模块公开。创建一个C#版本的生成器创建一个donut.py生成器,使用与donut.exe相同的命令行参数添加对HTTP代理的支持如果可能,找到简化shellcode的方法添加选项以指定最大参数长度添加对动态查找EXE入口点并使用命令行参数执行的支持写一篇博文,介绍如何将donut集成到你的工具中,并进行调试和定制,以及设计与之可协同工作的的payload。
Donut:将.NET程序集注入Windows进程相关推荐
- 直接将自身代码注入傀儡进程
EXE注入-傀儡进程 2008-08-16 16:38 直接将自身代码注入傀儡进程,不需要DLL.首先用CreateProcess来创建一个挂起的IE进程,创建时候就把它挂起.然后得到它的装载基址,使 ...
- 枚举windows进程模块的几种方法—PEB内核结构详解
1. 引言 在诸多的场景中(例如软件测试,软件安全研究等领域)经常需要分析在目标进程中 具体加载了哪些模块(DLL),以及所加载的模块的信息(如模块基地址,映射文件大小等).获取这win ...
- 枚举Windows进程中模块的几种方法-PEB内核结构详解
1. 引言 在诸多的场景中(例如软件测试,软件安全研究等领域)经常需要分析在目标进程中具体加载了哪些模块(DLL),以及所加载的模块的信息(如模块基地址,映射文件大小等).获取这windows进程加载 ...
- 几种Windows进程通信
32位Windows采用虚拟内存技术使每个进程虚拟4G内存,在逻辑上实现了对进程之间数据代码的分离与保护.那么相应的进程之间的通信也就有必要整理掌握一下. Windows进程间通讯的方法有很多:管道. ...
- Zabbix安装(十):监控windows进程
1.监控windows进程的几个KEYS: proc.mem[<name>,<user>,<mode>,<cmdline>] Memory used b ...
- 【Android 逆向】修改运行中的 Android 进程的内存数据 ( Android 命令行中获取要调试的应用进程的 PID | 进程注入调试进程内存的 so 库 )
文章目录 一.Android 命令行中获取要调试的应用进程的 PID 二.进程注入调试进程内存的 so 库 一.Android 命令行中获取要调试的应用进程的 PID 前置博客 [Android 逆向 ...
- zabbix监控windows进程
配置相关信息 server: linux centos 6.8 agent: windows server 2008 r2 ...
- Windows进程与线程学习笔记(九)—— 线程优先级/进程挂靠/跨进程读写
Windows进程与线程学习笔记(九)-- 线程优先级/进程挂靠/跨进程读写 要点回顾 线程优先级 调度链表 分析 KiFindReadyThread 分析 KiSwapThread 总结 进程挂靠 ...
- Windows进程与线程学习笔记(八)—— 线程切换与TSS/FS
Windows进程与线程学习笔记(八)-- 线程切换与TSS/FS 要点回顾 线程切换与TSS 内核堆栈 调用API进0环 实验:分析SwapContext 线程切换与FS 段描述符结构 分析Swap ...
最新文章
- python学好了能干啥_新手该如何学python怎么学好python?_python学好了能干什么
- 【转】无法将notepad++添加到打开方式列表中的解决办法
- 2020-10-18C++笔记之C/C++之字符串赋值
- RedHat 下常见系统故障及恢复方法(整理)
- 【转】Unity3d:读取FBX中的动画
- vue 开发一个按钮组件
- 精选 26 个 Python 实用技巧,想秀技能先 Get 这份技术列表!
- UE3 供游戏性程序员的使用的性能最优化方法
- 堪比整容!学会这些可视化技巧,让你的图表分分钟高级起来
- 大学计算机专业分流考试,北京林业大学计算机类(入学一年后分流至计算机科学与技术、数字媒体技术、网络工程、计算机科学与技术(物联网))专业2016年在江苏理科高考录取最低分数线...
- 60度斜坡怎么计算_坡度计算公式图解
- 西刺代理python_Python四线程爬取西刺代理
- 27岁了,女生,还可以学前端开发吗?可以的话,怎么开始学呢?
- 汇编条件判断 eq neq
- 武汉意向岗位(一)——中国建设银行数据运营中心
- 声速的测量的实验原理和应用_示波器的原理和使用声速测量实验报告.docx
- 关于在ubuntu server 14.04上安装docker以及git之笔记
- 【020期】面试官问:Java 遍历 Map 集合有几种方式?效率如何?
- 给中国学生的第三封信——成功、自信、快乐
- 共享开源技术,共建开放生态丨平凯星辰余梦杰出席 2022 世界互联网大会开源论坛圆桌对话