CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/multi/gather/dns_srv_lookup.rb
Views: 1904
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Post
7
include Msf::Auxiliary::Report
8
9
def initialize(info = {})
10
super(
11
update_info(
12
info,
13
'Name' => 'Multi Gather DNS Service Record Lookup Scan',
14
'Description' => %q{
15
Enumerates known SRV Records for a given domain using target host DNS query tool.
16
},
17
'License' => MSF_LICENSE,
18
'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>'],
19
'Platform' => %w[bsd linux osx solaris win],
20
'SessionTypes' => [ 'meterpreter', 'shell' ]
21
)
22
)
23
register_options(
24
[
25
26
OptString.new('DOMAIN', [true, 'Domain to perform SRV query against.'])
27
28
]
29
)
30
end
31
32
# Run Method for when run command is issued
33
def run
34
srvrcd = [
35
'_gc._tcp.', '_kerberos._tcp.', '_kerberos._udp.', '_ldap._tcp.',
36
'_test._tcp.', '_sips._tcp.', '_sip._udp.', '_sip._tcp.', '_aix._tcp.',
37
'_aix._tcp.', '_finger._tcp.', '_ftp._tcp.', '_http._tcp.', '_nntp._tcp.',
38
'_telnet._tcp.', '_whois._tcp.', '_h323cs._tcp.', '_h323cs._udp.',
39
'_h323be._tcp.', '_h323be._udp.', '_h323ls._tcp.',
40
'_h323ls._udp.', '_sipinternal._tcp.', '_sipinternaltls._tcp.',
41
'_sip._tls.', '_sipfederationtls._tcp.', '_jabber._tcp.',
42
'_xmpp-server._tcp.', '_xmpp-client._tcp.', '_imap.tcp.',
43
'_certificates._tcp.', '_crls._tcp.', '_pgpkeys._tcp.',
44
'_pgprevokations._tcp.', '_cmp._tcp.', '_svcp._tcp.', '_crl._tcp.',
45
'_ocsp._tcp.', '_PKIXREP._tcp.', '_smtp._tcp.', '_hkp._tcp.',
46
'_hkps._tcp.', '_jabber._udp.', '_xmpp-server._udp.', '_xmpp-client._udp.',
47
'_jabber-client._tcp.', '_jabber-client._udp.', '_kerberos.tcp.dc._msdcs.',
48
'_ldap._tcp.ForestDNSZones.', '_ldap._tcp.dc._msdcs.', '_ldap._tcp.pdc._msdcs.',
49
'_ldap._tcp.gc._msdcs.', '_kerberos._tcp.dc._msdcs.', '_kpasswd._tcp.', '_kpasswd._udp.',
50
'_imap._tcp.'
51
]
52
53
domain = datastore['DOMAIN']
54
55
print_status("Performing DNS SRV Record Lookup for Domain #{domain}")
56
57
a = []
58
59
case session.platform
60
when 'windows'
61
ns_opt = ' -query=srv '
62
cmd = 'nslookup'
63
when 'solaris'
64
ns_opt = ' -t srv '
65
cmd = '/usr/sbin/host'
66
else
67
ns_opt = ' -t srv '
68
cmd = '/usr/bin/host'
69
end
70
71
while !srvrcd.nil? && !srvrcd.empty?
72
1.upto session.max_threads do
73
a << framework.threads.spawn("Module(#{refname})", false, srvrcd.shift) do |srv|
74
next if srv.nil?
75
76
r = cmd_exec(cmd, ns_opt + "#{srv}#{domain}")
77
78
case session.platform
79
when 'windows'
80
if r =~ /\s*internet\saddress\s=\s/
81
nslookup_srv_consume("#{srv}#{domain}", r).each do |f|
82
print_good("\t#{f[:srv]} #{f[:target]} #{f[:port]} #{f[:ip]}")
83
end
84
end
85
else
86
found = host_srv_consume(r)
87
if found
88
found.each do |f|
89
print_good("\t#{f[:srv]} #{f[:target]} #{f[:port]} #{f[:ip]}")
90
end
91
end
92
end
93
end
94
a.map(&:join)
95
end
96
end
97
end
98
99
def nslookup_srv_consume(srv, ns_out)
100
srv_records = []
101
records = ns_out.split(srv)
102
103
# Get host to IP mapping
104
ip_map = {}
105
records.last.each_line do |e|
106
if e =~ /internet\saddress/i
107
host, ip = e.split(/\s*internet\saddress\s=\s/)
108
ip_map[host.strip] = ip.strip
109
end
110
end
111
112
# Get SRV parameter for each record
113
records.each do |r|
114
next unless r =~ /svr hostname/
115
116
rcrd = {}
117
rcrd[:srv] = srv
118
rcrd[:port] = r.scan(/port\s*=\s(\d*)/).join
119
rcrd[:target] = r.scan(/svr hostname\s*=\s(\S*)/).join
120
if !Rex::Socket.dotted_ip?(rcrd[:target])
121
w_get_ip(rcrd[:target]).each do |i|
122
rcrd[:ip] = i
123
report_host(host: rcrd[:ip].strip, name: rcrd[:target])
124
125
# Report on the service found
126
srv_info = rcrd[:srv].scan(/^_(\S*)\._(\w*)\./)[0]
127
128
report_service(host: rcrd[:ip].strip,
129
port: rcrd[:port].to_i,
130
proto: srv_info[1],
131
name: srv_info[0],
132
host_name: rcrd[:target])
133
srv_records << rcrd
134
end
135
else
136
137
rcrd[:ip] = ip_map[rcrd[:target]]
138
# Report hosts found
139
report_host(host: rcrd[:ip].strip, name: rcrd[:target])
140
141
# Report on the service found
142
srv_info = rcrd[:srv].scan(/^_(\S*)\._(\w*)\./)[0]
143
144
report_service(host: '1.2.3.4',
145
port: rcrd[:port].to_i,
146
proto: srv_info[1],
147
name: srv_info[0],
148
host_name: rcrd[:target])
149
srv_records << rcrd
150
end
151
end
152
return srv_records
153
end
154
155
# Get I{ for a given host using host, returns array
156
def get_ip(host)
157
ip_add = []
158
cmd_exec('host', " #{host}").each_line do |l|
159
ip = ''
160
ip = l.scan(/has address (\S*)$/).join
161
ip_add << ip if ip != ''
162
end
163
return ip_add
164
end
165
166
# Get IP for given host with nslookup, return array
167
def w_get_ip(host)
168
ips = []
169
data = cmd_exec("nslookup #{host}")
170
if data =~ /Name/
171
# Remove unnecessary data and get the section with the addresses
172
returned_data = data.split(/Name:/)[1]
173
# check each element of the array to see if they are IP
174
returned_data.gsub(/\r\n\t |\r\n|Aliases:|Addresses:|Address:/, ' ').split(' ').each do |e|
175
if Rex::Socket.dotted_ip?(e)
176
ips << e
177
end
178
end
179
end
180
return ips
181
end
182
183
def host_srv_consume(host_out)
184
srv_records = []
185
# Parse for SRV Records
186
host_out.each_line do |l|
187
next unless l =~ /has SRV/
188
189
record, port, target = l.scan(/(\S*) has SRV record \d*\s\d*\s(\d*)\s(\S*)/)[0]
190
if Rex::Socket.dotted_ip?(target)
191
rcrd = {}
192
rcrd[:srv] = record
193
rcrd[:port] = port
194
rcrd[:target] = target
195
rcrd[:ip] = target
196
srv_records << rcrd
197
198
# Report hosts found
199
report_host(host: rcrd[:ip], name: rcrd[:target])
200
201
# Report on the service found
202
srv_info = rcrd[:srv].scan(/^_(\S*)\._(\w*)\./)[0]
203
report_service(host: rcrd[:ip],
204
port: rcrd[:port],
205
proto: srv_info[1],
206
name: srv_info[0],
207
host_name: rcrd[:target])
208
else
209
get_ip(target).each do |i|
210
rcrd = {}
211
rcrd[:srv] = record
212
rcrd[:port] = port
213
rcrd[:target] = target
214
rcrd[:ip] = i
215
srv_records << rcrd
216
217
# Report hosts found
218
report_host(host: rcrd[:ip], name: rcrd[:target])
219
220
# Report on the service found
221
srv_info = rcrd[:srv].scan(/^_(\S*)\._(\w*)\./)[0]
222
report_service(host: rcrd[:ip],
223
port: rcrd[:port].to_i,
224
proto: srv_info[1],
225
name: srv_info[0],
226
host_name: rcrd[:target])
227
end
228
end
229
end
230
return srv_records
231
end
232
end
233
234