@@ -57,7 +57,6 @@ beef:
|
||||
# Hook
|
||||
hook_file: "/hook.js"
|
||||
hook_session_name: "BEEFHOOK"
|
||||
session_cookie_name: "BEEFSESSION"
|
||||
|
||||
# Allow one or multiple origins to access the RESTful API using CORS
|
||||
# For multiple origins use: "http://browserhacker.com, http://domain2.com"
|
||||
|
||||
@@ -29,9 +29,6 @@ require 'core/main/network_stack/handlers/raw'
|
||||
require 'core/main/network_stack/assethandler'
|
||||
require 'core/main/network_stack/api'
|
||||
|
||||
# @note Include the distributed engine
|
||||
require 'core/main/distributed_engine/models/rules'
|
||||
|
||||
# @note Include the autorun engine
|
||||
require 'core/main/autorun_engine/models/rule'
|
||||
require 'core/main/autorun_engine/models/execution'
|
||||
|
||||
@@ -22,7 +22,6 @@ require 'core/main/models/browserdetails'
|
||||
# @note Include the constants
|
||||
require 'core/main/constants/browsers'
|
||||
require 'core/main/constants/commandmodule'
|
||||
require 'core/main/constants/distributedengine'
|
||||
require 'core/main/constants/os'
|
||||
require 'core/main/constants/hardware'
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 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 Constants
|
||||
|
||||
# @note The distributed engine codes
|
||||
module DistributedEngine
|
||||
|
||||
REQUESTER = 1
|
||||
PORTSCANNER = 2
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,28 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 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 DistributedEngine
|
||||
module Models
|
||||
|
||||
# @note Table stores the rules for the Distributed Engine.
|
||||
class Rules
|
||||
|
||||
include DataMapper::Resource
|
||||
|
||||
storage_names[:default] = 'extension_distributedengine_rules'
|
||||
|
||||
property :id, Serial
|
||||
property :data, Text
|
||||
property :enabled, Boolean
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -20,13 +20,6 @@ module BeEF
|
||||
'Expires' => '0'
|
||||
end
|
||||
|
||||
#
|
||||
# @note Return a can of Leffe to the thirsty Bovine Security Team member. AthCon2012 joke /antisnatchor/
|
||||
#
|
||||
#get "/to/a/pub"
|
||||
# "BeER please"
|
||||
#end
|
||||
|
||||
#
|
||||
# @note Get online and offline hooked browsers details (like name, version, os, ip, port, ...)
|
||||
#
|
||||
@@ -158,7 +151,8 @@ module BeEF
|
||||
BeEF::Core::Models::BrowserDetails.new(:session_id => hb.session, :detail_key => 'OsVersion', :detail_value => os_version).save
|
||||
BeEF::Core::Models::BrowserDetails.new(:session_id => hb.session, :detail_key => 'Arch', :detail_value => arch).save
|
||||
|
||||
#TODO if there where any ARE rules defined for this hooked browser, after updating OS/arch, force a retrigger of the rule.
|
||||
# TODO if there where any ARE rules defined for this hooked browser,
|
||||
# after updating OS/arch, force a retrigger of the rule.
|
||||
{'success' => true}.to_json
|
||||
end
|
||||
|
||||
@@ -176,19 +170,24 @@ module BeEF
|
||||
details = BeEF::Core::Models::BrowserDetails
|
||||
|
||||
{
|
||||
'id' => hb.id,
|
||||
'session' => hb.session,
|
||||
'name' => details.get(hb.session, 'BrowserName'),
|
||||
'version' => details.get(hb.session, 'BrowserVersion'),
|
||||
'os' => details.get(hb.session, 'OsName'),
|
||||
'os_version' => details.get(hb.session, 'OsVersion'),
|
||||
'platform' => details.get(hb.session, 'BrowserPlatform'),
|
||||
'ip' => hb.ip,
|
||||
'domain' => details.get(hb.session, 'HostName'),
|
||||
'port' => hb.port.to_s,
|
||||
'page_uri' => details.get(hb.session, 'PageURI'),
|
||||
'firstseen' => hb.firstseen,
|
||||
'lastseen' => hb.lastseen,
|
||||
'id' => hb.id,
|
||||
'session' => hb.session,
|
||||
'name' => details.get(hb.session, 'BrowserName'),
|
||||
'version' => details.get(hb.session, 'BrowserVersion'),
|
||||
'os' => details.get(hb.session, 'OsName'),
|
||||
'os_version' => details.get(hb.session, 'OsVersion'),
|
||||
'platform' => details.get(hb.session, 'BrowserPlatform'),
|
||||
'hardware' => details.get(hb.session, 'Hardware'),
|
||||
'ip' => hb.ip,
|
||||
'domain' => details.get(hb.session, 'HostName'),
|
||||
'port' => hb.port.to_s,
|
||||
'page_uri' => details.get(hb.session, 'PageURI'),
|
||||
'firstseen' => hb.firstseen,
|
||||
'lastseen' => hb.lastseen,
|
||||
'date_stamp' => details.get(hb.session, 'DateStamp'),
|
||||
'city' => details.get(hb.session, 'LocationCity'),
|
||||
'country' => details.get(hb.session, 'LocationCountry'),
|
||||
'country_code' => details.get(hb.session, 'LocationCountryIsoCode'),
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@@ -104,24 +104,26 @@ module BeEF
|
||||
headers "Server" => "nginx",
|
||||
"Content-Type" => "text/html"
|
||||
else
|
||||
print_error "You have an error in beef.http.web_server_imitation.type! Supported values are: apache, iis, nginx."
|
||||
headers "Server" => '',
|
||||
"Content-Type" => "text/html"
|
||||
print_error "You have an error in beef.http.web_server_imitation.type!"
|
||||
print_more "Supported values are: apache, iis, nginx."
|
||||
end
|
||||
end
|
||||
|
||||
# @note If CORS is enabled, expose the appropriate headers
|
||||
# this apparently duplicate code is needed to reply to preflight OPTIONS requests, which need to respond with a 200
|
||||
# and be able to handle requests with a JSON content-type
|
||||
if request.request_method == 'OPTIONS' && config.get("beef.http.restful_api.allow_cors")
|
||||
allowed_domains = config.get("beef.http.restful_api.cors_allowed_domains")
|
||||
headers "Access-Control-Allow-Origin" => allowed_domains,
|
||||
"Access-Control-Allow-Methods" => "POST, GET",
|
||||
"Access-Control-Allow-Headers" => "Content-Type"
|
||||
halt 200
|
||||
end
|
||||
|
||||
# @note If CORS is enabled, expose the appropriate headers
|
||||
if config.get("beef.http.restful_api.allow_cors")
|
||||
allowed_domains = config.get("beef.http.restful_api.cors_allowed_domains")
|
||||
|
||||
# Responses to preflight OPTIONS requests need to respond with hTTP 200
|
||||
# and be able to handle requests with a JSON content-type
|
||||
if request.request_method == 'OPTIONS'
|
||||
headers "Access-Control-Allow-Origin" => allowed_domains,
|
||||
"Access-Control-Allow-Methods" => "POST, GET",
|
||||
"Access-Control-Allow-Headers" => "Content-Type"
|
||||
halt 200
|
||||
end
|
||||
|
||||
headers "Access-Control-Allow-Origin" => allowed_domains,
|
||||
"Access-Control-Allow-Methods" => "POST, GET"
|
||||
end
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 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 AdminUI
|
||||
module API
|
||||
|
||||
module CommandExtension
|
||||
|
||||
extend BeEF::API::Command
|
||||
|
||||
include BeEF::Core::Constants::Browsers
|
||||
include BeEF::Core::Constants::CommandModule
|
||||
|
||||
#
|
||||
# Get the browser detail from the database.
|
||||
#
|
||||
def get_browser_detail(key)
|
||||
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
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -36,16 +36,47 @@ module API
|
||||
end
|
||||
|
||||
def self.build_javascript_ui(beef_server)
|
||||
auth_js_file = File.read(File.dirname(__FILE__)+'/../media/javascript/ui/authentication.js') + "\n\n"
|
||||
js_files = ""
|
||||
|
||||
#NOTE: order counts! make sure you know what you're doing if you add files
|
||||
esapi = %w(esapi/Class.create.js esapi/jquery-3.3.1.min.js esapi/jquery-encoder-0.1.0.js)
|
||||
ux = %w(ui/common/beef_common.js ux/PagingStore.js ux/StatusBar.js ux/TabCloseMenu.js)
|
||||
panel = %w(ui/panel/common.js ui/panel/DistributedEngine.js ui/panel/PanelStatusBar.js ui/panel/tabs/ZombieTabDetails.js ui/panel/tabs/ZombieTabLogs.js ui/panel/tabs/ZombieTabCommands.js ui/panel/tabs/ZombieTabRider.js ui/panel/tabs/ZombieTabXssRays.js wterm/wterm.jquery.js ui/panel/tabs/ZombieTabIpec.js ui/panel/tabs/ZombieTabAutorun.js ui/panel/PanelViewer.js ui/panel/LogsDataGrid.js ui/panel/ZombieDataGrid.js ui/panel/MainPanel.js ui/panel/ZombieTab.js ui/panel/ZombieTabs.js ui/panel/zombiesTreeList.js ui/panel/ZombiesMgr.js ui/panel/tabs/ZombieTabNetwork.js ui/panel/tabs/ZombieTabRTC.js ui/panel/Logout.js ui/panel/WelcomeTab.js ui/panel/ModuleSearching.js)
|
||||
esapi = %w(
|
||||
esapi/Class.create.js
|
||||
esapi/jquery-3.3.1.min.js
|
||||
esapi/jquery-encoder-0.1.0.js)
|
||||
|
||||
ux = %w(
|
||||
ui/common/beef_common.js
|
||||
ux/PagingStore.js
|
||||
ux/StatusBar.js
|
||||
ux/TabCloseMenu.js)
|
||||
|
||||
panel = %w(
|
||||
ui/panel/common.js
|
||||
ui/panel/PanelStatusBar.js
|
||||
ui/panel/tabs/ZombieTabDetails.js
|
||||
ui/panel/tabs/ZombieTabLogs.js
|
||||
ui/panel/tabs/ZombieTabCommands.js
|
||||
ui/panel/tabs/ZombieTabRider.js
|
||||
ui/panel/tabs/ZombieTabXssRays.js
|
||||
vis.js/vis.min.js
|
||||
wterm/wterm.jquery.js
|
||||
ui/panel/tabs/ZombieTabIpec.js
|
||||
ui/panel/tabs/ZombieTabAutorun.js
|
||||
ui/panel/PanelViewer.js
|
||||
ui/panel/LogsDataGrid.js
|
||||
ui/panel/ZombieDataGrid.js
|
||||
ui/panel/MainPanel.js
|
||||
ui/panel/ZombieTab.js
|
||||
ui/panel/ZombieTabs.js
|
||||
ui/panel/zombiesTreeList.js
|
||||
ui/panel/ZombiesMgr.js
|
||||
ui/panel/tabs/ZombieTabNetwork.js
|
||||
ui/panel/tabs/ZombieTabRTC.js
|
||||
ui/panel/Logout.js
|
||||
ui/panel/WelcomeTab.js
|
||||
ui/panel/ModuleSearching.js)
|
||||
|
||||
global_js = esapi + ux + panel
|
||||
|
||||
js_files = ''
|
||||
global_js.each do |file|
|
||||
js_files << File.read(File.dirname(__FILE__)+'/../media/javascript/'+file) + "\n\n"
|
||||
end
|
||||
@@ -61,11 +92,11 @@ module API
|
||||
|
||||
# process all JavaScript files, evaluating them with Erubis
|
||||
web_ui_all = self.evaluate_and_minify(js_files, params, 'web_ui_all')
|
||||
auth_js_file = File.read(File.dirname(__FILE__)+'/../media/javascript/ui/authentication.js') + "\n\n"
|
||||
web_ui_auth = self.evaluate_and_minify(auth_js_file, params, 'web_ui_auth')
|
||||
|
||||
beef_server.mount("#{bp}/web_ui_all.js", Rack::File.new(web_ui_all))
|
||||
beef_server.mount("#{bp}/web_ui_auth.js", Rack::File.new(web_ui_auth))
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
@@ -84,22 +115,16 @@ module API
|
||||
beef_server.mount("#{bp}/#{mod_name}", BeEF::Extension::AdminUI::Handlers::UI.new(mod_name))
|
||||
end
|
||||
|
||||
# registers the http controllers used by BeEF extensions (requester, proxy, xssrays, etc..)
|
||||
Dir["#{$root_dir}/extensions/**/controllers/*.rb"].each do |http_module|
|
||||
require http_module
|
||||
mod_name = File.basename http_module, '.rb'
|
||||
beef_server.mount("#{bp}/#{mod_name}", BeEF::Extension::AdminUI::Handlers::UI.new(mod_name))
|
||||
end
|
||||
|
||||
# mount the folder were we store static files (javascript, css, images, audio) for the admin ui
|
||||
media_dir = File.dirname(__FILE__)+'/../media/'
|
||||
beef_server.mount("#{bp}/media", Rack::File.new(media_dir))
|
||||
|
||||
# mount the favicon file, if we're not imitating a web server.
|
||||
# If we're not imitating a web server, mount the favicon to /favicon.ico
|
||||
if !config.get("beef.http.web_server_imitation.enable")
|
||||
BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind(
|
||||
"/extensions/admin_ui/media#{config.get("beef.extension.admin_ui.favicon_dir")}/#{config.get("beef.extension.admin_ui.favicon_file_name")}",
|
||||
'/favicon.ico', 'ico')
|
||||
"/extensions/admin_ui/media/images/#{config.get("beef.extension.admin_ui.favicon_file_name")}",
|
||||
'/favicon.ico',
|
||||
'ico')
|
||||
end
|
||||
|
||||
self.build_javascript_ui beef_server
|
||||
|
||||
@@ -60,7 +60,7 @@ module AdminUI
|
||||
path = request.path_info
|
||||
(print_error "path is invalid";return) if not BeEF::Filters.is_valid_path_info?(path)
|
||||
function = @paths[path] || @paths[path + '/'] # check hash for '<path>' and '<path>/'
|
||||
(print_error "path does not exist";return) if function.nil?
|
||||
(print_error "[Admin UI] Path does not exist: #{path}";return) if function.nil?
|
||||
|
||||
# call the relevant mapped function
|
||||
function.call
|
||||
@@ -86,17 +86,17 @@ module AdminUI
|
||||
|
||||
# Constructs a html script tag (from media/javascript directory)
|
||||
def script_tag(filename)
|
||||
"<script src=\"#{$url}#{@bp}/media/javascript/#{filename}\" type=\"text/javascript\"></script>"
|
||||
"<script src=\"#{@bp}/media/javascript/#{filename}\" type=\"text/javascript\"></script>"
|
||||
end
|
||||
|
||||
# Constructs a html script tag (from media/javascript-min directory)
|
||||
def script_tag_min(filename)
|
||||
"<script src=\"#{$url}#{@bp}/media/javascript-min/#{filename}\" type=\"text/javascript\"></script>"
|
||||
"<script src=\"#{@bp}/media/javascript-min/#{filename}\" type=\"text/javascript\"></script>"
|
||||
end
|
||||
|
||||
# Constructs a html stylesheet tag
|
||||
def stylesheet_tag(filename)
|
||||
"<link rel=\"stylesheet\" href=\"#{$url}#{@bp}/media/css/#{filename}\" type=\"text/css\" />"
|
||||
"<link rel=\"stylesheet\" href=\"#{@bp}/media/css/#{filename}\" type=\"text/css\" />"
|
||||
end
|
||||
|
||||
# Constructs a hidden html nonce tag
|
||||
|
||||
@@ -90,7 +90,6 @@ class Session
|
||||
# Check if a session valid
|
||||
#
|
||||
def valid_session?(request)
|
||||
|
||||
# check if a valid session exists
|
||||
return false if @id.nil?
|
||||
return false if @ip.nil?
|
||||
@@ -99,7 +98,7 @@ class Session
|
||||
return false if not @ip.to_s.eql? request.ip
|
||||
|
||||
# get session cookie name from config
|
||||
session_cookie_name = BeEF::Core::Configuration.instance.get('beef.http.session_cookie_name')
|
||||
session_cookie_name = BeEF::Core::Configuration.instance.get('beef.extension.admin_ui.session_cookie_name')
|
||||
|
||||
# check session id matches
|
||||
request.cookies.each{|cookie|
|
||||
@@ -110,9 +109,7 @@ class Session
|
||||
# not a valid session
|
||||
false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,13 +9,13 @@ beef:
|
||||
name: 'Admin UI'
|
||||
enable: false
|
||||
|
||||
# Admin UI base path
|
||||
base_path: "/ui"
|
||||
|
||||
# Favicon
|
||||
favicon_file_name: "favicon.ico"
|
||||
favicon_dir: "/images"
|
||||
|
||||
# Authentication and authorisation
|
||||
session_cookie_name: "BEEFSESSION"
|
||||
login_fail_delay: 1
|
||||
play_sound_on_new_zombie: false
|
||||
|
||||
# Admin UI
|
||||
base_path: "/ui"
|
||||
favicon_file_name: "favicon.ico"
|
||||
play_sound_on_new_zombie: false
|
||||
panel_update_interval: 10 # seconds
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 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 AdminUI
|
||||
module Constants
|
||||
|
||||
# The User Agent strings for browser detection
|
||||
module Agents
|
||||
|
||||
AGENT_UNKNOWN_IMG = 'unknown.png'
|
||||
AGENT_FIREFOX_UA_STR = 'Firefox'
|
||||
AGENT_FIREFOX_IMG = 'firefox.png'
|
||||
AGENT_MOZILLA_UA_STR = 'Mozilla'
|
||||
AGENT_MOZILLA_IMG = 'mozilla.png'
|
||||
AGENT_IE_UA_STR = 'MSIE'
|
||||
AGENT_IE_IMG = 'msie.png'
|
||||
AGENT_EDGE_UA_STR = 'Edge'
|
||||
AGENT_EDGE_IMG = 'edge.png'
|
||||
AGENT_EPIPHANY_UA_STR = 'Epiphany'
|
||||
AGENT_EPIPHANY_IMG = 'epiphany.png'
|
||||
AGENT_SAFARI_UA_STR = 'Safari'
|
||||
AGENT_SAFARI_IMG = 'safari.png'
|
||||
AGENT_KONQ_UA_STR = 'Konqueror'
|
||||
AGENT_KONQ_IMG = 'konqueror.png'
|
||||
AGENT_CHROME_UA_STR = 'Chrome'
|
||||
AGENT_CHROME_IMG = 'chrome.png'
|
||||
AGENT_OPERA_UA_STR = 'Opera'
|
||||
AGENT_OPERA_IMG = 'opera.ico'
|
||||
AGENT_MIDORI_UA_STR = 'Midori'
|
||||
AGENT_MIDORI_IMG = 'midori.png'
|
||||
AGENT_ODYSSEY_UA_STR = 'Odyssey Web Browser'
|
||||
AGENT_ODYSSEY_IMG = 'odyssey.png'
|
||||
AGENT_BRAVE_UA_STR = 'brave'
|
||||
AGENT_BRAVE_IMG = 'brave.png'
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -70,7 +70,7 @@ class Authentication < BeEF::Extension::AdminUI::HttpController
|
||||
@session.set_logged_in(ua_ip)
|
||||
|
||||
# create session cookie
|
||||
session_cookie_name = config.get('beef.http.session_cookie_name') # get session cookie name
|
||||
session_cookie_name = config.get('beef.extension.admin_ui.session_cookie_name') # get session cookie name
|
||||
Rack::Utils.set_cookie_header!(@headers, session_cookie_name, {:value => @session.get_id, :path => "/", :httponly => true})
|
||||
|
||||
BeEF::Core::Logger.instance.register('Authentication', "User with ip #{@request.ip} has successfully authenticated in the application.")
|
||||
@@ -94,7 +94,7 @@ class Authentication < BeEF::Extension::AdminUI::HttpController
|
||||
|
||||
# clean up UA and expire the session cookie
|
||||
config = BeEF::Core::Configuration.instance
|
||||
session_cookie_name = config.get('beef.http.session_cookie_name') # get session cookie name
|
||||
session_cookie_name = config.get('beef.extension.admin_ui.session_cookie_name') # get session cookie name
|
||||
Rack::Utils.set_cookie_header!(@headers, session_cookie_name, {:value => "", :path => "/", :httponly => true, expires: Time.now})
|
||||
|
||||
BeEF::Core::Logger.instance.register('Authentication', "User with ip #{@request.ip} has successfully logged out.")
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
<%= script_tag 'ext-base.js' %>
|
||||
<%= script_tag 'ext-all.js' %>
|
||||
<%= script_tag 'vis.js/vis.min.js' %>
|
||||
<%= script_tag_min 'web_ui_all.js' %>
|
||||
<%= stylesheet_tag 'wterm.css' %>
|
||||
<%= stylesheet_tag 'ext-all.css' %>
|
||||
|
||||
@@ -7,113 +7,21 @@ module BeEF
|
||||
module Extension
|
||||
module AdminUI
|
||||
module Controllers
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
class Panel < BeEF::Extension::AdminUI::HttpController
|
||||
|
||||
def initialize
|
||||
super({
|
||||
'paths' => {
|
||||
'/' => method(:index),
|
||||
'/hooked-browser-tree-update.json' => method(:hooked_browser_tree_update)
|
||||
}
|
||||
})
|
||||
'paths' => {
|
||||
'/' => method(:index)
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
# default index page
|
||||
def index
|
||||
@headers['X-Frame-Options']='sameorigin'
|
||||
end
|
||||
|
||||
# return a JSON object contains all the updates for the hooked browser trees
|
||||
def hooked_browser_tree_update
|
||||
# retrieve the hbs that are online
|
||||
hooked_browsers_online = zombies2json_simple(BeEF::Core::Models::HookedBrowser.all(:lastseen.gte => (Time.new.to_i - 30)))
|
||||
|
||||
# retrieve the hbs that are offline
|
||||
hooked_browsers_offline = zombies2json_simple(BeEF::Core::Models::HookedBrowser.all(:lastseen.lt => (Time.new.to_i - 30)))
|
||||
|
||||
# retrieve the distributed engine rules that are enabled
|
||||
distributed_engine_rules = distributed_engine_rules_2_json_simple(BeEF::Core::DistributedEngine::Models::Rules.all(:enabled => true))
|
||||
|
||||
# hash that gets populated with all the information for the hb trees
|
||||
ret = {
|
||||
'success' => true,
|
||||
|
||||
# the list of hb
|
||||
'hooked-browsers' => {
|
||||
'online' => hooked_browsers_online,
|
||||
'offline' => hooked_browsers_offline
|
||||
},
|
||||
|
||||
# the rules for the distributed engine
|
||||
'distributed-engine-rules' => distributed_engine_rules
|
||||
}
|
||||
|
||||
@body = ret.to_json
|
||||
end
|
||||
|
||||
# Takes a list distributed engine rules and format the results into JSON
|
||||
def distributed_engine_rules_2_json_simple(rules)
|
||||
|
||||
end
|
||||
|
||||
# Takes a list of zombies and format the results in a JSON array.
|
||||
def zombies2json_simple(zombies)
|
||||
zombies_hash = {}
|
||||
i = 0
|
||||
|
||||
zombies.each do |zombie|
|
||||
# create hash of zombie details
|
||||
zombies_hash[i] = (get_simple_hooked_browser_hash(zombie))
|
||||
i+=1
|
||||
end
|
||||
|
||||
zombies_hash
|
||||
end
|
||||
|
||||
# create a hash of simple hooked browser details
|
||||
def get_simple_hooked_browser_hash(hooked_browser)
|
||||
|
||||
browser_name = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'BrowserName')
|
||||
browser_version = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'BrowserVersion')
|
||||
os_name = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'OsName')
|
||||
hw_name = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'Hardware')
|
||||
domain = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HostName')
|
||||
has_flash = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasFlash')
|
||||
has_web_sockets = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasWebSocket')
|
||||
has_webrtc = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasWebRTC')
|
||||
has_activex = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasActiveX')
|
||||
date_stamp = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'DateStamp')
|
||||
city = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'LocationCity')
|
||||
country = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'LocationCountry')
|
||||
country_code = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'LocationCountryIsoCode')
|
||||
|
||||
return {
|
||||
'session' => hooked_browser.session,
|
||||
'ip' => hooked_browser.ip,
|
||||
'domain' => domain,
|
||||
'port' => hooked_browser.port.to_s,
|
||||
'browser_name' => browser_name,
|
||||
'browser_version' => browser_version,
|
||||
'os_name' => os_name,
|
||||
'hw_name' => hw_name,
|
||||
'has_flash' => has_flash,
|
||||
'has_web_sockets' => has_web_sockets,
|
||||
'has_webrtc' => has_webrtc,
|
||||
'has_activex' => has_activex,
|
||||
'date_stamp' => date_stamp,
|
||||
'city' => city,
|
||||
'country' => country,
|
||||
'country_code' => country_code,
|
||||
'hb_id' => hooked_browser.id
|
||||
}
|
||||
|
||||
@headers['X-Frame-Options'] = 'sameorigin'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,21 +6,16 @@
|
||||
module BeEF
|
||||
module Extension
|
||||
module AdminUI
|
||||
|
||||
extend BeEF::API::Extension
|
||||
|
||||
@full_name = 'administration web UI'
|
||||
|
||||
@full_name = 'Administration Web UI'
|
||||
@short_name = 'admin_ui'
|
||||
|
||||
@description = 'command control panel for beef using a web interface'
|
||||
|
||||
@description = 'Command and control web interface'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Constants for that extension
|
||||
require 'extensions/admin_ui/constants/agents'
|
||||
# Constants
|
||||
require 'extensions/admin_ui/constants/icons'
|
||||
|
||||
# Classes
|
||||
@@ -31,5 +26,4 @@ require 'extensions/admin_ui/classes/session'
|
||||
require 'extensions/admin_ui/handlers/ui'
|
||||
|
||||
# API Hooking
|
||||
require 'extensions/admin_ui/api/command'
|
||||
require 'extensions/admin_ui/api/handler'
|
||||
|
||||
@@ -103,41 +103,6 @@ if(typeof beefwui === 'undefined' && typeof window.beefwui === 'undefined') {
|
||||
});
|
||||
console.log(info);
|
||||
return info;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Get hooked browser info from ID
|
||||
*/
|
||||
get_fullinfo_from_id: function(id) {
|
||||
var info = {};
|
||||
$jwterm.ajax({
|
||||
type: 'POST',
|
||||
url: "<%= @base_path %>/panel/hooked-browser-tree-update.json",
|
||||
async: false,
|
||||
processData: false,
|
||||
success: function(data){
|
||||
for (var k in data['hooked-browsers']['online']) {
|
||||
if (data['hooked-browsers']['online'][k].id === id) {
|
||||
info = data['hooked-browsers']['online'][k];
|
||||
}
|
||||
}
|
||||
|
||||
if ($jwterm.isEmptyObject(info)) {
|
||||
for (var k in data['hooked-browsers']['offline']) {
|
||||
if (data['hooked-browsers']['offline'][k].id === id) {
|
||||
info = data['hooked-browsers']['offline'][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
error: function(){
|
||||
commands_statusbar.update_fail("Error getting hb ip");
|
||||
}
|
||||
});
|
||||
console.log(info);
|
||||
return info;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
/*
|
||||
* RULES TYPE
|
||||
* - DOMAIN : DOMAIN www.zzz.com
|
||||
* - EXTERNAL : EXTERNAL 123.456.789.123
|
||||
* - INTERNAL : INTERNAL 10.0.0.3
|
||||
*/
|
||||
DistributedEngine = function() {
|
||||
//defines the constant code to match with the backend ruby
|
||||
this.CONSTANTS = {
|
||||
'requester' : 1,
|
||||
'portscanner' : 2
|
||||
};
|
||||
|
||||
/*
|
||||
* Returns true of the hooked browser matches one of the rules and should be checked.
|
||||
* @param: {Literal Object} the browser object.
|
||||
* @param: {Literal Object} the rule set object.
|
||||
* @return: {Boolean} true if matches, false if not.
|
||||
*/
|
||||
this.HookedBrowserMatchesRules = function(hooked_browser, rules) {
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* Disable an existing rule in the framework. That function is called when the user
|
||||
* unchecks a hooked browser.
|
||||
* @param: {Integer} the id of the rule.
|
||||
*/
|
||||
this.DisableRule = function(rule_id) {
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates and sends a new rule to the backend.
|
||||
*/
|
||||
this.CreateNewRule = function() {
|
||||
|
||||
};
|
||||
};
|
||||
@@ -39,16 +39,17 @@ Ext.onReady(function() {
|
||||
/*
|
||||
* Panel Events Updater
|
||||
*
|
||||
* This event updater retrieves updates every 8 seconds. Those updates
|
||||
* are then pushed to various managers (i.e. the zombie manager).
|
||||
* This event updater retrieves zombie updates every periodically.
|
||||
* The poll timer is specified in befe.extension.admin_ui.panel_update_interval
|
||||
* These updates are then pushed to various managers (i.e. the zombie manager).
|
||||
*/
|
||||
var lastpoll = new Date().getTime();
|
||||
|
||||
Ext.TaskMgr.start({
|
||||
run: function() {
|
||||
Ext.Ajax.request({
|
||||
url: '<%= @base_path %>/panel/hooked-browser-tree-update.json',
|
||||
method: 'POST',
|
||||
url: '/api/hooks/?token=' + beefwui.get_rest_token(),
|
||||
method: 'GET',
|
||||
success: function(response) {
|
||||
var updates;
|
||||
try {
|
||||
@@ -58,12 +59,10 @@ Ext.TaskMgr.start({
|
||||
var hr = document.getElementById("header-right");
|
||||
hr.innerHTML = "You appear to be logged out. <a href='<%= @base_path %>/panel/'>Login</a>";
|
||||
}
|
||||
var distributed_engine_rules = (updates['distributed-engine-rules']) ? updates['distributed-engine-rules'] : null;
|
||||
beefwui.hooked_browsers = (updates['hooked-browsers']); //? updates['hooked-browsers'] : null;
|
||||
var hooked_browsers = (updates['hooked-browsers']) ? updates['hooked-browsers'] : null;
|
||||
|
||||
if(zombiesManager && hooked_browsers) {
|
||||
zombiesManager.updateZombies(hooked_browsers, distributed_engine_rules);
|
||||
zombiesManager.updateZombies(hooked_browsers);
|
||||
}
|
||||
lastpoll = new Date().getTime();
|
||||
var hr = document.getElementById("header-right");
|
||||
@@ -80,5 +79,5 @@ Ext.TaskMgr.start({
|
||||
});
|
||||
},
|
||||
|
||||
interval: 8000
|
||||
interval: <%= (BeEF::Core::Configuration.instance.get("beef.extension.admin_ui.panel_update_interval") || 10).to_i * 1_000 %>
|
||||
});
|
||||
|
||||
@@ -14,10 +14,11 @@ var ZombiesMgr = function(zombies_tree_lists) {
|
||||
|
||||
var ip = zombie_array[index]["ip"];
|
||||
var session = zombie_array[index]["session"];
|
||||
var browser_name = zombie_array[index]["browser_name"];
|
||||
var browser_version = zombie_array[index]["browser_version"];
|
||||
var os_name = zombie_array[index]["os_name"];
|
||||
var hw_name = zombie_array[index]["hw_name"];
|
||||
var browser_name = zombie_array[index]["name"];
|
||||
var browser_version = zombie_array[index]["version"];
|
||||
var os_name = zombie_array[index]["os"];
|
||||
var os_version = zombie_array[index]["os_version"];
|
||||
var hardware = zombie_array[index]["hardware"];
|
||||
var domain = zombie_array[index]["domain"];
|
||||
var port = zombie_array[index]["port"];
|
||||
var city = zombie_array[index]["city"];
|
||||
@@ -35,7 +36,8 @@ var ZombiesMgr = function(zombies_tree_lists) {
|
||||
'browser_name': browser_name,
|
||||
'browser_version': browser_version,
|
||||
'os_name': os_name,
|
||||
'hw_name': hw_name,
|
||||
'os_version': os_version,
|
||||
'hw_name': hardware,
|
||||
'city': city,
|
||||
'country': country,
|
||||
'country_code': country_code,
|
||||
@@ -48,9 +50,8 @@ var ZombiesMgr = function(zombies_tree_lists) {
|
||||
/*
|
||||
* Update the hooked browser trees
|
||||
* @param: {Literal Object} an object containing the list of offline and online hooked browsers.
|
||||
* @param: {Literal Object} an object containing the list of rules from the distributed engine.
|
||||
*/
|
||||
this.updateZombies = function(zombies, rules){
|
||||
this.updateZombies = function(zombies){
|
||||
var offline_hooked_browsers = zombies["offline"];
|
||||
var online_hooked_browsers = zombies["online"];
|
||||
beefwui.hooked_browsers = zombies["online"];
|
||||
@@ -73,9 +74,6 @@ var ZombiesMgr = function(zombies_tree_lists) {
|
||||
hooked_browsers_tree.addZombie(online_hooked_browser, true, ((tree_type != 'basic') ? true : false));
|
||||
}
|
||||
|
||||
//apply the rules to the tree
|
||||
hooked_browsers_tree.applyRules(rules);
|
||||
|
||||
//expand the online hooked browser tree lists
|
||||
if(hooked_browsers_tree.online_hooked_browsers_treenode.childNodes.length > 0) {
|
||||
hooked_browsers_tree.online_hooked_browsers_treenode.expand(true);
|
||||
|
||||
@@ -54,8 +54,7 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, {
|
||||
|
||||
//saves the configuration for the tree
|
||||
tree_configuration: {
|
||||
'sub-branch' : 'domain',
|
||||
'distributed' : false
|
||||
'sub-branch' : 'domain'
|
||||
},
|
||||
|
||||
|
||||
@@ -65,9 +64,6 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, {
|
||||
//store the list of offline hooked browsers in an array
|
||||
offline_hooked_browsers_array: new Array,
|
||||
|
||||
//store the distributed engine rules
|
||||
distributed_engine_rules: null,
|
||||
|
||||
//add a context menu that will contain common action shortcuts for HBs
|
||||
contextMenu: new Ext.menu.Menu({
|
||||
items: [{
|
||||
@@ -470,7 +466,11 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, {
|
||||
balloon_text += "Browser: " + hooked_browser.browser_name + " " + hooked_browser.browser_version;
|
||||
balloon_text += "<br/>";
|
||||
balloon_text += " <img width='13px' height='13px' class='zombie-tree-icon' src='<%= @base_path %>/media/images/icons/" + escape(os_icon) + "' /> ";
|
||||
balloon_text += "OS: " + hooked_browser.os_name;
|
||||
if (hooked_browser.os_version == 'Unknown') {
|
||||
balloon_text += "OS: " + hooked_browser.os_name;
|
||||
} else {
|
||||
balloon_text += "OS: " + hooked_browser.os_name + ' ' + hooked_browser.os_version;
|
||||
}
|
||||
balloon_text += "<br/>";
|
||||
balloon_text += " <img width='13px' height='13px' class='zombie-tree-icon' src='<%= @base_path %>/media/images/icons/" + escape(hw_icon) + "' /> ";
|
||||
balloon_text += "Hardware: " + hooked_browser.hw_name;
|
||||
@@ -657,14 +657,4 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, {
|
||||
this.reload();
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Apply a new set of distributed engine rules to the nodes in the tree
|
||||
* @param: {Literal Objects} the rules set. See the zombie manager.
|
||||
*/
|
||||
applyRules: function(rules) {
|
||||
//we return if the tree is not distributed
|
||||
if(!this.tree_configuration["distributed"]) return;
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user