From 9b3dfacce182200a6dc4d620d6b11caf907422fe Mon Sep 17 00:00:00 2001 From: soh_cah_toa Date: Fri, 25 Apr 2014 13:06:33 -0400 Subject: [PATCH] Added support for upstream nameservers. Previously, upstream nameservers were configured by default even if the config file did not specify them. Now upstream nameservers are only used if they are specified. If none are given, then NXDOMAIN is returned for unresolvable requests. --- extensions/dns/api.rb | 33 ++++++++++----------------------- extensions/dns/config.yaml | 4 ++-- extensions/dns/dns.rb | 24 ++++++++++++++++++++++-- 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/extensions/dns/api.rb b/extensions/dns/api.rb index cbac81b6c..ca0accd45 100644 --- a/extensions/dns/api.rb +++ b/extensions/dns/api.rb @@ -34,38 +34,25 @@ module BeEF port = dns_config['port'] || 5300 interfaces = [[protocol, address, port]] - Thread.new { EventMachine.next_tick { dns.run(:listen => interfaces) } } - - print_info "DNS Server: #{address}:#{port} (#{protocol})" - - # @todo Upstream servers are not yet supported. Uncomment this section when they are. -=begin servers = [] + upstream_servers = '' - unless dns_config['upstream'].nil? + unless dns_config['upstream'].nil? || dns_config['upstream'].empty? dns_config['upstream'].each do |server| - next if server[1].nil? or server[2].nil? + up_protocol = server[0].downcase + up_address = server[1] + up_port = server[2] - if server[0] == 'tcp' - servers << ['tcp', server[1], server[2]] - elsif server[0] == 'udp' - servers << ['udp', server[1], server[2]] - end + next if [up_protocol, up_address, up_port].include?(nil) + servers << [up_protocol.to_sym, up_address, up_port] if up_protocol =~ /^(tcp|udp)$/ + upstream_servers << "Upstream Server: #{up_address}:#{up_port} (#{up_port})\n" end end - if servers.empty? - servers << ['tcp', '8.8.8.8', 53] - servers << ['udp', '8.8.8.8', 53] - end - - upstream_servers = '' - servers.each do |server| - upstream_servers << "Upstream Server: #{server[1]}:#{server[2]} (#{server[0]})\n" - end + Thread.new { EventMachine.next_tick { dns.run(:upstream => servers, :listen => interfaces) } } + print_info "DNS Server: #{address}:#{port} (#{protocol})" print_more upstream_servers -=end end # Mounts the handler for processing DNS RESTful API requests. diff --git a/extensions/dns/config.yaml b/extensions/dns/config.yaml index 3733af7ea..5a525a2e3 100644 --- a/extensions/dns/config.yaml +++ b/extensions/dns/config.yaml @@ -13,6 +13,6 @@ beef: address: '127.0.0.1' port: 5300 upstream: [ - ['tcp', '8.8.8.8', 53], - ['udp', '8.8.8.8', 53] + ['udp', '8.8.8.8', 53], + ['tcp', '8.8.8.8', 53] ] diff --git a/extensions/dns/dns.rb b/extensions/dns/dns.rb index 2c7467aaa..e01271cdd 100644 --- a/extensions/dns/dns.rb +++ b/extensions/dns/dns.rb @@ -105,6 +105,26 @@ module BeEF @lock.synchronize { @database.destroy } end + # Starts the DNS server. + # + # @param options [Hash] server configuration options + # @option options [Array] :upstream upstream DNS servers (if ommitted, unresolvable + # requests return NXDOMAIN) + # @option options [Array] :listen local interfaces to listen on + def run(options = {}) + @lock.synchronize do + upstream = options[:upstream] + listen = options[:listen] + + unless upstream.nil? || upstream.empty? + resolver = RubyDNS::Resolver.new(upstream) + @otherwise = Proc.new { |t| t.passthrough!(resolver) } + end + + super(:listen => listen) + end + end + # Entry point for processing incoming DNS requests. Attempts to find a matching rule and # sends back its associated response. # @@ -131,12 +151,12 @@ module BeEF end end - # When no match is found, query upstream servers (if enabled) if @otherwise print_debug "No match found, querying upstream servers" @otherwise.call(transaction) else - print_debug "Failed to handle DNS request for #{name}" + print_debug "No match found, sending NXDOMAIN response" + transaction.fail!(:NXDomain) end end end