From 44e9871503c36f74d51c83e243f20362d3cbb668 Mon Sep 17 00:00:00 2001 From: Christian Frichot Date: Sun, 15 Apr 2012 07:24:17 +0800 Subject: [PATCH 01/14] RESTful API now obeys permitted_ui_subnet --- core/bootstrap.rb | 1 + core/main/rest/api.rb | 20 ++++++++++++++++++++ core/main/rest/handlers/hookedbrowsers.rb | 1 + core/main/rest/handlers/logs.rb | 1 + core/main/rest/handlers/modules.rb | 1 + 5 files changed, 24 insertions(+) diff --git a/core/bootstrap.rb b/core/bootstrap.rb index 148136e79..290b4a554 100644 --- a/core/bootstrap.rb +++ b/core/bootstrap.rb @@ -50,4 +50,5 @@ require 'core/hbmanager' require 'core/main/rest/handlers/hookedbrowsers' require 'core/main/rest/handlers/modules' require 'core/main/rest/handlers/logs' +require 'core/main/rest/handlers/admin' require 'core/main/rest/api' diff --git a/core/main/rest/api.rb b/core/main/rest/api.rb index c6bfafa59..0f8ce0b7c 100644 --- a/core/main/rest/api.rb +++ b/core/main/rest/api.rb @@ -35,9 +35,29 @@ module BeEF end end + module RegisterAdminHandler + def self.mount_handler(server) + server.mount('/api/admin', BeEF::Core::Rest::Admin.new) + end + end + BeEF::API::Registrar.instance.register(BeEF::Core::Rest::RegisterHooksHandler, BeEF::API::Server, 'mount_handler') BeEF::API::Registrar.instance.register(BeEF::Core::Rest::RegisterModulesHandler, BeEF::API::Server, 'mount_handler') BeEF::API::Registrar.instance.register(BeEF::Core::Rest::RegisterLogsHandler, BeEF::API::Server, 'mount_handler') + BeEF::API::Registrar.instance.register(BeEF::Core::Rest::RegisterAdminHandler, BeEF::API::Server, 'mount_handler') + + # + # Check the source IP is within the permitted subnet + # This is from extensions/admin_ui/controllers/authentication/authentication.rb + # + def self.permitted_source?(ip) + # get permitted subnet + permitted_ui_subnet = BeEF::Core::Configuration.instance.get("beef.restrictions.permitted_ui_subnet") + target_network = IPAddr.new(permitted_ui_subnet) + + # test if ip within subnet + return target_network.include?(ip) + end end end diff --git a/core/main/rest/handlers/hookedbrowsers.rb b/core/main/rest/handlers/hookedbrowsers.rb index aa269ff88..89379ac7f 100644 --- a/core/main/rest/handlers/hookedbrowsers.rb +++ b/core/main/rest/handlers/hookedbrowsers.rb @@ -23,6 +23,7 @@ module BeEF before do error 401 unless params[:token] == config.get('beef.api_token') + halt 401 if not BeEF::Core::Rest.permitted_source?(request.ip) headers 'Content-Type' => 'application/json; charset=UTF-8', 'Pragma' => 'no-cache', 'Cache-Control' => 'no-cache', diff --git a/core/main/rest/handlers/logs.rb b/core/main/rest/handlers/logs.rb index 52a64e089..848e1fd2e 100644 --- a/core/main/rest/handlers/logs.rb +++ b/core/main/rest/handlers/logs.rb @@ -23,6 +23,7 @@ module BeEF before do error 401 unless params[:token] == config.get('beef.api_token') + halt 401 if not BeEF::Core::Rest.permitted_source?(request.ip) headers 'Content-Type' => 'application/json; charset=UTF-8', 'Pragma' => 'no-cache', 'Cache-Control' => 'no-cache', diff --git a/core/main/rest/handlers/modules.rb b/core/main/rest/handlers/modules.rb index 5afa85482..61e78209c 100644 --- a/core/main/rest/handlers/modules.rb +++ b/core/main/rest/handlers/modules.rb @@ -23,6 +23,7 @@ module BeEF before do error 401 unless params[:token] == config.get('beef.api_token') + halt 401 if not BeEF::Core::Rest.permitted_source?(request.ip) headers 'Content-Type' => 'application/json; charset=UTF-8', 'Pragma' => 'no-cache', 'Cache-Control' => 'no-cache', From 321a63b148c271bdac042457d7bf25832403ad4b Mon Sep 17 00:00:00 2001 From: Christian Frichot Date: Sun, 15 Apr 2012 07:24:56 +0800 Subject: [PATCH 02/14] Placeholder admin RESTful API class --- core/main/rest/handlers/admin.rb | 42 ++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 core/main/rest/handlers/admin.rb diff --git a/core/main/rest/handlers/admin.rb b/core/main/rest/handlers/admin.rb new file mode 100644 index 000000000..51fa7555e --- /dev/null +++ b/core/main/rest/handlers/admin.rb @@ -0,0 +1,42 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +module BeEF + module Core + module Rest + class Admin < BeEF::Core::Router::Router + + config = BeEF::Core::Configuration.instance + + before do + # error 401 unless params[:token] == config.get('beef.api_token') + halt 401 if not 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 + + get '/' do + "Hiya" + end + + private + + end + end + end +end \ No newline at end of file From 79a7dd3e883a78c006e0e1fe83597372ede8973d Mon Sep 17 00:00:00 2001 From: Christian Frichot Date: Sun, 15 Apr 2012 16:38:38 +0800 Subject: [PATCH 03/14] RESTful Admin API Class now includes a LOGIN method --- core/main/rest/handlers/admin.rb | 35 ++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/core/main/rest/handlers/admin.rb b/core/main/rest/handlers/admin.rb index 51fa7555e..ac1e6c046 100644 --- a/core/main/rest/handlers/admin.rb +++ b/core/main/rest/handlers/admin.rb @@ -30,8 +30,39 @@ module BeEF 'Expires' => '0' end - get '/' do - "Hiya" + # @note Authenticate using the config set username/password to retrieve the "token" used for subsquent calls. + # Return the secret token used for subsquene tAPI calls. + # + # Input must be specified in JSON format + # + # +++ Example: +++ + #POST /api/admin/login HTTP/1.1 + #Host: 127.0.0.1:3000 + #Content-Type: application/json; charset=UTF-8 + #Content-Length: 18 + # + #{"username":"beef", "password":"beef"} + #===response (snip)=== + #HTTP/1.1 200 OK + #Content-Type: application/json; charset=UTF-8 + #Content-Length: 35 + # + #{"success":"true","token":"122323121"} + # + post '/login' do + request.body.rewind + begin + data = JSON.parse request.body.read + # check username and password + if not (data['username'].eql? config.get('beef.extension.admin_ui.username') and data['password'].eql? config.get('beef.extension.admin_ui.password') ) + BeEF::Core::Logger.instance.register('Authentication', "User with ip #{request.ip} has failed to authenticate in the application.") + halt 401 + else + '{"success":"true","token":"' + config.get('beef.api_token') + '"' + end + rescue Exception => e + error 400 + end end private From 364575592ae6821ccc65eb7aa7d807529a0537e4 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Sun, 15 Apr 2012 10:53:08 +0100 Subject: [PATCH 04/14] Moved BeEF credentials from admin_ui extension to the main config.yaml. Updated both admin_ui and RESTful API to reflect the changes. --- config.yaml | 10 +++++++--- core/main/rest/handlers/admin.rb | 2 +- extensions/admin_ui/config.yaml | 4 +--- .../controllers/authentication/authentication.rb | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/config.yaml b/config.yaml index 97658800e..669bb5bdd 100644 --- a/config.yaml +++ b/config.yaml @@ -39,9 +39,8 @@ beef: session_cookie_name: "BEEFSESSION" # Imitate a specified web server (default root page, 404 default error page, 'Server' HTTP response header) web_server_imitation: - enable: false - #supported: apache, iis - type: "apache" + enable: false + type: "apache" #supported: apache, iis database: # For information on using other databases please read the @@ -60,6 +59,11 @@ beef: db_passwd: "beef123" db_encoding: "UTF-8" + # Credentials to authenticate in BeEF. Used by both the RESTful API and the Admin_UI extension + credentials: + user: "beef" + passwd: "beef" + crypto_default_value_length: 80 # You may override default extension configuration parameters here diff --git a/core/main/rest/handlers/admin.rb b/core/main/rest/handlers/admin.rb index ac1e6c046..c5ffd9f08 100644 --- a/core/main/rest/handlers/admin.rb +++ b/core/main/rest/handlers/admin.rb @@ -54,7 +54,7 @@ module BeEF begin data = JSON.parse request.body.read # check username and password - if not (data['username'].eql? config.get('beef.extension.admin_ui.username') and data['password'].eql? config.get('beef.extension.admin_ui.password') ) + if not (data['username'].eql? config.get('beef.credentials.user') and data['password'].eql? config.get('beef.credentials.passwd') ) BeEF::Core::Logger.instance.register('Authentication', "User with ip #{request.ip} has failed to authenticate in the application.") halt 401 else diff --git a/extensions/admin_ui/config.yaml b/extensions/admin_ui/config.yaml index 0e29a226a..dde46ca70 100644 --- a/extensions/admin_ui/config.yaml +++ b/extensions/admin_ui/config.yaml @@ -17,9 +17,7 @@ beef: extension: admin_ui: name: 'Admin UI' - enable: true - username: "beef" - password: "beef" + enable: true favicon_file_name: "favicon.ico" favicon_dir: "/images" login_fail_delay: 1 diff --git a/extensions/admin_ui/controllers/authentication/authentication.rb b/extensions/admin_ui/controllers/authentication/authentication.rb index ad94d452e..f07a4f94e 100644 --- a/extensions/admin_ui/controllers/authentication/authentication.rb +++ b/extensions/admin_ui/controllers/authentication/authentication.rb @@ -69,7 +69,7 @@ class Authentication < BeEF::Extension::AdminUI::HttpController end # check username and password - if not (username.eql? config.get('beef.extension.admin_ui.username') and password.eql? config.get('beef.extension.admin_ui.password') ) + if not (username.eql? config.get('beef.credentials.user') and password.eql? config.get('beef.credentials.passwd') ) BeEF::Core::Logger.instance.register('Authentication', "User with ip #{@request.ip} has failed to authenticate in the application.") return end From 8feef887b95a64b499309a964f69177aad00f2ef Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Sun, 15 Apr 2012 11:56:00 +0100 Subject: [PATCH 05/14] Fixed issue with malformed JSON response (missing }). No using hash.to_json to send response. --- core/main/rest/handlers/admin.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/main/rest/handlers/admin.rb b/core/main/rest/handlers/admin.rb index c5ffd9f08..d36935bfe 100644 --- a/core/main/rest/handlers/admin.rb +++ b/core/main/rest/handlers/admin.rb @@ -58,7 +58,9 @@ module BeEF BeEF::Core::Logger.instance.register('Authentication', "User with ip #{request.ip} has failed to authenticate in the application.") halt 401 else - '{"success":"true","token":"' + config.get('beef.api_token') + '"' + { "success" => true, + "token" => "#{config.get('beef.api_token')}" + }.to_json end rescue Exception => e error 400 From 3ebe44732b4fc5e497ed6d5ec3d304960a31f8c1 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Sun, 15 Apr 2012 12:54:04 +0100 Subject: [PATCH 06/14] Added beef.module.key.class to /api/module JSON response. --- core/main/rest/handlers/modules.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/core/main/rest/handlers/modules.rb b/core/main/rest/handlers/modules.rb index 61e78209c..7addcf623 100644 --- a/core/main/rest/handlers/modules.rb +++ b/core/main/rest/handlers/modules.rb @@ -41,6 +41,7 @@ module BeEF next if !BeEF::Module.is_enabled(modk) mods_hash[i] = { 'id' => mod.id, + 'class' => config.get("beef.module.#{modk}.class"), 'name' => config.get("beef.module.#{modk}.name"), 'category' => config.get("beef.module.#{modk}.category") } From 98807ae9a3e9d4b82c507505cef3f3a619d871b4 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Sun, 15 Apr 2012 13:22:35 +0100 Subject: [PATCH 07/14] Added RESTful API tests for /api/auth, /api/hooks, /api/modules. Added Test_return_long_string Debug module test using the API :D --- test/common/test_constants.rb | 11 ++++ test/integration/tc_debug_modules.rb | 93 ++++++++++++++++++++++++++++ test/integration/ts_integration.rb | 2 + 3 files changed, 106 insertions(+) create mode 100644 test/integration/tc_debug_modules.rb diff --git a/test/common/test_constants.rb b/test/common/test_constants.rb index b7390f0ae..322010219 100644 --- a/test/common/test_constants.rb +++ b/test/common/test_constants.rb @@ -1,6 +1,17 @@ BEEF_TEST_DIR = "/tmp/beef-test/" +# General constants ATTACK_DOMAIN = "attacker.beefproject.com" VICTIM_DOMAIN = "attacker.beefproject.com" ATTACK_URL = "http://" + ATTACK_DOMAIN + ":3000/ui/panel" VICTIM_URL = "http://" + VICTIM_DOMAIN + ":3000/demos/basic.html" + +# Credentials +BEEF_USER = "beef" +BEEF_PASSWD = "beef" + +# RESTful API root endpoints +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_ADMIN = "http://" + ATTACK_DOMAIN + ":3000/api/admin" diff --git a/test/integration/tc_debug_modules.rb b/test/integration/tc_debug_modules.rb new file mode 100644 index 000000000..6945d7a7f --- /dev/null +++ b/test/integration/tc_debug_modules.rb @@ -0,0 +1,93 @@ +require 'test/unit' +require 'rest_client' +require 'json' +require '../common/test_constants' +require '../common/beef_test' + +class TC_DebugModules < Test::Unit::TestCase + + @@token = nil + @@hb_session = nil + + @@mod_debug_long_string = nil + @@mod_debug_ascii_chars = nil + @@mod_debug_test_network = nil + + # Test RESTful API authentication with default credentials, returns the API token to be used later. + def test_restful_auth + response = RestClient.post "#{RESTAPI_ADMIN}/login", + { 'username' => "#{BEEF_USER}", + 'password' => "#{BEEF_PASSWD}"}.to_json, + :content_type => :json, + :accept => :json + assert_equal 200, response.code + assert_not_nil response.body + result = JSON.parse(response.body) + success = result['success'] + @@token = result['token'] + assert(success) + end + + # Test RESTful API hooks handler hooking a victim browser, and then retrieving his BeEF session + def test_restful_hooks + BeefTest.new_victim + sleep 2.0 + response = RestClient.get "#{RESTAPI_HOOKS}", {:params => {:token => @@token}} + assert_equal 200, response.code + assert_not_nil response.body + result = JSON.parse(response.body) + @@hb_session = result["hooked-browsers"]["online"]["0"]["session"] + assert_not_nil @@hb_session + end + + # Test RESTful API modules handler, retrieving the IDs of the 3 debug modules currently in the framework + def test_restful_modules + response = RestClient.get "#{RESTAPI_MODULES}", {:params => {:token => @@token}} + assert_equal 200, response.code + assert_not_nil response.body + result = JSON.parse(response.body) + result.each do |mod| + case mod[1]["class"] + when "Test_return_long_string" + @@mod_debug_long_string = mod[1]["id"] + when "Test_return_ascii_chars" + @@mod_debug_ascii_chars = mod[1]["id"] + when "Test_network_request" + @@mod_debug_test_network = mod[1]["id"] + end + end + assert_not_nil @@mod_debug_long_string + assert_not_nil @@mod_debug_ascii_chars + assert_not_nil @@mod_debug_test_network + end + + # Test debug module "Test_return_long_string" using the RESTful API + def test_return_long_string + repeat_string = "BeEF" + repeat_count = 20 + + BeefTest.new_victim + sleep 2.0 + response = RestClient.post "#{RESTAPI_MODULES}/#{@@hb_session}/#{@@mod_debug_long_string}?token=#{@@token}", + { 'repeat_string' => repeat_string, + 'repeat' => repeat_count}.to_json, + :content_type => :json, + :accept => :json + assert_equal 200, response.code + assert_not_nil response.body + result = JSON.parse(response.body) + success = result['success'] + assert success + + cmd_id = result['command_id'] + sleep 3.0 + response = RestClient.get "#{RESTAPI_MODULES}/#{@@hb_session}/#{@@mod_debug_long_string}/#{cmd_id}", {:params => {:token => @@token}} + assert_equal 200, response.code + assert_not_nil response.body + result = JSON.parse(response.body) + data = JSON.parse(result["data"]) + assert_not_nil data + assert data["data"] == (repeat_string * repeat_count) + end + +end \ No newline at end of file diff --git a/test/integration/ts_integration.rb b/test/integration/ts_integration.rb index 917de1324..b5f4d5a28 100644 --- a/test/integration/ts_integration.rb +++ b/test/integration/ts_integration.rb @@ -23,6 +23,7 @@ Capybara.run_server = false # we need to run our own BeEF server require 'selenium/webdriver' require './check_environment' # Basic log in and log out tests +require './tc_debug_modules' # RESTful API tests (as well as debug modules) require './tc_login' # Basic log in and log out tests class TS_BeefIntegrationTests @@ -30,6 +31,7 @@ class TS_BeefIntegrationTests suite = Test::Unit::TestSuite.new(name="BeEF Integration Test Suite") suite << TC_CheckEnvironment.suite + suite << TC_DebugModules.suite suite << TC_login.suite return suite From 8f05a403eeb51978d0d1851de21ff7796bf044f1 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Sun, 15 Apr 2012 13:45:24 +0100 Subject: [PATCH 08/14] Added Test_return_ascii_chars Debug module test using the API. --- test/integration/tc_debug_modules.rb | 29 +++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/test/integration/tc_debug_modules.rb b/test/integration/tc_debug_modules.rb index 6945d7a7f..183774e91 100644 --- a/test/integration/tc_debug_modules.rb +++ b/test/integration/tc_debug_modules.rb @@ -87,7 +87,34 @@ class TC_DebugModules < Test::Unit::TestCase result = JSON.parse(response.body) data = JSON.parse(result["data"]) assert_not_nil data - assert data["data"] == (repeat_string * repeat_count) + assert_equal data["data"],(repeat_string * repeat_count) + end + + # Test debug module "Test_return_ascii_chars" using the RESTful API + def test_return_ascii_chars + BeefTest.new_victim + sleep 2.0 + response = RestClient.post "#{RESTAPI_MODULES}/#{@@hb_session}/#{@@mod_debug_ascii_chars}?token=#{@@token}", + {}.to_json, + :content_type => :json, + :accept => :json + assert_equal 200, response.code + assert_not_nil response.body + result = JSON.parse(response.body) + success = result['success'] + assert success + + cmd_id = result['command_id'] + sleep 3.0 + response = RestClient.get "#{RESTAPI_MODULES}/#{@@hb_session}/#{@@mod_debug_ascii_chars}/#{cmd_id}", {:params => {:token => @@token}} + assert_equal 200, response.code + assert_not_nil response.body + result = JSON.parse(response.body) + data = JSON.parse(result["data"]) + assert_not_nil data + ascii_chars = "" + (32..127).each do |i| ascii_chars << i.chr end + assert_equal ascii_chars,data["data"] end end \ No newline at end of file From 54e244013bcaff20ae61ccb3a64a2608943f45b8 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Sun, 15 Apr 2012 15:08:42 +0100 Subject: [PATCH 09/14] Removed response= variable from test_network_request module response. NOt needed. --- modules/debug/test_network_request/command.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/debug/test_network_request/command.js b/modules/debug/test_network_request/command.js index f71ef814c..1e298d835 100644 --- a/modules/debug/test_network_request/command.js +++ b/modules/debug/test_network_request/command.js @@ -25,7 +25,7 @@ beef.execute(function() { var timeout = "<%= @timeout %>"; var dataType = "<%= @dataType %>"; - beef.net.request(scheme, method, domain, port, path, anchor, data, timeout, dataType, function(response) { beef.net.send("<%= @command_url %>", <%= @command_id %>, "response="+JSON.stringify(response)); } ); + beef.net.request(scheme, method, domain, port, path, anchor, data, timeout, dataType, function(response) { beef.net.send("<%= @command_url %>", <%= @command_id %>, JSON.stringify(response)); } ); }); From 66dbf871f14e1bbae4eaac99365a95d9414b783d Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Sun, 15 Apr 2012 15:09:26 +0100 Subject: [PATCH 10/14] Added test for test_network_request using the API. --- test/integration/tc_debug_modules.rb | 34 ++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/test/integration/tc_debug_modules.rb b/test/integration/tc_debug_modules.rb index 183774e91..e1547b7c7 100644 --- a/test/integration/tc_debug_modules.rb +++ b/test/integration/tc_debug_modules.rb @@ -66,8 +66,6 @@ class TC_DebugModules < Test::Unit::TestCase repeat_string = "BeEF" repeat_count = 20 - BeefTest.new_victim - sleep 2.0 response = RestClient.post "#{RESTAPI_MODULES}/#{@@hb_session}/#{@@mod_debug_long_string}?token=#{@@token}", { 'repeat_string' => repeat_string, 'repeat' => repeat_count}.to_json, @@ -92,10 +90,8 @@ class TC_DebugModules < Test::Unit::TestCase # Test debug module "Test_return_ascii_chars" using the RESTful API def test_return_ascii_chars - BeefTest.new_victim - sleep 2.0 response = RestClient.post "#{RESTAPI_MODULES}/#{@@hb_session}/#{@@mod_debug_ascii_chars}?token=#{@@token}", - {}.to_json, + {}.to_json, # module does not expect any input :content_type => :json, :accept => :json assert_equal 200, response.code @@ -117,4 +113,32 @@ class TC_DebugModules < Test::Unit::TestCase assert_equal ascii_chars,data["data"] end + # Test debug module "Test_network_request" using the RESTful API + def test_return_network_request + + # Test same-domain request (response code and content of secret_page.html) + response = RestClient.post "#{RESTAPI_MODULES}/#{@@hb_session}/#{@@mod_debug_test_network}?token=#{@@token}", + #override only a few parameters, the other ones will have default values from modules's module.rb definition + {"domain" => ATTACK_DOMAIN, "port" => "3000", "path" => "/demos/secret_page.html"}.to_json, + :content_type => :json, + :accept => :json + assert_equal 200, response.code + assert_not_nil response.body + result = JSON.parse(response.body) + success = result['success'] + assert success + + cmd_id = result['command_id'] + sleep 3.0 + response = RestClient.get "#{RESTAPI_MODULES}/#{@@hb_session}/#{@@mod_debug_test_network}/#{cmd_id}", {:params => {:token => @@token}} + assert_equal 200, response.code + assert_not_nil response.body + result = JSON.parse(response.body) + data = JSON.parse(result["data"]) + res = JSON.parse(data["data"]) + assert_not_nil res + assert_equal 200, res["status_code"] + assert res["response_body"].include?("However you should still be capable of accessing it\n\t\tusing the Requester") + + end end \ No newline at end of file From 6f57d563eaf2ea440cac8b3716f69566e3a339df Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Mon, 16 Apr 2012 18:02:42 +0100 Subject: [PATCH 11/14] Jenkins test --- test/integration/tc_debug_modules.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/tc_debug_modules.rb b/test/integration/tc_debug_modules.rb index e1547b7c7..7386455cc 100644 --- a/test/integration/tc_debug_modules.rb +++ b/test/integration/tc_debug_modules.rb @@ -13,6 +13,7 @@ class TC_DebugModules < Test::Unit::TestCase @@mod_debug_ascii_chars = nil @@mod_debug_test_network = nil + # test jenkins # Test RESTful API authentication with default credentials, returns the API token to be used later. def test_restful_auth response = RestClient.post "#{RESTAPI_ADMIN}/login", From 8a3fadb5f82da5c3e9274fb178912a35c40535eb Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Wed, 18 Apr 2012 12:04:37 +0100 Subject: [PATCH 12/14] removed test jenkind line --- test/integration/tc_debug_modules.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/test/integration/tc_debug_modules.rb b/test/integration/tc_debug_modules.rb index 7386455cc..e1547b7c7 100644 --- a/test/integration/tc_debug_modules.rb +++ b/test/integration/tc_debug_modules.rb @@ -13,7 +13,6 @@ class TC_DebugModules < Test::Unit::TestCase @@mod_debug_ascii_chars = nil @@mod_debug_test_network = nil - # test jenkins # Test RESTful API authentication with default credentials, returns the API token to be used later. def test_restful_auth response = RestClient.post "#{RESTAPI_ADMIN}/login", From cd4fce7887869be119b062a64da80ab7cac54a76 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Wed, 18 Apr 2012 12:54:48 +0100 Subject: [PATCH 13/14] Moved initialization extension into the core. BrowserDetails are a vital component of BeEF. There is no reason to don't have it in the core. --- core/bootstrap.rb | 1 + core/core.rb | 1 + .../main/handlers/browserdetails.rb | 15 +++----- .../main}/models/browserdetails.rb | 17 ++------- core/main/rest/handlers/hookedbrowsers.rb | 2 +- core/main/server.rb | 3 ++ extensions/console/lib/shellinterface.rb | 2 +- extensions/initialization/api.rb | 38 ------------------- extensions/initialization/config.yaml | 21 ---------- extensions/initialization/extension.rb | 32 ---------------- 10 files changed, 16 insertions(+), 116 deletions(-) rename extensions/initialization/handler.rb => core/main/handlers/browserdetails.rb (97%) rename {extensions/initialization => core/main}/models/browserdetails.rb (93%) delete mode 100644 extensions/initialization/api.rb delete mode 100644 extensions/initialization/config.yaml delete mode 100644 extensions/initialization/extension.rb diff --git a/core/bootstrap.rb b/core/bootstrap.rb index 290b4a554..b48ef93a0 100644 --- a/core/bootstrap.rb +++ b/core/bootstrap.rb @@ -30,6 +30,7 @@ require 'core/main/handlers/modules/beefjs' require 'core/main/handlers/modules/command' require 'core/main/handlers/commands' require 'core/main/handlers/hookedbrowsers' +require 'core/main/handlers/browserdetails' # @note Include the network stack require 'core/main/network_stack/handlers/dynamicreconstruction' diff --git a/core/core.rb b/core/core.rb index bc655694c..dc554314b 100644 --- a/core/core.rb +++ b/core/core.rb @@ -27,6 +27,7 @@ require 'core/main/models/log' require 'core/main/models/command' require 'core/main/models/result' require 'core/main/models/optioncache' +require 'core/main/models/browserdetails' # @note Include the constants require 'core/main/constants/browsers' diff --git a/extensions/initialization/handler.rb b/core/main/handlers/browserdetails.rb similarity index 97% rename from extensions/initialization/handler.rb rename to core/main/handlers/browserdetails.rb index a56fae3fb..862e20770 100644 --- a/extensions/initialization/handler.rb +++ b/core/main/handlers/browserdetails.rb @@ -14,18 +14,15 @@ # limitations under the License. # module BeEF - module Extension - module Initialization - - # - # The http handler that manages the return of the initial browser details. - # - class Handler + module Core + module Handlers + # @note Retrieves information about the browser (type, version, plugins etc.) + class BrowserDetails @data = {} HB = BeEF::Core::Models::HookedBrowser - BD = BeEF::Extension::Initialization::Models::BrowserDetails + BD = BeEF::Core::Models::BrowserDetails def initialize(data) @data = data @@ -33,7 +30,7 @@ module BeEF end def err_msg(error) - print_error "[INITIALIZATION] #{error}" + print_error "[Browser Details] #{error}" end def setup() diff --git a/extensions/initialization/models/browserdetails.rb b/core/main/models/browserdetails.rb similarity index 93% rename from extensions/initialization/models/browserdetails.rb rename to core/main/models/browserdetails.rb index f2ac1edb6..0cd114c75 100644 --- a/extensions/initialization/models/browserdetails.rb +++ b/core/main/models/browserdetails.rb @@ -14,8 +14,7 @@ # limitations under the License. # module BeEF -module Extension -module Initialization +module Core module Models # # Table stores the details of browsers. @@ -26,16 +25,7 @@ module Models include DataMapper::Resource - storage_names[:default] = 'extension_initialization_browserdetails' - - - # - # Class constructor - # - def initialize(config) - super(config) - end - + storage_names[:default] = 'core_browserdetails' property :session_id, String, :length => 255, :key => true property :detail_key, String, :length => 255, :lazy => false, :key => true property :detail_value, Text, :lazy => false @@ -59,7 +49,7 @@ module Models return nil if not get(session_id, detail_key).nil? # store the returned browser details - browserdetails = BeEF::Extension::Initialization::Models::BrowserDetails.new( + browserdetails = BeEF::Core::Models::BrowserDetails.new( :session_id => session_id, :detail_key => detail_key, :detail_value => detail_value) @@ -120,4 +110,3 @@ module Models end end end -end diff --git a/core/main/rest/handlers/hookedbrowsers.rb b/core/main/rest/handlers/hookedbrowsers.rb index 89379ac7f..aedc3fe34 100644 --- a/core/main/rest/handlers/hookedbrowsers.rb +++ b/core/main/rest/handlers/hookedbrowsers.rb @@ -55,7 +55,7 @@ module BeEF end def get_hb_details(hb) - details = BeEF::Extension::Initialization::Models::BrowserDetails + details = BeEF::Core::Models::BrowserDetails { 'name' => details.get(hb.session, 'BrowserName'), diff --git a/core/main/server.rb b/core/main/server.rb index e47eb1fd1..86ae23e74 100644 --- a/core/main/server.rb +++ b/core/main/server.rb @@ -82,6 +82,9 @@ module BeEF # Create http handler for the javascript hook file self.mount("#{@configuration.get("beef.http.hook_file")}", BeEF::Core::Handlers::HookedBrowsers.new) + # Create handler for the initialization checks (Browser Details) + self.mount("/init", BeEF::Core::Handlers::BrowserDetails) + # Dynamically get the list of all the http handlers using the API and register them BeEF::API::Registrar.instance.fire(BeEF::API::Server, 'mount_handler', self) diff --git a/extensions/console/lib/shellinterface.rb b/extensions/console/lib/shellinterface.rb index 78f099e53..927686cb7 100644 --- a/extensions/console/lib/shellinterface.rb +++ b/extensions/console/lib/shellinterface.rb @@ -19,7 +19,7 @@ module Console class ShellInterface - BD = BeEF::Extension::Initialization::Models::BrowserDetails + BD = BeEF::Core::Models::BrowserDetails def initialize(config) self.config = config diff --git a/extensions/initialization/api.rb b/extensions/initialization/api.rb deleted file mode 100644 index ea3138e9d..000000000 --- a/extensions/initialization/api.rb +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright 2012 Wade Alcorn wade@bindshell.net -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -module BeEF -module Extension -module Initialization - - module RegisterHttpHandler - - # Register API calls - BeEF::API::Registrar.instance.register(BeEF::Extension::Initialization::RegisterHttpHandler, BeEF::API::Server, 'mount_handler') - - # - # Register the http handler for the initialization script that retrieves - # all the information about hooked browsers. - # - def self.mount_handler(beef_server) - beef_server.mount('/init', BeEF::Extension::Initialization::Handler) - end - - end - - -end -end -end diff --git a/extensions/initialization/config.yaml b/extensions/initialization/config.yaml deleted file mode 100644 index d83ae154c..000000000 --- a/extensions/initialization/config.yaml +++ /dev/null @@ -1,21 +0,0 @@ -# -# Copyright 2012 Wade Alcorn wade@bindshell.net -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -beef: - extension: - initialization: - enable: true - name: 'Initialization' - diff --git a/extensions/initialization/extension.rb b/extensions/initialization/extension.rb deleted file mode 100644 index e13f67fe0..000000000 --- a/extensions/initialization/extension.rb +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright 2012 Wade Alcorn wade@bindshell.net -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -module BeEF -module Extension -module Initialization - - extend BeEF::API::Extension - - @short_name = @full_name = 'initialization' - - @description = 'retrieves information about the browser (type, version, plugins etc.)' - -end -end -end - -require 'extensions/initialization/models/browserdetails' -require 'extensions/initialization/handler' -require 'extensions/initialization/api' From d1e23c208435b0228a66ee8062a663bcf000f465 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Wed, 18 Apr 2012 14:37:44 +0100 Subject: [PATCH 14/14] Updated admin_ui and console extensions code to reflect the move of initialization extension into the core. --- extensions/admin_ui/api/command.rb | 2 +- extensions/admin_ui/controllers/modules/modules.rb | 2 +- extensions/admin_ui/controllers/panel/panel.rb | 6 +++--- extensions/console/lib/command_dispatcher/core.rb | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/extensions/admin_ui/api/command.rb b/extensions/admin_ui/api/command.rb index a35d52839..d1257fe64 100644 --- a/extensions/admin_ui/api/command.rb +++ b/extensions/admin_ui/api/command.rb @@ -29,7 +29,7 @@ module API # Get the browser detail from the database. # def get_browser_detail(key) - bd = BeEF::Extension::Initialization::Models::BrowserDetails + bd = BeEF::Core::Models::BrowserDetails (print_error "@session_id is invalid";return) if not BeEF::Filters.is_valid_hook_session_id?(@session_id) bd.get(@session_id, key) end diff --git a/extensions/admin_ui/controllers/modules/modules.rb b/extensions/admin_ui/controllers/modules/modules.rb index f140ef3d5..18528ceed 100644 --- a/extensions/admin_ui/controllers/modules/modules.rb +++ b/extensions/admin_ui/controllers/modules/modules.rb @@ -23,7 +23,7 @@ module Controllers # class Modules < BeEF::Extension::AdminUI::HttpController - BD = BeEF::Extension::Initialization::Models::BrowserDetails + BD = BeEF::Core::Models::BrowserDetails def initialize super({ diff --git a/extensions/admin_ui/controllers/panel/panel.rb b/extensions/admin_ui/controllers/panel/panel.rb index 64fd04593..f50adb121 100644 --- a/extensions/admin_ui/controllers/panel/panel.rb +++ b/extensions/admin_ui/controllers/panel/panel.rb @@ -85,9 +85,9 @@ class Panel < BeEF::Extension::AdminUI::HttpController # create a hash of simple hooked browser details def get_simple_hooked_browser_hash(hooked_browser) - browser_icon = BeEF::Extension::Initialization::Models::BrowserDetails.browser_icon(hooked_browser.session) - os_icon = BeEF::Extension::Initialization::Models::BrowserDetails.os_icon(hooked_browser.session) - domain = BeEF::Extension::Initialization::Models::BrowserDetails.get(hooked_browser.session, 'HostName') + browser_icon = BeEF::Core::Models::BrowserDetails.browser_icon(hooked_browser.session) + os_icon = BeEF::Core::Models::BrowserDetails.os_icon(hooked_browser.session) + domain = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HostName') return { 'session' => hooked_browser.session, diff --git a/extensions/console/lib/command_dispatcher/core.rb b/extensions/console/lib/command_dispatcher/core.rb index d766dcdaa..2a1f81a99 100644 --- a/extensions/console/lib/command_dispatcher/core.rb +++ b/extensions/console/lib/command_dispatcher/core.rb @@ -151,7 +151,7 @@ class Core ]) BeEF::Core::Models::HookedBrowser.all(:lastseen.gte => (Time.new.to_i - 30)).each do |zombie| - tbl << [zombie.id,zombie.ip,beef_logo_to_os(BeEF::Extension::Initialization::Models::BrowserDetails.os_icon(zombie.session))] + tbl << [zombie.id,zombie.ip,beef_logo_to_os(BeEF::Core::Models::BrowserDetails.os_icon(zombie.session))] end puts "\n" @@ -182,7 +182,7 @@ class Core ]) BeEF::Core::Models::HookedBrowser.all(:lastseen.lt => (Time.new.to_i - 30)).each do |zombie| - tbl << [zombie.id,zombie.ip,beef_logo_to_os(BeEF::Extension::Initialization::Models::BrowserDetails.os_icon(zombie.session))] + tbl << [zombie.id,zombie.ip,beef_logo_to_os(BeEF::Core::Models::BrowserDetails.os_icon(zombie.session))] end puts "\n"