GadgetToJScript 利用分析

发布于 2024-11-04 12:18:11 字数 6609 浏览 17 评论 0

0x00 前言

GadgetToJScrip 能够将.Net 程序封装在 js 或 vbs 脚本中,相比于 James Forshaw 开源的 DotNetToJScript ,修改了反序列化调用链,能够绕过 AMSI,添加了绕过.Net 4.8+阻止 Assembly.Load 的功能

本文用来记录研究细节,分析利用思路,简要修改原工程,更便于测试 Payload,分享同 SILENTTRINITY 结合的方法

0x01 简介

本文将要介绍以下内容:

  • GadgetToJScript 的代码分析和实现逻辑
  • 为了便于测试 Payload 的修改方法
  • 利用分析
  • 同 SILENTTRINITY 结合的方法

0x02 GadgetToJScript 的代码分析和实现逻辑

1.代码分析

(1)templates 文件夹

保存有 js、vbs 和 hta 的模板

模板文件同 DotNetToJScript 基本相同,区别如下:

  1. 添加了一些对.Net 版本的判断,读取注册表 HKLM\\SOFTWARE\\Microsoft\\.NETFramework\\v4.0.30319\\ ,如果成功,版本为 4.0.30319,否则为 2.0.50727
  2. 做了两次反序列化,第一次是禁用 ActivitySurrogateSelector 类型检查,用来绕过.Net 4.8+阻止 Assembly.Load 的功能,第二次用来加载.Net 程序

(2)Program.cs

主程序,替换模板中的变量,计算长度,生成最终的 js、vbs 和 hta 脚本

(3)TestAssemblyLoader.cs

Payload 以字符串的形式保存,使用 CompileAssemblyFromSource 对其进行动态编译,编译结果保存在内存(results.CompiledAssembly) 中

关键函数: CompileAssemblyFromSource

其中,GenerateInMemory 属性默认为 true,表示把编译生成的程序集保留在内存中,通过 CompilerResults 实例的 CompiledAssembly 可以获取,如果设置为 false,可以将编译生成的程序集保存在本地硬盘

参考资料:https://docs.microsoft.com/en-us/dotnet/api/system.codedom.compiler.codedomprovider.compileassemblyfromsource?view=netframework-4.8

(4)_ASurrogateGadgetGenerator.cs

构建一个链来映射字节数组以创建类的实例:

byte[] -> Assembly.Load -> Assembly -> Assembly.GetType -> Type[] -> Activator.CreateInstance -> Win!

该段代码应该来自于: https://github.com/pwntester/ysoserial.net/blob/master/ysoserial/Generators/ActivitySurrogateSelectorGenerator.cs

可以理解为 TestAssemblyLoader.cs 实现将编译结果保存在内存(results.CompiledAssembly) 中,_ASurrogateGadgetGenerator.cs 用来读取这段内存并实现对.Net 程序的调用

(5)_DisableTypeCheckGadgetGenerator.cs

用来绕过.Net 4.8+阻止 Assembly.Load 的功能

详细细节可参考:https://silentbreaksecurity.com/re-animating-activitysurrogateselector/

(6)_SurrogateSelector.cs

创建 Surrogate 类,该类充当包装器

该段代码应该来自于: https://github.com/pwntester/ysoserial.net/blob/bb695b8162bdc1d191c32f6a234a8fff5665ab9b/ysoserial/Generators/ActivitySurrogateSelectorGenerator.cs

2.实现逻辑

  1. 执行 TestAssemblyLoader.cs,将字符串形式的 Payload 进行动态编译,编译结果保存在内存(results.CompiledAssembly) 中
  2. 执行_ASurrogateGadgetGenerator.cs,读取 1 中的内存并实现.Net 程序的调用
  3. 执行_DisableTypeCheckGadgetGenerator.cs,实现绕过.Net 4.8+阻止 Assembly.Load 的功能
  4. 执行 Program.cs,替换模板文件的两个变量,计算长度,生成最终的 js、vbs 和 hta 脚本

0x03 为了便于测试 Payload 的修改方法

查看文件 TestAssemblyLoader.cs,Payload 以字符串的形式进行保存,部分内容如下:

           string _testClass = @"

                using System;
                using System.Runtime.InteropServices;
                    public class TestClass
                    {
                        " + "[DllImport(\"User32.dll\", CharSet = CharSet.Unicode)]" +
                        @"public static extern int MessageBox(IntPtr h, string m, string c, int t);
                        public TestClass(){
                            " + "MessageBox((IntPtr)0, \"Test .NET Assembly Constructor Called.\", \"Coolio\", 0);" +
                        @"}
                    }           
            ";

我们可以看到,Payload 以字符串的形式进行保存时,需要考虑转义字符,这会影响 Payload 的开发效率,也不是很直观

这里给出我的一个解决方法:将 CompileAssemblyFromSource 换成 CompileAssemblyFromFile

这样可以从文件中读取 Payload,也就不再需要考虑转义字符

我修改过的版本已上传至 github,地址如下:https://github.com/3gstudent/GadgetToJScript

我的版本修改了 TestAssemblyLoader.cs,关键代码如下:

CompilerResults results = provider.CompileAssemblyFromFile(parameters, "payload.txt");

从固定文件 payload.txt 中读取 Payload,如果想要实现同原工程相同的功能,payload.txt 的内容如下:

using System;
using System.Runtime.InteropServices;
public class TestClass
{
    [DllImport("User32.dll", CharSet = CharSet.Unicode)]public static extern int MessageBox(IntPtr h, string m, string c, int t);
    public TestClass()
    {
        MessageBox((IntPtr)0, "Test .NET Assembly Constructor Called.", "Coolio", 0);
        }
}

Payload 看起来更加直观,也更易于开发

0x04 利用分析

GadgetToJScript 应该算是对 James Forshaw 开源的 DotNetToJScript 的进一步利用,添加的反序列化调用链不需要调用 d.DynamicInvoke(al.ToArray()).CreateInstance(entry_class) ,能够绕过一些杀毒软件对特定代码的检测,可尝试以此为模板做进一步的开发

对于 Payload 的进一步利用,需要更换成 csharp 的格式,这让我想到了 SILENTTRINITY

0x05 同 SILENTTRINITY 结合的方法

注:

SILENTTRINITY 正在持续更新中,添加了更多功能,我文章的内容有可能不再准确

搭建好 SILENTTRINITY 后,选择生成 csharp 格式的 stager,命令如下:

stagers
list
use csharp
generate http

提取 stager.cs 中的代码,填入 payload.txt,最终示例代码已上传至 github,地址如下: https://github.com/3gstudent/GadgetToJScript/blob/master/payload.txt

编译我修改过的 GadgetToJScript,将 payload.txt 保存在同级目录,生成 js 脚本的命令如下:

GadgetToJScript.exe -w js -o 1

生成 1.js

执行 1.js 后,SILENTTRINITY 获得上线信息,进程名称为 wscript,如下图

Alt text

测试成功

0x06 小结

本文介绍了 GadgetToJScript 的代码细节和实现流程,简要修改原工程,更便于测试 Payload,分析利用思路,分享同 SILENTTRINITY 结合的方法。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

卷耳

暂无简介

文章
评论
25 人气
更多

推荐作者

迎风吟唱

文章 0 评论 0

qq_hXErI

文章 0 评论 0

茶底世界

文章 0 评论 0

捎一片雪花

文章 0 评论 0

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文