1
mirror of https://github.com/rapid7/metasploit-framework synced 2024-11-12 11:52:01 +01:00

Add domain join parse

This commit is contained in:
Meatballs 2013-04-26 00:20:10 +01:00
parent 235887ccb5
commit e2bf4882f0
3 changed files with 40 additions and 63 deletions

View File

@ -9,13 +9,14 @@ module Parser
# and uses REXML (as opposed to Nokogiri) for its XML parsing.
# See: http://technet.microsoft.com/en-us/library/ff715801
# http://technet.microsoft.com/en-us/library/cc749415(v=ws.10).aspx
# Samples: http://technet.microsoft.com/en-us/library/cc732280%28v=ws.10%29.aspx
class Unattend
def self.parse(xml)
return [] if xml.nil? or xml.elements['unattend'].nil?
return [] if xml.nil?
results = []
unattend = xml.elements['unattend']
return if unattend.nil?
return [] if unattend.nil?
unattend.each_element do |settings|
next if settings.class != REXML::Element
settings.get_elements('component').each do |c|
@ -23,6 +24,7 @@ class Unattend
results << extract_useraccounts(c.elements['UserAccounts'])
results << extract_autologon(c.elements['AutoLogon'])
results << extract_deployment(c.elements['WindowsDeploymentServices'])
results << extract_domain_join(c.elements['Identification/Credentials'])
end
end
return results.flatten
@ -48,6 +50,18 @@ class Unattend
return {'type' => 'wds', 'domain' => domain, 'username' => username, 'password' => password }
end
#
# Extract sensitive data from 'Secure' Domain Join
#
def self.extract_domain_join(credentials)
return [] if credentials.nil?
domain = credentials.elements['Domain'].get_text.value rescue ''
username = credentials.elements['Username'].get_text.value rescue ''
password = credentials.elements['Password'].get_text.value rescue ''
return {'type' => 'domain_join', 'domain' => domain, 'username' => username, 'password' => password }
end
#
# Extract sensitive data from AutoLogon
#
@ -129,59 +143,27 @@ class Unattend
return results
end
def self.create_tables(results)
return [] if results.nil? or results.empty?
tables = []
wds_table = Rex::Ui::Text::Table.new({
'Header' => 'WindowsDeploymentServices',
def self.create_table(results)
return nil if results.nil? or results.empty?
table = Rex::Ui::Text::Table.new({
'Header' => 'Unattend Credentials',
'Indent' => 1,
'Columns' => ['Domain', 'Username', 'Password']
'Columns' => ['Type', 'Domain', 'Username', 'Password', 'Groups']
})
autologin_table = Rex::Ui::Text::Table.new({
'Header' => 'AutoLogon',
'Indent' => 1,
'Columns' => ['Domain', 'Username', 'Password']
})
admin_table = Rex::Ui::Text::Table.new({
'Header' => 'AdministratorPasswords',
'Indent' => 1,
'Columns' => ['Username', 'Password']
})
domain_table = Rex::Ui::Text::Table.new({
'Header' => 'DomainAccounts',
'Indent' => 1,
'Columns' => ['Username', 'Group']
})
local_table = Rex::Ui::Text::Table.new({
'Header' => 'LocalAccounts',
'Indent' => 1,
'Columns' => ['Username', 'Password']
})
results.each do |result|
case result['type']
when 'wds'
wds_table << [result['domain'], result['username'], result['password']]
when 'auto'
autologin_table << [result['domain'], result['username'], result['password']]
when 'admin'
admin_table << [result['username'], result['password']]
when 'wds', 'auto', 'domain_join'
table << [result['type'], result['domain'], result['username'], result['password'], ""]
when 'admin', 'local'
table << [result['type'], "", result['username'], result['password'], ""]
when 'domain'
domain_table << [result['username'], result['group']]
when 'local'
local_table << [result['username'], result['password']]
table << [result['type'], "", result['username'], "", result['group']]
end
end
tables << autologin_table
tables << admin_table
tables << domain_table
tables << local_table
return tables
return table
end
end
end

View File

@ -55,11 +55,9 @@ class Metasploit3 < Msf::Auxiliary
end
results = Rex::Parser::Unattend.parse(xml)
tables = Rex::Parser::Unattend.create_tables(results)
tables.each do |table|
table.print
print_line
end
table = Rex::Parser::Unattend.create_table(results)
table.print unless table.nil?
print_line
end
end
end

View File

@ -79,12 +79,11 @@ class Metasploit3 < Msf::Post
#
# Save Rex tables separately
#
def save_cred_tables(cred_tables)
cred_tables.each do |t|
vprint_line("\n#{t.to_s}\n")
p = store_loot('windows.unattended.creds', 'text/csv', session, t.to_csv, t.header, t.header)
print_status("#{t.header} saved as: #{p}")
end
def save_cred_tables(cred_table)
t = cred_table
vprint_line("\n#{t.to_s}\n")
p = store_loot('windows.unattended.creds', 'text/csv', session, t.to_csv, t.header, t.header)
print_status("#{t.header} saved as: #{p}")
end
@ -165,14 +164,12 @@ class Metasploit3 < Msf::Post
return if not xml
results = Rex::Parser::Unattend.parse(xml)
tables = Rex::Parser::Unattend.create_tables(results)
tables.each do |table|
table.print
print_line
end
table = Rex::Parser::Unattend.create_table(results)
table.print unless table.nil?
print_line
# Save the data
save_cred_tables(tables.flatten) if not tables.empty?
save_cred_tables(table) if not table.nil?
return if not datastore['GETALL']
end