Merge remote branch 'bonsaiviking/axfr' into bonsai-afxr
commit
2edf4a676a
|
@ -995,12 +995,54 @@ module Net # :nodoc:
|
|||
#
|
||||
# Performs a zone transfer for the zone passed as a parameter.
|
||||
#
|
||||
# It is actually only a wrapper to a send with type set as Net::DNS::AXFR,
|
||||
# since it is using the same infrastucture.
|
||||
# Returns a list of Net::DNS::Packet (not answers!)
|
||||
#
|
||||
def axfr(name,cls=Net::DNS::IN)
|
||||
@logger.info "Requested AXFR transfer, zone #{name} class #{cls}"
|
||||
send(name,Net::DNS::AXFR,cls)
|
||||
if @config[:nameservers].size == 0
|
||||
raise Resolver::Error, "No nameservers specified!"
|
||||
end
|
||||
|
||||
method = :send_tcp
|
||||
packet = make_query_packet(name, Net::DNS::AXFR, cls)
|
||||
|
||||
# Store packet_data for performance improvements,
|
||||
# so methods don't keep on calling Packet#data
|
||||
packet_data = packet.data
|
||||
packet_size = packet_data.size
|
||||
|
||||
if @raw
|
||||
@logger.warn "AXFR query, switching to TCP over RAW socket"
|
||||
method = :send_raw_tcp
|
||||
else
|
||||
@logger.warn "AXFR query, switching to TCP"
|
||||
method = :send_tcp
|
||||
end
|
||||
|
||||
answers = []
|
||||
soa = 0
|
||||
self.old_send(method, packet, packet_data) do |ans|
|
||||
@logger.info "Received #{ans[0].size} bytes from #{ans[1][2]+":"+ans[1][1].to_s}"
|
||||
|
||||
begin
|
||||
response = Net::DNS::Packet.parse(ans[0],ans[1])
|
||||
if response.answer[0].type == "SOA"
|
||||
soa += 1
|
||||
if soa >= 2
|
||||
break
|
||||
end
|
||||
end
|
||||
answers << response
|
||||
rescue NameError => e
|
||||
@logger.warn "Error parsing axfr response: #{e.message}"
|
||||
end
|
||||
end
|
||||
if answers.empty?
|
||||
@logger.fatal "No response from nameservers list: aborting"
|
||||
raise NoResponseError
|
||||
end
|
||||
|
||||
return answers
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -1119,38 +1161,56 @@ module Net # :nodoc:
|
|||
|
||||
@config[:nameservers].each do |ns|
|
||||
begin
|
||||
buffer = ""
|
||||
socket = Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)
|
||||
socket.bind(Socket.pack_sockaddr_in(@config[:source_port],@config[:source_address].to_s))
|
||||
|
||||
sockaddr = Socket.pack_sockaddr_in(@config[:port],ns.to_s)
|
||||
|
||||
@config[:tcp_timeout].timeout do
|
||||
socket.connect(sockaddr)
|
||||
@logger.info "Contacting nameserver #{ns} port #{@config[:port]}"
|
||||
socket.write(length+packet_data)
|
||||
ans = socket.recv(Net::DNS::INT16SZ)
|
||||
len = ans.unpack("n")[0]
|
||||
catch "next nameserver" do
|
||||
socket.connect(sockaddr)
|
||||
@logger.info "Contacting nameserver #{ns} port #{@config[:port]}"
|
||||
socket.write(length+packet_data)
|
||||
got_something = false
|
||||
loop do
|
||||
buffer = ""
|
||||
ans = socket.recv(Net::DNS::INT16SZ)
|
||||
if ans.size == 0
|
||||
if got_something
|
||||
break #Proper exit from loop
|
||||
else
|
||||
@logger.warn "Connection reset to nameserver #{ns}, trying next."
|
||||
throw "next nameserver"
|
||||
end
|
||||
end
|
||||
got_something = true
|
||||
len = ans.unpack("n")[0]
|
||||
|
||||
@logger.info "Receiving #{len} bytes..."
|
||||
@logger.info "Receiving #{len} bytes..."
|
||||
|
||||
if len == 0
|
||||
@logger.warn "Receiving 0 lenght packet from nameserver #{ns}, trying next."
|
||||
next
|
||||
end
|
||||
if len == 0
|
||||
@logger.warn "Receiving 0 length packet from nameserver #{ns}, trying next."
|
||||
throw "next nameserver"
|
||||
end
|
||||
|
||||
while (buffer.size < len)
|
||||
left = len - buffer.size
|
||||
temp,from = socket.recvfrom(left)
|
||||
buffer += temp
|
||||
end
|
||||
while (buffer.size < len)
|
||||
left = len - buffer.size
|
||||
temp,from = socket.recvfrom(left)
|
||||
buffer += temp
|
||||
end
|
||||
|
||||
unless buffer.size == len
|
||||
@logger.warn "Malformed packet from nameserver #{ns}, trying next."
|
||||
next
|
||||
unless buffer.size == len
|
||||
@logger.warn "Malformed packet from nameserver #{ns}, trying next."
|
||||
throw "next nameserver"
|
||||
end
|
||||
if block_given?
|
||||
yield [buffer,["",@config[:port],ns.to_s,ns.to_s]]
|
||||
else
|
||||
return [buffer,["",@config[:port],ns.to_s,ns.to_s]]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return [buffer,["",@config[:port],ns.to_s,ns.to_s]]
|
||||
rescue Timeout::Error
|
||||
@logger.warn "Nameserver #{ns} not responding within TCP timeout, trying next one"
|
||||
next
|
||||
|
@ -1158,6 +1218,7 @@ module Net # :nodoc:
|
|||
socket.close
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
def send_udp(packet,packet_data)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
##
|
||||
# $Id$
|
||||
# $Id: enum_dns.rb 15475 2012-06-18 23:39:04Z rapid7 $
|
||||
##
|
||||
|
||||
##
|
||||
|
@ -26,7 +26,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
},
|
||||
'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'Version' => '$Revision$',
|
||||
'Version' => '$Revision: 15475 $',
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '1999-0532'],
|
||||
|
@ -100,7 +100,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
query.answer.each do |rr|
|
||||
next unless rr.class == Net::DNS::RR::A
|
||||
print_status("Domain: #{target} IP address: #{rr.address} Record: A ")
|
||||
report_note(:host => rr.address.to_s,
|
||||
report_note(:host => @nsinuse.to_s,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
|
@ -115,7 +115,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
if (query1)
|
||||
query1.answer.each do |ip|
|
||||
print_status("Start of Authority: #{rr.mname} IP address: #{ip.address} Record: SOA")
|
||||
report_note(:host => ip.address.to_s,
|
||||
report_note(:host => @nsinuse.to_s,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
|
@ -133,7 +133,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
query1.answer.each do |ip|
|
||||
next unless ip.class == Net::DNS::RR::A
|
||||
print_status("Name Server: #{rr.nsdname} IP address: #{ip.address} Record: NS")
|
||||
report_note(:host => ip.address.to_s,
|
||||
report_note(:host => @nsinuse.to_s,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
|
@ -175,6 +175,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
target.chomp!
|
||||
if not nssrv.nil?
|
||||
@res.nameserver=(nssrv)
|
||||
@nsinuse = nssrv
|
||||
end
|
||||
i, a = 0, []
|
||||
tlds = [
|
||||
|
@ -209,7 +210,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
if (query1)
|
||||
query1.answer.each do |rr|
|
||||
print_status("Domain: #{target}.#{tld} Name: #{rr.name} IP address: #{rr.address} Record: A ") if rr.class == Net::DNS::RR::A
|
||||
report_note(:host => rr.address.to_s,
|
||||
report_note(:host => @nsinuse.to_s,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53,
|
||||
|
@ -229,13 +230,14 @@ class Metasploit3 < Msf::Auxiliary
|
|||
::File.open(wordlist, "rb").each_line do |line|
|
||||
if not nssrv.nil?
|
||||
@res.nameserver=(nssrv)
|
||||
@nsinuse = nssrv
|
||||
end
|
||||
query1 = @res.search("#{line.chomp}.#{target}")
|
||||
if (query1)
|
||||
query1.answer.each do |rr|
|
||||
if rr.class == Net::DNS::RR::A
|
||||
print_status("Hostname: #{line.chomp}.#{target} IP address: #{rr.address.to_s}")
|
||||
report_note(:host => rr.address.to_s,
|
||||
report_note(:host => @nsinuse.to_s,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
|
@ -256,6 +258,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
arr = IO.readlines(wordlist)
|
||||
if not nssrv.nil?
|
||||
@res.nameserver=(nssrv)
|
||||
@nsinuse = nssrv
|
||||
end
|
||||
arr.each do |line|
|
||||
query1 = @res.search("#{line.chomp}.#{target}", "AAAA")
|
||||
|
@ -263,7 +266,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
query1.answer.each do |rr|
|
||||
if rr.class == Net::DNS::RR::AAAA
|
||||
print_status("Hostname: #{line.chomp}.#{target} IPv6 Address: #{rr.address.to_s}")
|
||||
report_note(:host => rr.address.to_s,
|
||||
report_note(:host => @nsinuse.to_s,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
|
@ -284,6 +287,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
print_status("Running reverse lookup against IP range #{iprange}")
|
||||
if not nssrv.nil?
|
||||
@res.nameserver = (nssrv)
|
||||
@nsinuse = nssrv
|
||||
end
|
||||
ar = Rex::Socket::RangeWalker.new(iprange)
|
||||
tl = []
|
||||
|
@ -297,7 +301,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
query = @res.query(tip)
|
||||
query.each_ptr do |addresstp|
|
||||
print_status("Hostname: #{addresstp} IP address: #{tip.to_s}")
|
||||
report_note(:host => tip,
|
||||
report_note(:host => @nsinuse.to_s,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
|
@ -354,6 +358,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
print_status("Performing zone transfer against all nameservers in #{target}")
|
||||
if not nssrv.nil?
|
||||
@res.nameserver=(nssrv)
|
||||
@nsinuse = nssrv
|
||||
end
|
||||
@res.tcp_timeout=15
|
||||
query = @res.query(target, "NS")
|
||||
|
@ -361,96 +366,105 @@ class Metasploit3 < Msf::Auxiliary
|
|||
(query.answer.select { |i| i.class == Net::DNS::RR::NS}).each do |nsrcd|
|
||||
print_status("Testing nameserver: #{nsrcd.nsdname}")
|
||||
nssrvquery = @res.query(nsrcd.nsdname, "A")
|
||||
begin
|
||||
if nssrvquery.answer.length == 0
|
||||
nssrvip = Rex::Socket.gethostbyname(nsrcd.nsdname)[3].bytes.reduce {|a,b| [a,b].join(".")}
|
||||
else
|
||||
nssrvip = nssrvquery.answer[0].address.to_s
|
||||
end
|
||||
begin
|
||||
@res.nameserver=(nssrvip)
|
||||
@nsinuse = nssrvip
|
||||
zone = []
|
||||
zone = @res.query(target,Net::DNS::AXFR)
|
||||
if zone.answer.length != 0
|
||||
namesrvips = @res.query(nsrcd.nsdname,"A")
|
||||
nsip = namesrvips.answer[0]
|
||||
zone = @res.axfr(target)
|
||||
if zone.length != 0
|
||||
print_status("Zone transfer successful")
|
||||
report_note(:host => nsip.address.to_s,
|
||||
report_note(:host => nssrvip,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "Zone transfer successful")
|
||||
#Prints each record according to its type
|
||||
zone.answer.each do |rr|
|
||||
case rr.type
|
||||
when "A"
|
||||
print_status("Name: #{rr.name} IP address: #{rr.address} Record: A ")
|
||||
report_note(:host => rr.address.to_s,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "#{rr.address.to_s},#{rr.name},A")
|
||||
when "SOA"
|
||||
print_status("Name: #{rr.mname} Record: SOA")
|
||||
report_note(:host => nsip.address.to_s,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "#{rr.name},SOA")
|
||||
when "MX"
|
||||
print_status("Name: #{rr.exchange} Preference: #{rr.preference} Record: MX")
|
||||
report_note(:host => nsip.address.to_s,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "#{rr.exchange},MX")
|
||||
when "CNAME"
|
||||
print_status("Name: #{rr.cname} Record: CNAME")
|
||||
report_note(:host => nsip.address.to_s,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "#{rr.cname},CNAME")
|
||||
when "HINFO"
|
||||
print_status("CPU: #{rr.cpu} OS: #{rr.os} Record: HINFO")
|
||||
report_note(:host => nsip.address.to_s,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "CPU:#{rr.cpu},OS:#{rr.os},HINFO")
|
||||
when "AAAA"
|
||||
print_status("IPv6 Address: #{rr.address} Record: AAAA")
|
||||
report_note(:host => rr.address.to_s,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "#{rr.address.to_s}, AAAA")
|
||||
when "NS"
|
||||
print_status("Name: #{rr.nsdname} Record: NS")
|
||||
report_note(:host => nsip.address.to_s,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "#{rr.nsdname},NS")
|
||||
when "TXT"
|
||||
print_status("Text: #{rr.inspect}")
|
||||
report_note(:host => nsip.address.to_s,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => rr.inspect)
|
||||
when "SRV"
|
||||
print_status("Host: #{rr.host} Port: #{rr.port} Priority: #{rr.priority} Record: SRV")
|
||||
report_note(:host => nsip.address.to_s,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "#{rr.host},#{rr.port},#{rr.priority},SRV")
|
||||
zone.each do |response|
|
||||
response.answer.each do |rr|
|
||||
begin
|
||||
case rr.type
|
||||
when "A"
|
||||
print_status("Name: #{rr.name} IP address: #{rr.address} Record: A ")
|
||||
report_note(:host => nssrvip,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "#{rr.address.to_s},#{rr.name},A")
|
||||
when "SOA"
|
||||
print_status("Name: #{rr.mname} Record: SOA")
|
||||
report_note(:host => nssrvip,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "#{rr.name},SOA")
|
||||
when "MX"
|
||||
print_status("Name: #{rr.exchange} Preference: #{rr.preference} Record: MX")
|
||||
report_note(:host => nssrvip,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "#{rr.exchange},MX")
|
||||
when "CNAME"
|
||||
print_status("Name: #{rr.cname} Record: CNAME")
|
||||
report_note(:host => nssrvip,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "#{rr.cname},CNAME")
|
||||
when "HINFO"
|
||||
print_status("CPU: #{rr.cpu} OS: #{rr.os} Record: HINFO")
|
||||
report_note(:host => nssrvip,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "CPU:#{rr.cpu},OS:#{rr.os},HINFO")
|
||||
when "AAAA"
|
||||
print_status("IPv6 Address: #{rr.address} Record: AAAA")
|
||||
report_note(:host => nssrvip,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "#{rr.address.to_s}, AAAA")
|
||||
when "NS"
|
||||
print_status("Name: #{rr.nsdname} Record: NS")
|
||||
report_note(:host => nssrvip,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "#{rr.nsdname},NS")
|
||||
when "TXT"
|
||||
print_status("Text: #{rr.inspect}")
|
||||
report_note(:host => nssrvip,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => rr.inspect)
|
||||
when "SRV"
|
||||
print_status("Host: #{rr.host} Port: #{rr.port} Priority: #{rr.priority} Record: SRV")
|
||||
report_note(:host => nssrvip,
|
||||
:proto => 'udp',
|
||||
:sname => 'dns',
|
||||
:port => 53 ,
|
||||
:type => 'dns.enum',
|
||||
:data => "#{rr.host},#{rr.port},#{rr.priority},SRV")
|
||||
end
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
#Do nothing. Probably tried to store :host => 127.0.0.1
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue