浅谈.Net Profiling在红队中的使用

科技   科技   2024-06-17 18:04   北京  

前言

.NET Profiling 是一组用于开发性能分析工具的接口,用于监控和分析 .NET 应用程序的各种行为。近日,有研究员将该项技术用于横向移动,本文主要对此技术在红队中的使用做介绍。


01 .Net Profiling

.NET Profiling 用于监控和分析 .NET 应用程序的各种行为。通过调用这些接口,开发人员可以创建自定义的性能分析器,深入了解应用程序的性能瓶颈、内存使用、线程行为等,从而进行优化和改进。 


.Net Profiling API分为.Net Framework和.Net Core两个版本,Framework中大部分的API都适用于.Net Core。主要的API接口有两个:


  • ICorProfilerCallback: 定义了所有分析事件的回调接口,例如方法调用、垃圾回收等。


  • ICorProfilerInfo: 提供了查询和控制被分析应用程序的信息,例如获取模块信息、设置分析标志等。


下面列举几个有意思的API:


  • ICorProfilerCallback2::GarbageCollectionFinished GC(垃圾回收)完成时,该回调函数被调用


  • ICorProfilerCallback::JITCompilationStarted 通过该回调函数,我们可以知道哪个函数开始JIT(即时编译)


  • ICorProfilerCallback::AssemblyLoadStarted 通过该回调函数,我们可以知道哪些程序集被加载


  • ICorProfilerInfo4::RequestReJIT 通过该方法,我们可以强制重新JIT某个方法,这意味着可以动态修改IL代码


02 .Net Profiler

.Net Profiler是调用.Net Profiling接口编写的分析器,本身以dll形式出现。这个dll和Java中的agent类似,需要注入到CLR或者CoreCLR中。注入方式也有两种,一种是任意.Net进程启动时由CLR或CoreCLR自动加载,另一种是在任意.Net程序运行中执行Attach。这两种方式类似于Java Agent的premain和agentmain,但实际上比Java要复杂和重型。


第一种方式是通过设置环境变量实现的,适用于.Net Core和.Net Framework 如下所示。


CORECLR_ENABLE_PROFILING为1,代表允许分析器加载到.Net进程


CORECLR_PROFILER 分析器dll将检查传递的CLSID是否正确


CORECLR_PROFILER_PATH 代表分析器dll的路径

setx CORECLR_ENABLE_PROFILING=1 setx CORECLR_PROFILER={805A308B-061C-47F3-9B30-F785C3186E71}setx CORECLR_PROFILER_PATH=C:\DotNextMoscow2019-master\Debug\DotNext.Profiler.Windows.dll


设置好上述变量后,任意.Net进程启动都会自动加载分析器Dll


第二种方式,用到了ICLRProfiling::AttachProfile 接口。.Net FrameWork的主要步骤如下:


  1. 获取ICLRMetaHost


  2. 枚举加载到目标进程中的 CLR


  3. 获取目标进程中特定 CLR 的 ICLRRuntimeInfo


  4. 获取ICLRProfiling接口


  5. 调用 ICLRProfiling::AttachProfiler 方法,附加成功


可以看到,整个流程前三步和Execute-Assembly技术实现的前三步完全一致


.Net Core则提供了相应库Microsoft.Diagnostics.NETCore.Client,相关代码如下。

using Microsoft.Diagnostics.NETCore.Client;
class profiler_injector{    static void Main(string[] args){        int pid = Int32.Parse(args[0]);        string profilerPath = args[1];                DiagnosticsClient dia = new DiagnosticsClient(pid);        Guid guid = new Guid("{805A308B-061C-47F3-9B30-F785C3186E71}");        dia.AttachProfiler(TimeSpan.FromSeconds(30),guid, path );    }}



谈完注入方式后,咱们来谈一下分析器Dll本身。分析器dll的工作原理大致如下图所示:

1. CoreCLR 首先Load Profiler这个dll,每个分析器Dll都会有DllGetClassobject这个导出函数。


2. CoreCLR然后调用DllGetClassobject导出函数,该函数通常判断CLSID的正确性,然后返回IClassFactory接口实例对象指针。


3. CoreCLR然后调用IClassFactory::CreateInstance方法,获取ICorCallback接口实例对象指针。


4. CoreCLR调用ICorCallback::Initialize方法,传入指向自己的指针,profiler会保存下来,然后调用SetEventMask通知coreclr 收集什么类的信息。


5. 双方进入正常通信。一旦有事件发生,ICorCallback接口的回调函数会被调用。


详细代码见参考链接3,建议观看 Pavel Yosifovich 的演讲视频"Writing a .NET Core cross platform profiler in an hour"



03 应用

持久化

上文提到,当3个环境变量被设置时,任意.Net进程启动会自动加载环境变量指定路径下的Dll,这意味着可以用来做持久化。需要注意的是,Dll不一定要是分析器Dll,普通的Dll也会被加载,即DllMain函数会被执行,可以把恶意代码放在DllMain中。


横向移动

如果可以通过UNC路径远程加载分析器Dll,并设置环境变量,那么便可以用.Net Profiler来横向移动。利用Win32_Process Create创建进程是一种常见的横向方式。而Win32_ProcessStartup可以为指定进程创建环境变量,这意味着我们可以利用上面两个函数远程执行任意.Net进程并加载分析器Dll。


研究员Daniel Mayer在WMI bof项目的基础上,添加了设置环境变量的功能,并将分析器Dll的路径设置为远程UNC路径,但由于使用了WMI,会有双跳(Double Hop)问题,因此失败。然而,他又发现了一种新方式,即分析器Dll可以从远程WebDAV服务器加载,从而实现了横向移动。


04 总结

.Net Profiling API是一组功能较为强大的接口,本文主要介绍了该技术在红队横向移动和持久化中的使用。由于该组接口的参考文档不多,且使用较为复杂,因此相关研究较少,但该组接口有着不少强大的功能,比如运行时修改.Net程序中的某个方法、挂钩.Net程序的指定方法等,这些技术有待进一步研究。


附录 参考链接

[1] https://learn.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/profiling-interfaces

[2] https://github.com/dotnet/coreclr/blob/master/Documentation/Profiling/davbr-blog-archive/Attach.md

[3] https://github.com/zodiacon/DotNextMoscow2019

[4] https://www.youtube.com/watch?v=TqS4OEWn6hQ

[5] https://posts.specterops.io/lateral-movement-with-the-net-profiler-8772c86f9523


天元实验室专注于新型实战化攻防对抗技术研究。

研究目标包括:漏洞利用技术、防御绕过技术、攻击隐匿技术、攻击持久化技术等蓝军技术,以及攻击技战术、攻击框架的研究。涵盖Web安全、终端安全、AD安全、云安全等多个技术领域的攻击技术研究,以及工业互联网、车联网等业务场景的攻击技术研究。通过研究攻击对抗技术,从攻击视角提供识别风险的方法和手段,为威胁对抗提供决策支撑。


M01N Team公众号

聚焦高级攻防对抗热点技术

绿盟科技蓝军技术研究战队

官方攻防交流群

网络安全一手资讯

攻防技术答疑解惑

扫码加好友即可拉群


M01N Team
研战一体,以攻促防,共筑网络安全未来!
 最新文章