diff --git a/lib/msf/base/sessions/meterpreter.rb b/lib/msf/base/sessions/meterpreter.rb index 34111dc3be..9bcf08b1f3 100644 --- a/lib/msf/base/sessions/meterpreter.rb +++ b/lib/msf/base/sessions/meterpreter.rb @@ -152,6 +152,12 @@ class Meterpreter < Rex::Post::Meterpreter::Client # TODO: This session was either staged or previously known, and so we should do some accounting here! end + # Unhook the process prior to loading stdapi to reduce logging/inspection by any AV/PSP + if datastore['AutoUnhookProcess'] == true + console.run_single('load unhook') + console.run_single('unhook_pe') + end + unless datastore['AutoLoadStdapi'] == false session.load_stdapi diff --git a/lib/msf/base/sessions/meterpreter_options.rb b/lib/msf/base/sessions/meterpreter_options.rb index a037203e72..f6acca662d 100644 --- a/lib/msf/base/sessions/meterpreter_options.rb +++ b/lib/msf/base/sessions/meterpreter_options.rb @@ -70,7 +70,11 @@ module Msf OptString.new( 'PayloadProcessCommandLine', [ false, 'The displayed command line that will be used by the payload', ''] - ) + ), + OptBool.new( + 'AutoUnhookProcess', + [true, "Automatically load the unhook extension and unhook the process", false] + ), ], self.class ) diff --git a/lib/rex/post/meterpreter/extensions/unhook/tlv.rb b/lib/rex/post/meterpreter/extensions/unhook/tlv.rb new file mode 100644 index 0000000000..88eee2c18a --- /dev/null +++ b/lib/rex/post/meterpreter/extensions/unhook/tlv.rb @@ -0,0 +1,12 @@ +# -*- coding: binary -*- +module Rex +module Post +module Meterpreter +module Extensions +module Unhook + TLV_TYPE_UNHOOK_ERROR_CODE = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 1) +end +end +end +end +end diff --git a/lib/rex/post/meterpreter/extensions/unhook/unhook.rb b/lib/rex/post/meterpreter/extensions/unhook/unhook.rb new file mode 100644 index 0000000000..e42104e6c6 --- /dev/null +++ b/lib/rex/post/meterpreter/extensions/unhook/unhook.rb @@ -0,0 +1,42 @@ +# -*- coding: binary -*- + +require 'rex/post/meterpreter/extensions/unhook/tlv' + +module Rex +module Post +module Meterpreter +module Extensions +module Unhook + +### +# +# This meterpreter extension can be used to unhook PSP products +# +### +# +class Unhook < Extension + UNHOOK_ERROR_SUCCESS = 0 + + def initialize(client) + super(client, 'unhook') + + client.register_extension_aliases( + [ + { + 'name' => 'unhook', + 'ext' => self + }, + ]) + end + + def unhook_pe + request = Packet.create_request('unhook_pe') + response = client.send_request(request) + response_code = response.get_tlv_value(TLV_TYPE_UNHOOK_ERROR_CODE) + + raise Exception, "Did not get ERROR_SUCCESS back!" if response_code != UNHOOK_ERROR_SUCCESS + return 0, response_code, nil + end + +end +end; end; end; end; end diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/unhook.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/unhook.rb new file mode 100644 index 0000000000..aeaaea35ed --- /dev/null +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/unhook.rb @@ -0,0 +1,66 @@ +# -*- coding: binary -*- +require 'rex/post/meterpreter' + +module Rex +module Post +module Meterpreter +module Ui + +### +# +# Unhook extension - unhook PSP products +# +### +class Console::CommandDispatcher::Unhook + + Klass = Console::CommandDispatcher::Unhook + + include Console::CommandDispatcher + + # + # Name for this dispatcher + # + def name + 'Unhook' + end + + # + # List of supported commands. + # + def commands + { + 'unhook_pe' => 'Unhook the current process' + } + end + + @@bf_execute_opts = Rex::Parser::Arguments.new( + '-h' => [false, 'Help banner'] + ) + + def unhook_execute_usage + print_line('Usage: unhook_pe') + print_line + print_line('Removes any runtime hooks placed by PSPs') + print_line(@@bf_execute_opts.usage) + end + + # + # Execute a simple BF command string + # + def cmd_unhook_pe(*args) + if args.include?('-h') + unhook_execute_usage + return false + end + + result = client.unhook.unhook_pe + + print_good("Command execution completed:\n#{result}") + end + +end + +end +end +end +end