Files
beef/extensions/dns/rest/dns.rb
soh_cah_toa 1d5afbb81e Added Dns::Server attribute to DNS REST router.
This is primarily intended to add clarity by reducing clutter. Moreover,
it also has the side effect of improving performance very slightly by
removing the overhead of calling #instance numerous times.
2014-04-25 10:14:05 -04:00

153 lines
4.7 KiB
Ruby

#
# Copyright (c) 2006-2014 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
module BeEF
module Extension
module Dns
# This class handles the routing of RESTful API requests that query BeEF's DNS server
class DnsRest < BeEF::Core::Router::Router
# Filters out bad requests before performing any routing
before do
@dns ||= BeEF::Extension::Dns::Server.instance
config = BeEF::Core::Configuration.instance
# Require a valid API token from a valid IP address
halt 401 unless params[:token] == config.get('beef.api_token')
halt 403 unless BeEF::Core::Rest.permitted_source?(request.ip)
headers 'Content-Type' => 'application/json; charset=UTF-8',
'Pragma' => 'no-cache',
'Cache-Control' => 'no-cache',
'Expires' => '0'
end
# Returns the entire current DNS ruleset
get '/ruleset' do
begin
ruleset = @dns.get_ruleset
count = ruleset.length
result = {}
result[:count] = count
result[:ruleset] = ruleset
result.to_json
rescue StandardError => e
print_error "Internal error while retrieving DNS ruleset (#{e.message})"
halt 500
end
end
# Returns a specific rule given its id
get '/rule/:id' do
begin
id = params[:id]
rule = @dns.get_rule(id)
raise InvalidParamError, 'id' if rule.nil?
halt 404 if rule.empty?
rule.to_json
rescue InvalidParamError => e
print_error e.message
halt 400
rescue StandardError => e
print_error "Internal error while retrieving DNS rule with id #{id} (#{e.message})"
halt 500
end
end
# Adds a new DNS rule
post '/rule' do
begin
body = JSON.parse(request.body.read)
pattern = body['pattern']
resource = body['resource']
response = body['response']
valid_resources = ["A", "AAAA", "CNAME", "HINFO", "MINFO", "MX", "NS", "PTR", "SOA", "TXT", "WKS"]
# Validate required JSON keys
unless [pattern, resource, response].include?(nil)
if response.is_a?(Array)
raise InvalidJsonError, 'Empty "response" key passed to endpoint /api/dns/rule' if response.empty?
else
raise InvalidJsonError, 'Non-array "response" key passed to endpoint /api/dns/rule'
end
raise InvalidJsonError, 'Wrong "resource" key passed to endpoint /api/dns/rule' unless valid_resources.include?(resource)
id = @dns.add_rule(
:pattern => pattern,
:resource => eval("Resolv::DNS::Resource::IN::#{resource}"),
:response => response
)
result = {}
result['success'] = true
result['id'] = id
result.to_json
end
rescue InvalidJsonError => e
print_error e.message
halt 400
rescue StandardError => e
print_error "Internal error while adding DNS rule (#{e.message})"
halt 500
end
end
# Removes a rule given its id
delete '/rule/:id' do
begin
id = params[:id]
removed = @dns.remove_rule!(id)
raise InvalidParamError, 'id' if removed.nil?
result = {}
result['success'] = removed
result.to_json
rescue InvalidParamError => e
print_error e.message
halt 400
rescue StandardError => e
print_error "Internal error while removing DNS rule with id #{id} (#{e.message})"
halt 500
end
end
# Raised when invalid JSON input is passed to an /api/dns handler.
class InvalidJsonError < StandardError
DEFAULT_MESSAGE = 'Invalid JSON input passed to /api/dns handler'
def initialize(message = nil)
super(message || DEFAULT_MESSAGE)
end
end
# Raised when an invalid named parameter is passed to an /api/dns handler.
class InvalidParamError < StandardError
DEFAULT_MESSAGE = 'Invalid parameter passed to /api/dns handler'
def initialize(message = nil)
str = "Invalid \"%s\" parameter passed to /api/dns handler"
message = sprintf str, message unless message.nil?
super(message)
end
end
end
end
end
end