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