PowerShell。一旦我们知道如何运行编码命令,它就成为后期开发的必备条件,因为它使我能够访问ADSI,COM​​,Win32 API,.NET API以及各种第三方.NET库。大多数主要商业产品中存在某种PowerShell功能,那么与Metasploit交互中,以及高版本的Windows PowerShell Runspace添加Metrerpeter扩展。

0x01 加载powershell

和其他Metrepreter扩展一样,使用load命令加载。在界面中有3个可用的命令。
图片已损坏

0x02 powershell_execute

该命令在内存中的非托管运行空间中执行给定的字符串,并返回其输出的字符串。
-s选项允许在Runspace中的单独会话中指定一个ID或Name,这样使变量想要运行必须把一个代码与另一个代码分开。

0x03 powershell_import

这个命令基本上点将一个PS1文件导入当前的会话(会话)或加载一个.NET程序集。
脚本文件必须以.ps1扩展名结尾。
.NET程序集必须编译为.Net
Framework3.5,即您运行的Meterpreter会话的架构,并且必须以.dll结尾。
加载的任何程序集将影响运行空间中的所有会话。

0x04 powershell_shell

允许我们使用当前会话或者我们创建或创建的任何其他会话的交互式shell,包括我们导入的任何脚本或程序集。
这个交互式shell不是conhost shell,基本上不能使用tab完成或键盘快捷键的工作。
记住在Windows内部,当你使用powershell.exe它实际上是一个Conhost包装在System.Management.Automation库,那样倒是可以和所有的键盘交互。
图片已损坏

0x05 基本扩展使用

通过简单地使用要执行的命令或一系列命令来验证字符串来运行命令,并选择要给出会话的ID或名称。
图片已损坏
添加会话名称来显示变量之间的区别
图片已损坏

在交互式shell中,Metrepeter或其他任何有效载荷,可以随便编写任何命令并获取输出,但是退格键,制表符,箭头键等在终端没办法使用
图片已损坏
把要使用的脚本,使用powershell_import命令导入

图片已损坏

导入完成后,就可以使用创建的函数
图片已损坏

0x06 加载.NET程序集

加载JHSoftware DNS客户端程序
JHSoftware.DnsClient
图片已损坏
加载完成,再新构建一个使用程序集来执行DNS查询的脚本:

1
2
3
4
5
6
$dnsopts = new-object -TypeName JHSoftware.DnsClient+RequestOptions
$dnsopts.TimOut = New-TimeSpan -Seconds 2
$dnsopts.RetryCount = 1
$dns = [System.Net.IPAddress]'223.6.6.6'
$dnsopts.DnsServers += $dns
[JHSoftware.DnsClient]::Lookup('04z.net',[JHSoftware.DnsClient+RecordType]::A,$dnsopts).AnswerRecords

因为代码不在函数之外,所以上面的代码就像其他PowerShell脚本一样执行,我们可以看到调用程序集暴露的API的结果:

0x07 Meterpreter PowerShell绑定

除了可以添加命令和API之外,Meterpreter的功能可以和.NET命名交互,实现攻击的自动化和功能化,这些功能可以在GitHub repo中找到。

FileSystem
Elevate
Incognito - 允许创建用户,将用户添加到组和基本的令牌操纵。
Kiwi - 使用mimikatz执行内存中的密码。
User - 检查系统是否获取运行中的进程并获取用户SID的用户名。
Sys - 允许列出流程并获取系统信息
Transport - 添加并列出当前会话的新传输。

Meterpreter在MSF.Powershell.Meterpreter的空间下创建的运行模式内进行访问。首先被加载的是> 绑定中的每一个命令提供访问的扩展。在交互式PowerShell会话中完成所有攻击,而且可以使用Get-Memb> er cmdlet查看静态方法

图片已损坏

在运行Windows PowerShell 4.0及更高版本Windows(2012 R2,8.1和10)上,我们可以启用捕获脚本的日志记录,并保留详细的操作列表,甚至在执行Windows Defender进程之前传递代码以检查捕捉到像Invoke-Mimikatz等等。但是由于此扩展实例化引擎2.0的引擎,这种缓解没有任何效果。新版本Windows默认情况下,Engine 2.0是可选功能,因此当尝试执行该操作时,会导致扩展失败。但是还会加载,而且不会报错。

enum_ps_env,可以检测出相应的powershell脚本版本号
图片已损坏
其实是通过读取注册表的方式进行的,部分代码如下
参考:https://github.com/darkoperator/Meterpreter-Scripts/blob/master/post/windows/gather/enum_ps_env.rb

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
  # Enumerate the PowerShell version.
  #-----------------------------------------------------------------------
  def enum_version
    if registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\").include?("3")
        powershell_version = registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\3\\PowerShellEngine","PowerShellVersion")
      else
        powershell_version = registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellEngine","PowerShellVersion")
      end

      print_good("Version: #{powershell_version}")
      report_note(
        :host   => session,
        :type   => 'host.ps.version',
        :data   => { :version => powershell_version },
        :update => :unique_data
      )
      return powershell_version
  end

  # Enumerate the ExecutionPolicy in place for User and Machine.
  #-----------------------------------------------------------------------
  def enum_execpolicy
    # Enumerate the machine policy
    begin
      powershell_machine_policy = registry_getvaldata("HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\PowerShell","ExecutionPolicy")
    rescue
      powershell_machine_policy = "Restricted"
    end

    # Enumerate the User Policy
    begin
      powershell_user_policy = registry_getvaldata("HKCU\\Software\\Microsoft\\PowerShell\\1\\ShellIds\\Microsoft.PowerShell","ExecutionPolicy")
    rescue
      powershell_user_policy = "Restricted"
    end
      print_good("Current User Execution Policy: #{powershell_user_policy}")
      print_good("Machine Execution Policy: #{powershell_machine_policy}")
      report_note(
        :host   => session,
        :type   => 'host.ps.execpol.user',
        :data   => { :execpol => powershell_user_policy },
        :update => :unique_data
      )
      report_note(
        :host   => session,
        :type   => 'host.ps.execpol.machine',
        :data   => { :execpol => powershell_machine_policy },
        :update => :unique_data
      )
  end

  #-----------------------------------------------------------------------

  def enum_pssnapins
    powershell_path = registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\ShellIds\\Microsoft.PowerShell","Path")
      print_status("Path: #{powershell_path}")
      if registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1").include?("PowerShellSnapIns")
        print_status("Powershell Snap-Ins:")
        registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns").each do |si|
          print_status("\tSnap-In: #{si}")
          registry_enumvals("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns\\#{si}").each do |v|
            print_status("\t\t#{v}: #{registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns\\#{si}",v)}")
          end
        end
      else
        print_status("No PowerShell Snap-Ins are installed")

      end
  end

  #-----------------------------------------------------------------------
  def check_ps2enabled
    os = sysinfo['OS']
    if os =~ /Windows 2012|2016|8|10/
      print_status('Checking if PSv2 engine is enabled.')
      path = "HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1"
      if registry_enumkeys(path).include?("PowerShellEngine")
        if registry_getvaldata("#{path}\\PowerShellEngine", 'PowerShellVersion') == '2.0'
          print_good("\tPowerShell 2.0 engine feature is enabled.")
          report_note(
            :host   => session,
            :type   => 'host.log.ps_v2_feature',
            :data   => {
              :enabled => true},
            :update => :unique_data
          )
        else
          print_good("\tPowerShell 2.0 engine feature is not enabled.")
          report_note(
            :host   => session,
            :type   => 'host.log.ps_v2_feature',
            :data   => {
              :enabled => false},
            :update => :unique_data
          )
        end
      end
    end
  end

  #-----------------------------------------------------------------------
  def enum_powershell
    #Check if PowerShell is Installed
    if registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\").include?("PowerShell")
      print_status("Powershell is Installed on this system.")
      users = enum_users
      powershell_version = enum_version
      enum_execpolicy
      enum_pssnapins
      enum_modules(powershell_version, users)
      enum_profiles(users)
      enum_logging(powershell_version)
      check_ps2enabled
    end
  end