From c7eb1c7fc91f62c9df56f371c81acdc4eb56e320 Mon Sep 17 00:00:00 2001 From: soh_cah_toa Date: Wed, 8 May 2013 00:03:08 -0400 Subject: [PATCH] Added DNS database model to load resource records from. Now modules/extensions can dynamically add new RR's. However, changes don't take effect until BeEF restarts (fix incoming). --- extensions/dns/dns.rb | 37 ++++++++++++++++++++++++++++++++-- extensions/dns/extension.rb | 1 + extensions/dns/model.rb | 24 ++++++++++++++++++++++ extensions/dns/ruby/rubydns.rb | 8 ++++++-- 4 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 extensions/dns/model.rb diff --git a/extensions/dns/dns.rb b/extensions/dns/dns.rb index 78b2983f2..aa665cc53 100644 --- a/extensions/dns/dns.rb +++ b/extensions/dns/dns.rb @@ -11,13 +11,21 @@ module DNS include Singleton - #UPSTREAM = RubyDNS::Resolver.new([[:udp, '8.8.8.8', 53], [:tcp, '8.8.8.8', 53]]) - def run_server(address, port) EventMachine::next_tick do RubyDNS::run_server(:listen => [[:udp, address, port]]) do upstream = RubyDNS::Resolver.new([[:udp, '8.8.8.8', 53], [:tcp, '8.8.8.8', 53]]) + BeEF::Core::Models::DNS.each do |record| + name = record.name + type = BeEF::Extension::DNS::DNS.parse_type(record.type) + value = record.value + + match(name, type) do |transaction| + transaction.respond!(value) + end + end + otherwise do |transaction| transaction.passthrough!(upstream) end @@ -25,6 +33,31 @@ module DNS end end + def add_rule(name, type, value) + d = BeEF::Core::Models::DNS.new( + :name => name, + :type => type, + :value => value + ).save + + type = BeEF::Extension::DNS::DNS.parse_type(type) + + RubyDNS::stop_server + run_server + end + + # XXX Why must this be a class method? As a private instance method, + # it throws NoMethodError. + def self.parse_type(type) + resolv = 'Resolv::DNS::Resource' + + if type =~ /(A|AAAA|SRV|WKS)/ + resolv += '::IN' + end + + eval "#{resolv}::#{type}" + end + end end diff --git a/extensions/dns/extension.rb b/extensions/dns/extension.rb index 6b1375d2f..59f56543d 100644 --- a/extensions/dns/extension.rb +++ b/extensions/dns/extension.rb @@ -21,3 +21,4 @@ end require 'extensions/dns/api' require 'extensions/dns/dns' require 'extensions/dns/ruby' +require 'extensions/dns/model' diff --git a/extensions/dns/model.rb b/extensions/dns/model.rb new file mode 100644 index 000000000..4c171e483 --- /dev/null +++ b/extensions/dns/model.rb @@ -0,0 +1,24 @@ +# +# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +module BeEF +module Core +module Models + + class DNS + + include DataMapper::Resource + + property :name, String + property :type, String + property :value, String + + property :id, Serial, :key => true + + end + +end +end +end diff --git a/extensions/dns/ruby/rubydns.rb b/extensions/dns/ruby/rubydns.rb index bbf2a3669..112316667 100644 --- a/extensions/dns/ruby/rubydns.rb +++ b/extensions/dns/ruby/rubydns.rb @@ -16,9 +16,9 @@ module RubyDNS options[:listen].each do |spec| if spec[0] == :udp - EventMachine.open_datagram_socket(spec[1], spec[2], UDPHandler, server) + @signature = EventMachine.open_datagram_socket(spec[1], spec[2], UDPHandler, server) elsif spec[0] == :tcp - EventMachine.start_server(spec[1], spec[2], TCPHandler, server) + @signature = EventMachine.start_server(spec[1], spec[2], TCPHandler, server) end end @@ -28,6 +28,10 @@ module RubyDNS server.fire(:stop) end + def self.stop_server + EventMachine.stop_server(@signature) + end + class Transaction # Behaves exactly the same, except using debug logger instead of info