Module: Msf::Exploit::Remote::DNS::Client
- Included in:
- Enumeration
- Defined in:
- lib/msf/core/exploit/remote/dns/client.rb
Constant Summary
Constants included from Common
Msf::Exploit::Remote::DNS::Common::MATCH_HOSTNAME, Msf::Exploit::Remote::DNS::Common::Packet
Instance Attribute Summary
Attributes included from Tcp
Attributes included from Udp
Instance Method Summary collapse
-
#client ⇒ Object
Convenience method for DNS resolver as client Executes setup_resolver if none exists.
-
#initialize(info = {}) ⇒ Object
Initializes an exploit module that interacts with a DNS server.
-
#process_nameservers ⇒ Object
Sets the resolver’s nameservers Uses explicitly defined NS option if set Uses RHOSTS if not explicitly defined.
-
#query(domain = , type = 'A') ⇒ Dnsruby::RR
Convenience wrapper around Resolver’s query method - send DNS request.
-
#query_async(queries = [], threadmax = , &block) ⇒ Array
Performs a set of asynchronous lookups for an array of domain,type pairs.
-
#set_nameserver(ns = []) ⇒ Object
Switch DNS forwarders in resolver with thread safety.
-
#setup_resolver ⇒ Object
Create and configure Resolver object.
-
#switchdns(domain) ⇒ Object
Switch nameservers to use explicit NS or SOA for target.
-
#wildcard(domain, type = "A") ⇒ String
Detect if target has wildcards enabled for a record type.
Methods included from Tcp
#chost, #cleanup, #connect, #connect_timeout, #cport, #disconnect, #handler, #lhost, #lport, #peer, #print_prefix, #proxies, #rhost, #rport, #set_tcp_evasions, #shutdown, #ssl, #ssl_cipher, #ssl_verify_mode, #ssl_version
Methods included from Udp
#chost, #cleanup, #connect_udp, #cport, #deregister_udp_options, #disconnect_udp, #handler, #lhost, #lport, #rhost, #rport
Instance Method Details
#client ⇒ Object
Convenience method for DNS resolver as client Executes setup_resolver if none exists
189 190 191 192 |
# File 'lib/msf/core/exploit/remote/dns/client.rb', line 189 def client setup_resolver unless @dns_resolver @dns_resolver end |
#initialize(info = {}) ⇒ Object
Initializes an exploit module that interacts with a DNS server.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/msf/core/exploit/remote/dns/client.rb', line 21 def initialize(info = {}) super ('RHOST') ( [ Opt::RPORT(53), Opt::Proxies, OptString.new('DOMAIN', [ false, "The target domain name"]), OptString.new('NS', [ false, "Specify the nameservers to use for queries, space separated" ]), OptString.new('SEARCHLIST', [ false, "DNS domain search list, comma separated"]), OptInt.new('THREADS', [true, "Number of threads to use in threaded queries", 1]) ], Exploit::Remote::DNS::Client ) ( [ OptString.new('DnsClientDefaultNS', [ false, "Specify the default to use for queries, space separated", '8.8.8.8 8.8.4.4' ]), OptInt.new('DnsClientRetry', [ false, "Number of times to try to resolve a record if no response is received", 2]), OptInt.new('DnsClientRetryInterval', [ false, "Number of seconds to wait before doing a retry", 2]), OptBool.new('DnsClientReportARecords', [false, "Add hosts found via BRT and RVL to DB", true]), OptBool.new('DnsClientRVLExistingOnly', [false, "Only perform lookups on hosts in DB", true]), OptBool.new('DnsClientTcpDns', [false, "Run queries over TCP", false]), OptPath.new('DnsClientResolvconf', [true, "Resolvconf formatted configuration file to use for Resolver", "/dev/null"]) ], Exploit::Remote::DNS::Client ) register_autofilter_ports([ 53 ]) if respond_to?(:register_autofilter_ports) register_autofilter_services(%W{ dns }) if respond_to?(:register_autofilter_services) end |
#process_nameservers ⇒ Object
Sets the resolver’s nameservers Uses explicitly defined NS option if set Uses RHOSTS if not explicitly defined
198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/msf/core/exploit/remote/dns/client.rb', line 198 def process_nameservers if datastore['NS'].blank? nameservers = datastore['DnsClientDefaultNS'].split(/\s|,/) else nameservers = datastore['NS'].split(/\s|,/) end invalid = nameservers.select { |ns| !Rex::Socket.dotted_ip?(ns) } if !invalid.empty? raise "Nameservers must be IP addresses. The following were invalid: #{invalid.join(", ")}" end nameservers end |
#query(domain = , type = 'A') ⇒ Dnsruby::RR
Convenience wrapper around Resolver’s query method - send DNS request
60 61 62 |
# File 'lib/msf/core/exploit/remote/dns/client.rb', line 60 def query(domain = datastore['DOMAIN'], type = 'A') client.query(domain, type) end |
#query_async(queries = [], threadmax = , &block) ⇒ Array
Performs a set of asynchronous lookups for an array of domain,type pairs
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/msf/core/exploit/remote/dns/client.rb', line 72 def query_async(queries = [], threadmax = datastore['THREADS'], &block) running = [] while !queries.empty? domain, type = queries.shift running << framework.threads.spawn("Module(#{self.refname})-#{domain} #{type}", false) do |qat| if block block.call(query(domain,type)) else query(domain,type) end end while running.select(&:alive?).count >= threadmax Rex::ThreadSafe.sleep(1) end end return running.join end |
#set_nameserver(ns = []) ⇒ Object
Switch DNS forwarders in resolver with thread safety
94 95 96 97 98 99 100 101 |
# File 'lib/msf/core/exploit/remote/dns/client.rb', line 94 def set_nameserver(ns = []) if ns.respond_to?(:split) ns = [ns] end @lock.synchronize do @dns_resolver.nameserver = ns.flatten end end |
#setup_resolver ⇒ Object
Create and configure Resolver object
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/msf/core/exploit/remote/dns/client.rb', line 150 def setup_resolver .validate(datastore) # This is a hack, DS values should not be Strings prior to this config = { :config_file => datastore['DnsClientResolvconf'], :nameservers => process_nameservers, :port => datastore['RPORT'], :retry_number => datastore['DnsClientRetry'].to_i, :retry_interval => datastore['DnsClientRetryInterval'].to_i, :use_tcp => datastore['DnsClientTcpDns'], :context => {'Msf' => framework, 'MsfExploit' => self} } if datastore['SEARCHLIST'] if datastore['SEARCHLIST'].split(',').all? do |search| search.match(MATCH_HOSTNAME) end config[:search_list] = datastore['SEARCHLIST'].split(',') else raise 'Domain search list must consist of valid domains' end end if datastore['CHOST'] config[:source_address] = IPAddr.new(datastore['CHOST'].to_s) end if datastore['CPORT'] config[:source_port] = datastore['CPORT'] unless datastore['CPORT'] == 0 end if datastore['Proxies'] vprint_status("Using DNS/TCP resolution for proxy config") config[:use_tcp] = true config[:proxies] = datastore['Proxies'] end @dns_resolver_lock = Mutex.new unless @dns_resolver_lock @dns_resolver = Rex::Proto::DNS::Resolver.new(config) end |
#switchdns(domain) ⇒ Object
Switch nameservers to use explicit NS or SOA for target
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/msf/core/exploit/remote/dns/client.rb', line 107 def switchdns(domain) if datastore['NS'].blank? resp_soa = client.query(target, "SOA") if (resp_soa) (resp_soa.answer.select { |i| i.is_a?(Dnsruby::RR::SOA)}).each do |rr| resp_1_soa = client.search(rr.mname) if (resp_1_soa and resp_1_soa.answer[0]) set_nameserver(resp_1_soa.answer.map(&:address).compact.map(&:to_s)) print_status("Set DNS Server to #{target} NS: #{client.nameserver.join(', ')}") break end end end else vprint_status("Using DNS Server: #{client.nameserver.join(', ')}") client.nameserver = process_nameservers end end |
#wildcard(domain, type = "A") ⇒ String
Detect if target has wildcards enabled for a record type
133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/msf/core/exploit/remote/dns/client.rb', line 133 def wildcard(domain, type = "A") addr = false rendsub = rand(10000).to_s response = query("#{rendsub}.#{target}", type) if response.answer.length != 0 vprint_status("This domain has wildcards enabled!!") response.answer.each do |rr| print_status("Wildcard IP for #{rendsub}.#{target} is: #{rr.address.to_s}") if rr.class != Dnsruby::RR::CNAME addr = rr.address.to_s end end return addr end |