PageRenderTime 58ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/auxiliary/gather/dns_srv_enum.rb

https://gitlab.com/alx741/metasploit-framework
Ruby | 298 lines | 275 code | 18 blank | 5 comment | 22 complexity | 1255d556f72c3a52e2bd9ca091a9aa8b MD5 | raw file
  1. ##
  2. # This module requires Metasploit: http://metasploit.com/download
  3. # Current source: https://github.com/rapid7/metasploit-framework
  4. ##
  5. require 'msf/core'
  6. require "net/dns/resolver"
  7. require 'rex'
  8. class Metasploit3 < Msf::Auxiliary
  9. include Msf::Auxiliary::Report
  10. def initialize(info = {})
  11. super(update_info(info,
  12. 'Name' => 'DNS Common Service Record Enumeration',
  13. 'Description' => %q{
  14. This module enumerates common DNS service records in a given domain. By setting
  15. the ALL_DNS to true, all the name servers of a given domain are used for
  16. enumeration. Otherwise only the system dns is used for enumration. in order to get
  17. all the available name servers for the given domain the SOA and NS records are
  18. queried. In order to convert from domain names to IP addresses queries for A and
  19. AAAA (IPv6) records are used. For Active Directory, it is possible to specify sites.
  20. },
  21. 'Author' => [
  22. 'Carlos Perez <carlos_perez[at]darkoperator.com>', # First and main.
  23. 'Fabrice RAFART' # mainly change for AD and report.
  24. ],
  25. 'License' => BSD_LICENSE
  26. ))
  27. register_options(
  28. [
  29. OptString.new('DOMAIN', [true, "The target domain name."]),
  30. OptString.new('SITES', [false, "The Active Directory site names to test (comma-separated)."]),
  31. OptBool.new('ALL_NS', [false, "Run against all name servers for the given domain.", false])
  32. ], self.class)
  33. register_advanced_options(
  34. [
  35. OptInt.new('RETRY', [false, "Number of times to try to resolve a record if no response is received.", 2]),
  36. OptInt.new('RETRY_INTERVAL', [false, "Number of seconds to wait before doing a retry.", 2])
  37. ], self.class)
  38. end
  39. def run
  40. records = []
  41. @res = Net::DNS::Resolver.new()
  42. if datastore['RETRY']
  43. @res.retry = datastore['RETRY'].to_i
  44. end
  45. if datastore['RETRY_INTERVAL']
  46. @res.retry_interval = datastore['RETRY_INTERVAL'].to_i
  47. end
  48. print_status("Enumerating SRV Records for #{datastore['DOMAIN']}")
  49. records = records + srvqry(datastore['DOMAIN'])
  50. if datastore["ALL_NS"]
  51. get_soa(datastore['DOMAIN']).each do |s|
  52. switchdns(s[:address])
  53. records = records + srvqry(datastore['DOMAIN'])
  54. end
  55. get_ns(datastore['DOMAIN']).each do |ns|
  56. switchdns(ns[:address])
  57. records =records + srvqry(datastore['DOMAIN'])
  58. end
  59. end
  60. records.uniq!
  61. records.each do |r|
  62. print_good("Host: #{r[:host]} IP: #{r[:address].to_s} Service: #{r[:service]} Protocol: #{r[:proto]} Port: #{r[:port]} Query: #{r[:query]}")
  63. report_host(
  64. :host => r[:address].to_s,
  65. :name => r[:host]
  66. )
  67. report_service(
  68. :host=> r[:address].to_s,
  69. :port => r[:port].to_i,
  70. :proto => r[:proto],
  71. :name => r[:service],
  72. :host_name => r[:host]
  73. )
  74. report_note(
  75. :type => 'SRV record',
  76. :host => r[:address].to_s,
  77. :port => r[:port].to_i,
  78. :proto => r[:proto],
  79. :data => r[:query]
  80. )
  81. end
  82. end
  83. def get_soa(target)
  84. results = []
  85. query = @res.query(target, "SOA")
  86. return results if not query
  87. (query.answer.select { |i| i.class == Net::DNS::RR::SOA}).each do |rr|
  88. if Rex::Socket.dotted_ip?(rr.mname)
  89. record = {}
  90. record[:host] = rr.mname
  91. record[:type] = "SOA"
  92. record[:address] = rr.mname
  93. results << record
  94. else
  95. get_ip(rr.mname).each do |ip|
  96. record = {}
  97. record[:host] = rr.mname.gsub(/\.$/,'')
  98. record[:type] = "SOA"
  99. record[:address] = ip[:address].to_s
  100. results << record
  101. end
  102. end
  103. end
  104. return results
  105. end
  106. def srvqry(dom)
  107. results = []
  108. # Most common SRV Records
  109. srvrcd = [
  110. '_aix._tcp.',
  111. '_aix._tcp.',
  112. '_certificates._tcp.',
  113. '_cmp._tcp.',
  114. '_crl._tcp.',
  115. '_crls._tcp.',
  116. '_finger._tcp.',
  117. '_ftp._tcp.',
  118. '_gc._tcp.',
  119. '_gc._tcp.Default-First-Site-Name._sites.',
  120. '_h323be._tcp.',
  121. '_h323be._udp.',
  122. '_h323cs._tcp.',
  123. '_h323cs._udp.',
  124. '_h323ls._tcp.',
  125. '_h323ls._udp.',
  126. '_hkp._tcp.',
  127. '_hkps._tcp.',
  128. '_http._tcp.',
  129. '_imap.tcp.',
  130. '_jabber-client._tcp.',
  131. '_jabber-client._udp.',
  132. '_jabber._tcp.',
  133. '_jabber._udp.',
  134. '_kerberos._tcp.',
  135. '_kerberos._tcp.dc._msdcs.',
  136. '_kerberos._tcp.Default-First-Site-Name._sites.',
  137. '_kerberos._udp.',
  138. '_kerberos.tcp.Default-First-Site-Name._sites.dc._msdcs.',
  139. '_kpasswd._tcp.',
  140. '_kpasswd._udp.',
  141. '_ldap._tcp.',
  142. '_ldap._tcp.dc._msdcs.',
  143. '_ldap._tcp.Default-First-Site-Name._sites.',
  144. '_ldap._tcp.Default-First-Site-Name._sites.dc._msdcs.',
  145. '_ldap._tcp.Default-First-Site-Name._sites.gc._msdcs.',
  146. '_ldap._tcp.ForestDNSZones.',
  147. '_ldap._tcp.gc._msdcs.',
  148. '_ldap._tcp.pdc._msdcs.',
  149. '_nntp._tcp.',
  150. '_ocsp._tcp.',
  151. '_pgpkeys._tcp.',
  152. '_pgprevokations._tcp.',
  153. '_PKIXREP._tcp.',
  154. '_sip._tcp.',
  155. '_sip._tls.',
  156. '_sip._udp.',
  157. '_sipfederationtls._tcp.',
  158. '_sipinternal._tcp.',
  159. '_sipinternaltls._tcp.',
  160. '_sips._tcp.',
  161. '_smtp._tcp.',
  162. '_svcp._tcp.',
  163. '_telnet._tcp.',
  164. '_test._tcp.',
  165. '_whois._tcp.',
  166. '_xmpp-client._tcp.',
  167. '_xmpp-client._udp.',
  168. '_xmpp-server._tcp.',
  169. '_xmpp-server._udp.'
  170. ]
  171. sites = []
  172. if datastore['SITES']
  173. sites = datastore['SITES'].split(',')
  174. end
  175. sites.each do |site|
  176. srvrcd = srvrcd + [
  177. '_gc._tcp.'+site+'._sites.',
  178. '_kerberos._tcp.'+site+'._sites.',
  179. '_kerberos.tcp.'+site+'._sites.dc._msdcs.',
  180. '_ldap._tcp.'+site+'._sites.',
  181. '_ldap._tcp.'+site+'._sites.dc._msdcs.',
  182. '_ldap._tcp.'+site+'._sites.gc._msdcs.'
  183. ]
  184. end
  185. srvrcd.each do |srvt|
  186. trg = "#{srvt}#{dom}"
  187. begin
  188. query = @res.query(trg , Net::DNS::SRV)
  189. next unless query
  190. query.answer.each do |srv|
  191. if Rex::Socket.dotted_ip?(srv.host)
  192. record = {}
  193. srv_info = srvt.scan(/^_(\S*)\._(tcp|udp)\./)[0]
  194. record[:query] = "#{srvt}#{dom}"
  195. record[:host] = srv.host.gsub(/\.$/,'')
  196. record[:type] = "SRV"
  197. record[:address] = srv.host
  198. record[:srv] = srvt
  199. record[:service] = srv_info[0]
  200. record[:proto] = srv_info[1]
  201. record[:port] = srv.port
  202. record[:priority] = srv.priority
  203. results << record
  204. vprint_status("SRV Record: #{trg} Host: #{srv.host.gsub(/\.$/,'')} IP: #{srv.host} Port: #{srv.port} Priority: #{srv.priority}")
  205. else
  206. get_ip(srv.host.gsub(/\.$/,'')).each do |ip|
  207. record = {}
  208. srv_info = srvt.scan(/^_(\S*)\._(tcp|udp)\./)[0]
  209. record[:query] = "#{srvt}#{dom}"
  210. record[:host] = srv.host.gsub(/\.$/,'')
  211. record[:type] = "SRV"
  212. record[:address] = ip[:address]
  213. record[:srv] = srvt
  214. record[:service] = srv_info[0]
  215. record[:proto] = srv_info[1]
  216. record[:port] = srv.port
  217. record[:priority] = srv.priority
  218. results << record
  219. vprint_status("SRV Record: #{trg} Host: #{srv.host} IP: #{ip[:address]} Port: #{srv.port} Priority: #{srv.priority}")
  220. end
  221. end
  222. end
  223. rescue
  224. end
  225. end
  226. return results
  227. end
  228. def get_ip(host)
  229. results = []
  230. query = @res.search(host, "A")
  231. if (query)
  232. query.answer.each do |rr|
  233. if rr.type == "CNAME"
  234. results = results + get_ip(rr.cname)
  235. else
  236. record = {}
  237. record[:host] = host
  238. record[:type] = "AAAA"
  239. record[:address] = rr.address.to_s
  240. results << record
  241. end
  242. end
  243. end
  244. query1 = @res.search(host, "AAAA")
  245. if (query1)
  246. query1.answer.each do |rr|
  247. if rr.type == "CNAME"
  248. results = results + get_ip(rr.cname)
  249. else
  250. record = {}
  251. record[:host] = host
  252. record[:type] = "AAAA"
  253. record[:address] = rr.address.to_s
  254. results << record
  255. end
  256. end
  257. end
  258. return results
  259. end
  260. def switchdns(ns)
  261. vprint_status("Enumerating SRV Records on: #{ns}")
  262. @res.nameserver=(ns)
  263. @nsinuse = ns
  264. end
  265. def get_ns(target)
  266. results = []
  267. query = @res.query(target, "NS")
  268. return results if not query
  269. (query.answer.select { |i| i.class == Net::DNS::RR::NS}).each do |rr|
  270. get_ip(rr.nsdname).each do |r|
  271. record = {}
  272. record[:host] = rr.nsdname.gsub(/\.$/,'')
  273. record[:type] = "NS"
  274. record[:address] = r[:address].to_s
  275. results << record
  276. end
  277. end
  278. return results
  279. end
  280. end