Lucene search
+L

Multi Gather DNS Service Record Lookup Scan

🗓️ 18 Oct 2011 23:34:00Reported by Carlos Perez <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 33 Views

Enumerates known SRV Records for a given domain using the target host DNS query tool

Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Post
  include Msf::Auxiliary::Report

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Multi Gather DNS Service Record Lookup Scan',
        'Description' => %q{
          Enumerates known SRV Records for a given domain using target host DNS query tool.
        },
        'License' => MSF_LICENSE,
        'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>'],
        'Platform' => %w[bsd linux osx solaris win],
        'SessionTypes' => [ 'meterpreter', 'shell' ]
      )
    )
    register_options(
      [

        OptString.new('DOMAIN', [true, 'Domain to perform SRV query against.'])

      ]
    )
  end

  # Run Method for when run command is issued
  def run
    srvrcd = [
      '_gc._tcp.', '_kerberos._tcp.', '_kerberos._udp.', '_ldap._tcp.',
      '_test._tcp.', '_sips._tcp.', '_sip._udp.', '_sip._tcp.', '_aix._tcp.',
      '_aix._tcp.', '_finger._tcp.', '_ftp._tcp.', '_http._tcp.', '_nntp._tcp.',
      '_telnet._tcp.', '_whois._tcp.', '_h323cs._tcp.', '_h323cs._udp.',
      '_h323be._tcp.', '_h323be._udp.', '_h323ls._tcp.',
      '_h323ls._udp.', '_sipinternal._tcp.', '_sipinternaltls._tcp.',
      '_sip._tls.', '_sipfederationtls._tcp.', '_jabber._tcp.',
      '_xmpp-server._tcp.', '_xmpp-client._tcp.', '_imap.tcp.',
      '_certificates._tcp.', '_crls._tcp.', '_pgpkeys._tcp.',
      '_pgprevokations._tcp.', '_cmp._tcp.', '_svcp._tcp.', '_crl._tcp.',
      '_ocsp._tcp.', '_PKIXREP._tcp.', '_smtp._tcp.', '_hkp._tcp.',
      '_hkps._tcp.', '_jabber._udp.', '_xmpp-server._udp.', '_xmpp-client._udp.',
      '_jabber-client._tcp.', '_jabber-client._udp.', '_kerberos.tcp.dc._msdcs.',
      '_ldap._tcp.ForestDNSZones.', '_ldap._tcp.dc._msdcs.', '_ldap._tcp.pdc._msdcs.',
      '_ldap._tcp.gc._msdcs.', '_kerberos._tcp.dc._msdcs.', '_kpasswd._tcp.', '_kpasswd._udp.',
      '_imap._tcp.'
    ]

    domain = datastore['DOMAIN']

    print_status("Performing DNS SRV Record Lookup for Domain #{domain}")

    a = []

    case session.platform
    when 'windows'
      ns_opt = ' -query=srv '
      cmd = 'nslookup'
    when 'solaris'
      ns_opt = ' -t srv '
      cmd = '/usr/sbin/host'
    else
      ns_opt = ' -t srv '
      cmd = '/usr/bin/host'
    end

    while !srvrcd.nil? && !srvrcd.empty?
      1.upto session.max_threads do
        a << framework.threads.spawn("Module(#{refname})", false, srvrcd.shift) do |srv|
          next if srv.nil?

          r = cmd_exec(cmd, ns_opt + "#{srv}#{domain}")

          case session.platform
          when 'windows'
            if r =~ /\s*internet\saddress\s=\s/
              nslookup_srv_consume("#{srv}#{domain}", r).each do |f|
                print_good("\t#{f[:srv]} #{f[:target]} #{f[:port]} #{f[:ip]}")
              end
            end
          else
            found = host_srv_consume(r)
            if found
              found.each do |f|
                print_good("\t#{f[:srv]} #{f[:target]} #{f[:port]} #{f[:ip]}")
              end
            end
          end
        end
        a.map(&:join)
      end
    end
  end

  def nslookup_srv_consume(srv, ns_out)
    srv_records = []
    records = ns_out.split(srv)

    # Get host to IP mapping
    ip_map = {}
    records.last.each_line do |e|
      if e =~ /internet\saddress/i
        host, ip = e.split(/\s*internet\saddress\s=\s/)
        ip_map[host.strip] = ip.strip
      end
    end

    # Get SRV parameter for each record
    records.each do |r|
      next unless r =~ /svr hostname/

      rcrd = {}
      rcrd[:srv] = srv
      rcrd[:port] = r.scan(/port\s*=\s(\d*)/).join
      rcrd[:target] = r.scan(/svr hostname\s*=\s(\S*)/).join
      if !Rex::Socket.dotted_ip?(rcrd[:target])
        w_get_ip(rcrd[:target]).each do |i|
          rcrd[:ip] = i
          report_host(host: rcrd[:ip].strip, name: rcrd[:target])

          # Report on the service found
          srv_info = rcrd[:srv].scan(/^_(\S*)\._(\w*)\./)[0]

          report_service(host: rcrd[:ip].strip,
                         port: rcrd[:port].to_i,
                         proto: srv_info[1],
                         name: srv_info[0],
                         host_name: rcrd[:target])
          srv_records << rcrd
        end
      else

        rcrd[:ip] = ip_map[rcrd[:target]]
        # Report hosts found
        report_host(host: rcrd[:ip].strip, name: rcrd[:target])

        # Report on the service found
        srv_info = rcrd[:srv].scan(/^_(\S*)\._(\w*)\./)[0]

        report_service(host: '1.2.3.4',
                       port: rcrd[:port].to_i,
                       proto: srv_info[1],
                       name: srv_info[0],
                       host_name: rcrd[:target])
        srv_records << rcrd
      end
    end
    return srv_records
  end

  # Get I{ for a given host using host, returns array
  def get_ip(host)
    ip_add = []
    cmd_exec('host', " #{host}").each_line do |l|
      ip = ''
      ip = l.scan(/has address (\S*)$/).join
      ip_add << ip if ip != ''
    end
    return ip_add
  end

  # Get IP for given host with nslookup, return array
  def w_get_ip(host)
    ips = []
    data = cmd_exec("nslookup #{host}")
    if data =~ /Name/
      # Remove unnecessary data and get the section with the addresses
      returned_data = data.split(/Name:/)[1]
      # check each element of the array to see if they are IP
      returned_data.gsub(/\r\n\t |\r\n|Aliases:|Addresses:|Address:/, ' ').split(' ').each do |e|
        if Rex::Socket.dotted_ip?(e)
          ips << e
        end
      end
    end
    return ips
  end

  def host_srv_consume(host_out)
    srv_records = []
    # Parse for SRV Records
    host_out.each_line do |l|
      next unless l =~ /has SRV/

      record, port, target = l.scan(/(\S*) has SRV record \d*\s\d*\s(\d*)\s(\S*)/)[0]
      if Rex::Socket.dotted_ip?(target)
        rcrd = {}
        rcrd[:srv] = record
        rcrd[:port] = port
        rcrd[:target] = target
        rcrd[:ip] = target
        srv_records << rcrd

        # Report hosts found
        report_host(host: rcrd[:ip], name: rcrd[:target])

        # Report on the service found
        srv_info = rcrd[:srv].scan(/^_(\S*)\._(\w*)\./)[0]
        report_service(host: rcrd[:ip],
                       port: rcrd[:port],
                       proto: srv_info[1],
                       name: srv_info[0],
                       host_name: rcrd[:target])
      else
        get_ip(target).each do |i|
          rcrd = {}
          rcrd[:srv] = record
          rcrd[:port] = port
          rcrd[:target] = target
          rcrd[:ip] = i
          srv_records << rcrd

          # Report hosts found
          report_host(host: rcrd[:ip], name: rcrd[:target])

          # Report on the service found
          srv_info = rcrd[:srv].scan(/^_(\S*)\._(\w*)\./)[0]
          report_service(host: rcrd[:ip],
                         port: rcrd[:port].to_i,
                         proto: srv_info[1],
                         name: srv_info[0],
                         host_name: rcrd[:target])
        end
      end
    end
    return srv_records
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation