木马的复现
应急中遇到一个以前没见过的aspx webshell,读取post请求发送的数据,经过aes解密之后使用system.reflection.assembly.Load作为.net dll加载,然后调用createinstance实例化dll中的恶意类。
这里在本地调试,写了一个弹出messagebox的dll,修改了木马的代码,跳过了aes加解密的部分直接对post请求的内容解码后作为dll使用,可以看到成功弹出了messagebox。

用processhacker查看进程的.net程序集,可以看到加载进去的dll。
把进程的dump丢进windbg,lm后可以看到该dll模块。
导出该模块后用.net reflector可以逆向还原出该dll
.net 知识
.net
.NET 是一个免费的跨平台开放源代码开发人员平台,用于生成多种类型的应用程序。 .NET 可以运行使用多种语言编写的程序,其中 C# 是最常用的语言。 .NET 依赖于许多大规模应用在生产中使用的高性能运行时。
.net framework
.NET Framework是微软为开发应用程序而创建的主要运行在Windows操作系统的软件框架。它包含了大量的FCL(Framework Class Library)框架类库并且提供了多种语言之间的跨语言互操作。.NET Framework平台的应用程序在公共语言运行时(CLR)中执行,CLR是一个应用程序的虚拟机,它提供安全、内存管理和异常处理等服务。因此,使用.NET Framework编写的计算机代码称为“托管代码”。框架类库(FCL)和公共语言运行时(CLR)一起构成了.NET Framework。
.net core
.NET Core是一种模块化实现,可用于各种垂直领域,从数据中心扩展到基于触摸的设备,它是开源的,跨平台的,能在Windows、LinuxMac OSX等操作系统上运行,同时还支持docker等容器化环境安装和部署。
CLR
公共语言运行时。
具体含义依赖于上下文。 公共语言运行时通常指 .NET Framework 的运行时或 .NET 的运行时。
CLR 处理内存分配和管理。 CLR 也是一种虚拟机,不仅可执行应用,还可使用 JIT 编译器快速生成和编译代码。
适用于 .NET Framework 的 CLR 实现仅限于 Windows。
.NET 的 CLR 实现(也称为核心 CLR)是从与 .NET Framework CLR 相同的代码库生成的。 Core CLR 最初是 Silverlight 的运行时,并且设计为在多个平台上运行,尤其是在 Windows 和 OS X 上运行。它仍是跨平台运行时,现在包括对许多 Linux 分发的支持。
Assembly.Load()
用于加载程序集的方法,该方法有4个重载
public static System.Reflection.Assembly Load (byte[] rawAssembly, byte[]? rawSymbolStore);Load(Byte[])
加载带有基于通用对象文件格式 (COFF) 的映像的程序集,该映像包含已发出的程序集。
此方法重载始终在自己的独立加载上下文中创建新 Assembly 对象。
Load(String)
用指定的名称加载程序集。
程序集名称
程序集的名称存储在元数据中,它对程序集的范围及应用程序对程序集的使用有重要影响。 强名称程序集有一个完全限定的名称,由程序集的名称、区域性、公钥、版本号以及(可选)处理器体系结构组成。
myTypes, Version=1.0.1234.0, Culture=en-US, PublicKeyToken=b77a5c561934e089c, ProcessorArchitecture=msil完全限定名称表明 myTypes 程序集的强名称具有公钥标记、区域性值为美国英语、版本号为 1.0.1234.0。 它的处理器体系结构为 msil,表示程序集将以实时 (JIT) 方式编译为 32 位代码或 64 位代码(具体取决于操作系统和处理器)。
Load(AssemblyName)
在给定程序集的 AssemblyName 的情况下,加载程序集。
Load(Byte[], Byte[])
加载带有基于通用对象文件格式 (COFF) 的映像的程序集,此映像包含一个已发出的程序集,并且还可以选择包括程序集的符号。
Assembly.CreateInstance()
使用区分大小写的搜索,从此程序集中查找指定的类型,然后使用系统激活器创建它的实例。
public object? CreateInstance (string typeName);Type类
Type 类属于 System 命名空间,是 C# 反射机制的核心。它提供了用于获取类型信息的属性和方法,比如类的名称、命名空间、方法、属性、字段等。通过 Type 类,你可以动态地操作类型,这在需要处理动态类型或者插件系统时特别有用。
Type.GetType()
获取指定类的type对象
Type.GetMothod()
public System.Reflection.MethodInfo? GetMethod (string name, System.Reflection.BindingFlags bindingAttr, Type[] types);获取当前type的指定方法
返回一个MethodInfo类
MethodInfo类
发现方法的属性并提供对方法元数据的访问。
MethodInfo.Invoke(Object, Object[])
public object? Invoke(object? obj, object?[]? parameters);使用指定参数调用由当前实例表示的方法或构造函数。
obj:在其上调用方法或构造函数的对象。 如果方法是静态的,则忽略此参数。 如果构造函数是静态的,则此参数必须是 null 或定义构造函数的类的实例。
parameters:调用方法或构造函数的参数列表。 此对象数组在数量、顺序和类型方面与要调用的方法或构造函数的参数相同。 如果不存在任何参数,则参数应为 null。