Better cleanup and address comments

unstable
Meatballs1 2013-01-20 00:19:17 +00:00
parent 771baa3181
commit 567185ec65
2 changed files with 40 additions and 27 deletions

View File

@ -94,6 +94,9 @@ class Def_wldap32
['DWORD', 'res', 'in'] ['DWORD', 'res', 'in']
]) ])
dll.add_function('ldap_unbind', 'DWORD', [
['DWORD', 'ld', 'in']
])
return dll return dll
end end

View File

@ -51,39 +51,32 @@ class Metasploit3 < Msf::Post
end end
def run def run
if sysinfo["Architecture"] =~ /x64/i unless session.platform == "x64/win64"
print_error("Does not work in x64 see: http://dev.metasploit.com/redmine/issues/7639"); print_error("Does not work in x86 see: http://dev.metasploit.com/redmine/issues/7639");
return return
end end
print_status("Connecting to default LDAP server") print_status("Connecting to default LDAP server")
session_handle = bind_default_ldap_server session_handle = bind_default_ldap_server
if session_handle == 0 return false unless session_handle
return
end
print_status("Querying default naming context") print_status("Querying default naming context")
defaultNamingContext = query_ldap(session_handle, "", 0, "(objectClass=computer)", ["defaultNamingContext"])[0]['attributes'][0]['values']
query_result = query_ldap(session_handle, "", 0, "(objectClass=computer)", ["defaultNamingContext"])
first_entry_attributes = query_result[0]['attributes']
defaultNamingContext = first_entry_attributes[0]['values'] # Value from First Attribute of First Entry
print_status("Default Naming Context #{defaultNamingContext}") print_status("Default Naming Context #{defaultNamingContext}")
attributes = datastore['ATTRIBS'].split(',') attributes = datastore['ATTRIBS'].split(',')
#attributes = [ 'objectClass','cn', 'description', 'distinguishedName','instanceType','whenCreated',
# 'whenChanged','uSNCreated','uSNChanged','name','objectGUID',
# 'userAccountControl','badPwdCount','codePage','countryCode',
# 'badPasswordTime','lastLogoff','lastLogon','localPolicyFlags',
# 'pwdLastSet','primaryGroupID','objectSid','accountExpires',
# 'logonCount','sAMAccountName','sAMAccountType','operatingSystem',
# 'operatingSystemVersion','operatingSystemServicePack','serverReferenceBL',
# 'dNSHostName','rIDSetPreferences','servicePrincipalName','objectCategory',
# 'netbootSCPBL','isCriticalSystemObject','frsComputerReferenceBL',
# 'lastLogonTimestamp','msDS-SupportedEncryptionTypes'
# ]
print_status("Querying computer objects - Please wait...") print_status("Querying computer objects - Please wait...")
results = query_ldap(session_handle, defaultNamingContext, 2, "(objectClass=computer)", attributes) results = query_ldap(session_handle, defaultNamingContext, 2, "(objectClass=computer)", attributes)
print_status("Unbinding from LDAP service.")
wldap32.ldap_unbind(session_handle)
results_table = Rex::Ui::Text::Table.new( results_table = Rex::Ui::Text::Table.new(
'Header' => 'AD Computers', 'Header' => 'AD Computers',
'Indent' => 1, 'Indent' => 1,
@ -108,7 +101,7 @@ class Metasploit3 < Msf::Post
print_line results_table.to_s print_line results_table.to_s
if datastore['STORE'] if datastore['STORE']
stored_path = store_loot('ad.computers', 'text/plain', session, results_table.to_s) stored_path = store_loot('ad.computers', 'text/plain', session, results_table.to_csv)
print_status("Results saved to: #{stored_path}") print_status("Results saved to: #{stored_path}")
end end
end end
@ -124,15 +117,17 @@ class Metasploit3 < Msf::Post
if session_handle == 0 if session_handle == 0
print_error("Unable to connect to LDAP server") print_error("Unable to connect to LDAP server")
return 0 wldap32.ldap_unbind(session_handle)
return false
end end
vprint_status ("Binding to LDAP server.") vprint_status ("Binding to LDAP server.")
bind = wldap32.ldap_bind_sA(session_handle, nil, nil, 0x0486)['return'] #LDAP_AUTH_NEGOTIATE bind = wldap32.ldap_bind_sA(session_handle, nil, nil, 0x0486)['return'] #LDAP_AUTH_NEGOTIATE 0x0486
if bind != 0 if bind != 0
print_error("Unable to bind to LDAP server") print_error("Unable to bind to LDAP server")
return 0 wldap32.ldap_unbind(session_handle)
return false
end end
return session_handle return session_handle
@ -150,6 +145,13 @@ class Metasploit3 < Msf::Post
end end
search_count = wldap32.ldap_count_entries(session_handle, search['res'])['return'] search_count = wldap32.ldap_count_entries(session_handle, search['res'])['return']
if(search_count == 0)
print_error("No entries retrieved")
wldap32.ldap_msgfree(search['res'])
return
end
print_status("Entries retrieved: #{search_count}") print_status("Entries retrieved: #{search_count}")
vprint_status("Retrieving results...") vprint_status("Retrieving results...")
@ -163,15 +165,22 @@ class Metasploit3 < Msf::Post
max_search = [datastore['MAX_SEARCH'], search_count].min max_search = [datastore['MAX_SEARCH'], search_count].min
end end
# user definied limit on entries to search? 0.upto(max_search - 1) do |i|
for i in 0..(max_search-1)
print '.' print '.'
if i==0 if(i==0)
entries[i] = wldap32.ldap_first_entry(session_handle, search['res'])['return'] entries[0] = wldap32.ldap_first_entry(session_handle, search['res'])['return']
else else
entries[i] = wldap32.ldap_next_entry(session_handle, entries[i-1])['return'] entries[i] = wldap32.ldap_next_entry(session_handle, entries[i-1])['return']
end end
if(entries[i] == 0)
print_error("Failed to get entry.")
wldap32.ldap_unbind(session_handle)
wldap32.ldap_msgfree(search['res'])
return
end
vprint_status("Entry #{i}: #{entries[i]}") vprint_status("Entry #{i}: #{entries[i]}")
attribute_results = [] attribute_results = []
@ -191,7 +200,7 @@ class Metasploit3 < Msf::Post
if count < 1 if count < 1
vprint_error("Bad Value List") vprint_error("Bad Value List")
else else
for j in 0..(count-1) 0.upto(count - 1) do |j|
p_value = client.railgun.memread(pp_value+(j*4), 4).unpack('V*')[0] p_value = client.railgun.memread(pp_value+(j*4), 4).unpack('V*')[0]
vprint_status "p_value: 0x#{p_value.to_s(16)}" vprint_status "p_value: 0x#{p_value.to_s(16)}"
value = read_value(p_value) value = read_value(p_value)
@ -209,6 +218,7 @@ class Metasploit3 < Msf::Post
if pp_value != 0 if pp_value != 0
vprint_status("Free value memory.") vprint_status("Free value memory.")
wldap32.ldap_value_free(pp_value) wldap32.ldap_value_free(pp_value)
# wldap32.ldap_memfree(attr) No need to free attributes as these are hardcoded
end end
attribute_results << {"name" => attr, "values" => value_results} attribute_results << {"name" => attr, "values" => value_results}