GadgetToJScript 利用分析

发布于 2024-11-04 12:18:11 字数 6609 浏览 4 评论 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技术交流群

发布评论

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

关于作者

卷耳

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

謌踐踏愛綪

文章 0 评论 0

开始看清了

文章 0 评论 0

高速公鹿

文章 0 评论 0

alipaysp_PLnULTzf66

文章 0 评论 0

热情消退

文章 0 评论 0

白色月光

文章 0 评论 0

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