黑客学徒日记-DotNetToJScript

在2017年,google项目Zero的研究员James发布了一个很棒的工具DotNetToJScript。如果你不知道,它介绍了一种反射式加载.net程序集的方法,使用了windows原生api例如客户端JScript、VBScript。从攻击者的角度来说,它打开了一个获得代码执行的新的大门,尤其是在受限环境当中。

3年过去了,许多传统杀软厂商能够检测到DotNetToJScirpt的payloads。然而,在合适的情况下,红队和紫队活动中仍然可以使用这个有效的工具进行代码执行。

红队和紫队测试

我想花一些时间讨论为什么你想要在红队/紫队测试中使用这个工具。早在2017年,在我的前半生当中,我所经历的红队测试都处于相当严格的检测当中。我们每周对蓝队进行测试,并且测试那些恶意文档、落盘下载payload的代码执行。我们会将进程切换到Cobalt Strike中,然而过程中会遇到一些问题。如果我们想要在周期测试中执行powershell,我们会被发现因为powershell日志采集和分析。即使我们经过混淆的powershell一句话,我们仍然比想象的更快被蓝队所发现。虽然powershell降级攻击让我们成功了一半,但是检测团队很快更新了规则以捕获到任何让我们能够降级到PS v2的命令行参数变种。

我们已经知道了这个项目:https://github.com/leechristensen/UnmanagedPowerShell,并且想要将它集成到我们的设施当中。但是直到DotNetToJScript的出现,我们才有了一个将两者结合起来的好主意!此外,我们的自定义maldoc经过了混淆,我们可以反射式加载powershell加载器.net程序集到内存当中,然后运行cobaltstrike 的powershell一句话来加载payload,无需从 VBA 执行 PowerShell 二进制文件!

当我们使用cobaltstrike的vba的时候,我们能够生成powershellRunner程序集通过.net 2.0框架,从而绕过powershell事件日志。尽管蓝队十分讨厌我们,他们最终基于 PowerShell 引擎启动事件日志实现了更好的 PowerShell 降级检测,我们不得不寻找其他绕过方式。这时候,我们聘请了蓝队中最犀利的防御。在一些推动和指导下,他重构了我们的恶意文档生成工具链,使用 .NET 程序集和 DotNetToJScript 技术将 Cobalt Strike 信标从 VBA 直接注入内存。

DotNetToJScript的可用性

尽管过去了几年,DotNet2jscript仍然是一个非常使用的程序来构建可执行payloads。根据使用的杀软或者EDR产品,仍然可以构造wscript、cscript可执行payloads。我们发现在我们红队、紫队实施当中,如果你使用赛门铁克、迈克菲、defender,使用JS、VBS、WSF脚本来进行代码执行比较困难。然而,在我们的客户已经放弃传统 AV 的许多项目中,仅使用 EDR 解决方案,基本的 JScript/VBScript 有效负载将产生非常可靠的执行。我们不会说出哪些 EDR 供应商在这些测试用例中表现不佳的名称,但可以肯定地说,我们测试的所有 EDR 在检测/预防通过 WScript、CScript 或两者执行的恶意 DotNetToJScript 有效负载方面都失败了。

如果你是内部红队,请尝试使用此项目来推动你的组织的预防/检测改进。

编译与执行DotNetToJScript

第一步是下载并构建它。 尽管可以从 GitHub 下载发布版本,但我个人更喜欢在可用时从源代码构建。

DotNetToJScript.exe -l JScript -o test.js ExampleAssembly.dll

可以将dll转换为可以直接双击执行的js

修改UnmanagedPowerShell

https://github.com/leechristensen/UnmanagedPowerShell

我们将修改 UnmanagedPowerShell 项目的 PowerShellRunner 以便与 DotNetToJScript 一起使用。

首先打开PowerShellRunner.cs源代码

所以这看起来很容易。 我们需要使用 System.Runtime.InteropServices 添加到 PowerShellRunner.cs 文件,以便我们可以将我们的类设置为 ComVisible。 此外,为了与 PowerShellRunner 进行交互,我们需要添加一个公共方法。 在代码的原始版本中,有一个名为 InvokePS() 的公共静态(类)方法,它从非托管 C++ 代码运行以执行任意 PowerShell。 我们将保留此方法并从我们将调用的成员方法中调用它

修改后的代码在这里可以下载:https://github.com/Whale3070/ctf-coding/blob/master/PowerShellRunner.cs

将修改后的代码编译,即可获得powershellRunner.dll

转化为js

接下来将powershellRunner.dll转化为js

使用dotnet将dll转化为js

1
DotNetToJScript.exe -d -l JScript -c "PowerShellRunner.PowerShellRunner" -o test.js  C:\Users\Local\Desktop\Tools\UnmanagedPowerShell-master\PowerShellRunner\bin\Release\PowerShellRunner.dll

-d 开启debug输出

-l 设置输出语言格式

-o 设置输出的文件名

修改js

修改后的js下载地址https://github.com/Whale3070/ctf-coding/blob/master/PowershellRunner.js

可以修改第292行的代码,在引号中可以执行任意powershell语句,并且在进程中不会有powershell进程。

js文件的运行方式是cscript test.js

参考资料