diff --git a/core/core.rb b/core/core.rb index dc554314b..6dcff13f2 100644 --- a/core/core.rb +++ b/core/core.rb @@ -34,6 +34,7 @@ require 'core/main/constants/browsers' require 'core/main/constants/commandmodule' require 'core/main/constants/distributedengine' require 'core/main/constants/os' +require 'core/main/constants/hardware' # @note Include core modules for beef require 'core/main/configuration' diff --git a/core/filters/browser.rb b/core/filters/browser.rb index f955fb6f6..7dbcfdfc6 100644 --- a/core/filters/browser.rb +++ b/core/filters/browser.rb @@ -47,6 +47,16 @@ module Filters true end + # Check the Hardware name value - for example, 'iPhone' + # @param [String] str String for testing + # @return [Boolean] If the string has valid Hardware name characters + def self.is_valid_hwname?(str) + return false if not is_non_empty_string?(str) + return false if has_non_printable_char?(str) + return false if str.length < 2 + true + end + # Verify the browser version string is valid # @param [String] str String for testing # @return [Boolean] If the string has valid browser version characters diff --git a/core/main/client/browser.js b/core/main/client/browser.js index 762072108..9a243aad4 100644 --- a/core/main/client/browser.js +++ b/core/main/client/browser.js @@ -765,6 +765,7 @@ beef.browser = { var browser_plugins = beef.browser.getPlugins(); var date_stamp = new Date().toString(); var os_name = beef.os.getName(); + var hw_name = beef.hardware.getName(); var system_platform = (typeof(navigator.platform) != "undefined" && navigator.platform != "") ? navigator.platform : null; var browser_type = JSON.stringify(beef.browser.type(), function (key, value) {if (value == true) return value; else if (typeof value == 'object') return value; else return;}); var screen_size = beef.browser.getScreenSize(); @@ -789,6 +790,7 @@ beef.browser = { if(hostport) details["HostPort"] = hostport; if(browser_plugins) details["BrowserPlugins"] = browser_plugins; if(os_name) details['OsName'] = os_name; + if(hw_name) details['Hardware'] = hw_name; if(date_stamp) details['DateStamp'] = date_stamp; if(system_platform) details['SystemPlatform'] = system_platform; if(browser_type) details['BrowserType'] = browser_type; diff --git a/core/main/client/hardware.js b/core/main/client/hardware.js new file mode 100644 index 000000000..f498c53ac --- /dev/null +++ b/core/main/client/hardware.js @@ -0,0 +1,74 @@ +// +// Copyright 2012 Wade Alcorn wade@bindshell.net +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +beef.hardware = { + + ua: navigator.userAgent, + + isWinPhone: function() { + return (this.ua.match('(Windows Phone)')) ? true : false; + }, + + isIphone: function() { + return (this.ua.indexOf('iPhone') != -1) ? true : false; + }, + + isIpad: function() { + return (this.ua.indexOf('iPad') != -1) ? true : false; + }, + + isIpod: function() { + return (this.ua.indexOf('iPod') != -1) ? true : false; + }, + + isNokia: function() { + return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)')) ? true : false; + }, + + isBlackBerry: function() { + return (this.ua.match('BlackBerry')) ? true : false; + }, + + isZune: function() { + return (this.ua.match('ZuneWP7')) ? true : false; + }, + + isKindle: function() { + return (this.ua.match('Kindle')) ? true : false; + }, + + getName: function() { + + if(this.isNokia()) { + + if (this.ua.indexOf('Maemo Browser') != -1) return 'Maemo'; + if (this.ua.match('(SymbianOS)|(Symbian OS)')) return 'SymbianOS'; + if (this.ua.indexOf('Symbian') != -1) return 'Symbian'; + + //return 'Nokia'; + } + + if (this.isWinPhone()) return 'Windows Phone'; + if (this.isBlackBerry()) return 'BlackBerry'; + if (this.isIphone()) return 'iPhone'; + if (this.isIpad()) return 'iPad'; + if (this.isIpod()) return 'iPod'; + if (this.isKindle()) return 'Kindle'; + + return 'unknown'; + } +}; + +beef.regCmp('beef.net.hardware'); diff --git a/core/main/client/os.js b/core/main/client/os.js index c133edcc9..9ccea8a9c 100644 --- a/core/main/client/os.js +++ b/core/main/client/os.js @@ -72,7 +72,11 @@ beef.os = { isMacintosh: function() { return (this.ua.match('(Mac_PowerPC)|(Macintosh)|(MacIntel)')) ? true : false; }, - + + isWinPhone: function() { + return (this.ua.match('(Windows Phone)')) ? true : false; + }, + isIphone: function() { return (this.ua.indexOf('iPhone') != -1) ? true : false; }, @@ -97,6 +101,10 @@ beef.os = { return (this.ua.match('BlackBerry')) ? true : false; }, + isWebOS: function() { + return (this.ua.match('webOS')) ? true : false; + }, + isQNX: function() { return (this.ua.match('QNX')) ? true : false; }, @@ -139,11 +147,14 @@ beef.os = { if(this.isSunOS()) return 'Sun OS'; //iPhone - if (this.isIphone()) return 'iPhone'; + if (this.isIphone()) return 'iOS'; //iPad - if (this.isIpad()) return 'iPad'; + if (this.isIpad()) return 'iOS'; //iPod - if (this.isIpod()) return 'iPod'; + if (this.isIpod()) return 'iOS'; + + // zune + //if (this.isZune()) return 'Zune'; //macintosh if(this.isMacintosh()) { @@ -156,6 +167,7 @@ beef.os = { //others if(this.isQNX()) return 'QNX'; if(this.isBeOS()) return 'BeOS'; + if(this.isWebOS()) return 'webOS'; return 'unknown'; } diff --git a/core/main/constants/hardware.rb b/core/main/constants/hardware.rb new file mode 100644 index 000000000..63958a210 --- /dev/null +++ b/core/main/constants/hardware.rb @@ -0,0 +1,73 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +module BeEF +module Core +module Constants + + # @note The hardware's strings for hardware detection. + module Hardware + + HW_UNKNOWN_IMG = 'pc.png' + HW_IPHONE_UA_STR = 'iPhone' + HW_IPHONE_IMG = 'iphone.jpg' + HW_IPAD_UA_STR = 'iPad' + HW_IPAD_IMG = 'ipad.png' + HW_IPOD_UA_STR = 'iPod' + HW_IPOD_IMG = 'ipod.jpg' + HW_BLACKBERRY_UA_STR = 'BlackBerry' + HW_BLACKBERRY_IMG = 'blackberry.png' + HW_ANDROID_UA_STR = 'Android' + HW_ANDROID_IMG = 'android.png' + HW_WINPHONE_UA_STR = 'Windows Phone' + HW_WINPHONE_IMG = 'win.png' + HW_ZUNE_UA_STR = 'ZuneWP7' + HW_ZUNE_IMG = 'zune.gif' + HW_KINDLE_UA_STR = 'Kindle' + HW_KINDLE_IMG = 'kindle.png' + HW_ALL_UA_STR = 'All' + + # Attempt to match operating system string to constant + # @param [String] name Name of operating system + # @return [String] Constant name of matched operating system, returns 'ALL' if nothing are matched + def self.match_hardware(name) + case name.downcase + when /iphone/ + HW_IPHONE_UA_STR + when /ipad/ + HW_IPAD_UA_STR + when /ipod/ + HW_IPOD_UA_STR + when /blackberry/ + HW_BLACKBERRY_UA_STR + when /android/ + HW_ANDROID_UA_STR + when /windows phone/ + HW_WINPHONE_UA_STR + when /zune/ + HW_ZUNE_UA_STR + when /kindle/ + HW_KINDLE_UA_STR + else + 'ALL' + end + end + + end + +end +end +end diff --git a/core/main/constants/os.rb b/core/main/constants/os.rb index 2e86f1e39..15c8a1b67 100644 --- a/core/main/constants/os.rb +++ b/core/main/constants/os.rb @@ -29,17 +29,19 @@ module Constants OS_MAC_UA_STR = 'Mac' OS_MAC_IMG = 'mac.png' OS_QNX_UA_STR = 'QNX' - OS_QNX_IMG = 'qnx.ico' + OS_QNX_IMG = 'qnx.ico' OS_BEOS_UA_STR = 'BeOS' - OS_BEOS_IMG = 'beos.png' + OS_BEOS_IMG = 'beos.png' OS_OPENBSD_UA_STR = 'OpenBSD' OS_OPENBSD_IMG = 'openbsd.ico' + OS_IOS_UA_STR = 'iOS' + OS_IOS_IMG = 'ios.png' OS_IPHONE_UA_STR = 'iPhone' - OS_IPHONE_IMG = 'iphone.png' + OS_IPHONE_IMG = 'iphone.jpg' OS_IPAD_UA_STR = 'iPad' - OS_IPAD_IMG = 'ipad.png' + OS_IPAD_IMG = 'ipad.png' OS_IPOD_UA_STR = 'iPod' - OS_IPOD_IMG = 'ipod.jpg' + OS_IPOD_IMG = 'ipod.jpg' OS_MAEMO_UA_STR = 'Maemo' OS_MAEMO_IMG = 'maemo.ico' OS_BLACKBERRY_UA_STR = 'BlackBerry' @@ -65,12 +67,8 @@ module Constants OS_BEOS_UA_STR when /openbsd/ OS_OPENBSD_UA_STR - when /iphone/ - OS_IPHONE_UA_STR - when /ipad/ - OS_IPAD_UA_STR - when /ipod/ - OS_IPOD_UA_STR + when /ios/, /iphone/, /ipad/, /ipod/ + OS_IOS_UA_STR when /maemo/ OS_MAEMO_UA_STR when /blackberry/ diff --git a/core/main/handlers/browserdetails.rb b/core/main/handlers/browserdetails.rb index dfb3b8040..1ca83f165 100644 --- a/core/main/handlers/browserdetails.rb +++ b/core/main/handlers/browserdetails.rb @@ -118,6 +118,14 @@ module BeEF self.err_msg "Invalid operating system name returned from the hook browser's initial connection." end + # 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) + else + self.err_msg "Invalid hardware name returned from the hook browser's initial connection." + end + # get and store the date date_stamp = get_param(@data['results'], 'DateStamp') if BeEF::Filters.is_valid_date_stamp?(date_stamp) diff --git a/core/main/handlers/modules/beefjs.rb b/core/main/handlers/modules/beefjs.rb index 92473876d..b7ca90bae 100644 --- a/core/main/handlers/modules/beefjs.rb +++ b/core/main/handlers/modules/beefjs.rb @@ -32,9 +32,9 @@ module Modules # @note we load websocket library only if ws server is enabled in config.yalm # check in init.js if config.get("beef.http.websocket.enable") - js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js beef.js browser.js browser/cookie.js browser/popup.js session.js os.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js websocket.js) + js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js websocket.js) else - js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js beef.js browser.js browser/cookie.js browser/popup.js session.js os.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js) + js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js) end # @note construct the beefjs string from file(s) diff --git a/core/main/models/browserdetails.rb b/core/main/models/browserdetails.rb index 8a8f79c61..ae3868691 100644 --- a/core/main/models/browserdetails.rb +++ b/core/main/models/browserdetails.rb @@ -94,9 +94,10 @@ module Models return BeEF::Core::Constants::Os::OS_QNX_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_QNX_UA_STR return BeEF::Core::Constants::Os::OS_BEOS_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_BEOS_UA_STR return BeEF::Core::Constants::Os::OS_OPENBSD_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_OPENBSD_UA_STR - return BeEF::Core::Constants::Os::OS_IPHONE_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_IPHONE_UA_STR - return BeEF::Core::Constants::Os::OS_IPAD_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_IPAD_UA_STR - return BeEF::Core::Constants::Os::OS_IPOD_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_IPOD_UA_STR + return BeEF::Core::Constants::Os::OS_WEBOS_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_WEBOS_UA_STR + return BeEF::Core::Constants::Os::OS_IOS_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_IPHONE_UA_STR + return BeEF::Core::Constants::Os::OS_IOS_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_IPAD_UA_STR + return BeEF::Core::Constants::Os::OS_IOS_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_IPOD_UA_STR return BeEF::Core::Constants::Os::OS_MAEMO_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_MAEMO_UA_STR return BeEF::Core::Constants::Os::OS_MAC_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_MAC_UA_STR return BeEF::Core::Constants::Os::OS_BLACKBERRY_IMG if ua_string.include? BeEF::Core::Constants::Os::OS_BLACKBERRY_UA_STR @@ -105,6 +106,26 @@ module Models BeEF::Core::Constants::Os::OS_UNKNOWN_IMG end + # + # Returns the icon representing the hardware the + # zombie is running on (i.e. iPhone, BlackBerry) + # + def self.hw_icon(session_id) + + ua_string = get(session_id, 'BrowserReportedName') + + return BeEF::Core::Constants::Hardware::HW_UNKNOWN_IMG if ua_string.nil? + + return BeEF::Core::Constants::Hardware::HW_WINPHONE_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_WINPHONE_UA_STR + return BeEF::Core::Constants::Hardware::HW_ZUNE_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_ZUNE_UA_STR + return BeEF::Core::Constants::Hardware::HW_IPHONE_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_IPHONE_UA_STR + return BeEF::Core::Constants::Hardware::HW_IPAD_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_IPAD_UA_STR + return BeEF::Core::Constants::Hardware::HW_IPOD_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_IPOD_UA_STR + + BeEF::Core::Constants::Hardware::HW_UNKNOWN_IMG + + end + end end diff --git a/extensions/admin_ui/controllers/modules/modules.rb b/extensions/admin_ui/controllers/modules/modules.rb index b30573a0d..827f6c241 100644 --- a/extensions/admin_ui/controllers/modules/modules.rb +++ b/extensions/admin_ui/controllers/modules/modules.rb @@ -136,7 +136,7 @@ class Modules < BeEF::Extension::AdminUI::HttpController # set and add the return values for the os name os_name = BD.get(zombie_session, 'OsName') - if not host_name.nil? + if not os_name.nil? encoded_os_name = CGI.escapeHTML(os_name) encoded_os_name_hash = { 'OS Name' => encoded_os_name } @@ -148,6 +148,21 @@ class Modules < BeEF::Extension::AdminUI::HttpController summary_grid_hash['results'].push(page_name_row) # add the row end + + # set and add the return values for the hardware name + hw_name = BD.get(zombie_session, 'Hardware') + if not hw_name.nil? + encoded_hw_name = CGI.escapeHTML(hw_name) + encoded_hw_name_hash = { 'Hardware' => encoded_hw_name } + + page_name_row = { + 'category' => 'Host', + 'data' => encoded_hw_name_hash, + 'from' => 'Initialization' + } + + summary_grid_hash['results'].push(page_name_row) # add the row + end # set and add the return values for the browser name browser_name = BD.get(zombie_session, 'BrowserName') diff --git a/extensions/admin_ui/controllers/panel/panel.rb b/extensions/admin_ui/controllers/panel/panel.rb index c67ec41f7..56b6a708c 100644 --- a/extensions/admin_ui/controllers/panel/panel.rb +++ b/extensions/admin_ui/controllers/panel/panel.rb @@ -90,10 +90,12 @@ class Panel < BeEF::Extension::AdminUI::HttpController browser_icon = BeEF::Core::Models::BrowserDetails.browser_icon(hooked_browser.session) os_icon = BeEF::Core::Models::BrowserDetails.os_icon(hooked_browser.session) os_name = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'OsName') + hw_icon = BeEF::Core::Models::BrowserDetails.hw_icon(hooked_browser.session) + hw_name = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'Hardware') domain = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HostName') has_flash = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasFlash') has_web_sockets = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasWebSocket') - date_stamp = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'DateStamp') + date_stamp = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'DateStamp') return { 'session' => hooked_browser.session, @@ -105,6 +107,8 @@ class Panel < BeEF::Extension::AdminUI::HttpController 'browser_icon' => browser_icon, 'os_icon' => os_icon, 'os_name' => os_name, + 'hw_icon' => hw_icon, + 'hw_name' => hw_name, 'has_flash' => has_flash, 'has_web_sockets' => has_web_sockets, 'date_stamp' => date_stamp diff --git a/extensions/admin_ui/media/images/icons/ios.png b/extensions/admin_ui/media/images/icons/ios.png new file mode 100644 index 000000000..de94a27ce Binary files /dev/null and b/extensions/admin_ui/media/images/icons/ios.png differ diff --git a/extensions/admin_ui/media/images/icons/iphone.jpg b/extensions/admin_ui/media/images/icons/iphone.jpg new file mode 100644 index 000000000..134b5c9f9 Binary files /dev/null and b/extensions/admin_ui/media/images/icons/iphone.jpg differ diff --git a/extensions/admin_ui/media/images/icons/iphone.png b/extensions/admin_ui/media/images/icons/iphone.png deleted file mode 100644 index ab4a8cc31..000000000 Binary files a/extensions/admin_ui/media/images/icons/iphone.png and /dev/null differ diff --git a/extensions/admin_ui/media/images/icons/kindle.png b/extensions/admin_ui/media/images/icons/kindle.png new file mode 100644 index 000000000..b858fc003 Binary files /dev/null and b/extensions/admin_ui/media/images/icons/kindle.png differ diff --git a/extensions/admin_ui/media/images/icons/pc.png b/extensions/admin_ui/media/images/icons/pc.png new file mode 100644 index 000000000..d8f38aca7 Binary files /dev/null and b/extensions/admin_ui/media/images/icons/pc.png differ diff --git a/extensions/admin_ui/media/images/icons/zune.gif b/extensions/admin_ui/media/images/icons/zune.gif new file mode 100644 index 000000000..6d8259b13 Binary files /dev/null and b/extensions/admin_ui/media/images/icons/zune.gif differ diff --git a/extensions/admin_ui/media/javascript/ui/panel/ZombiesMgr.js b/extensions/admin_ui/media/javascript/ui/panel/ZombiesMgr.js index 964e586a4..6f7d02f50 100644 --- a/extensions/admin_ui/media/javascript/ui/panel/ZombiesMgr.js +++ b/extensions/admin_ui/media/javascript/ui/panel/ZombiesMgr.js @@ -28,6 +28,8 @@ var ZombiesMgr = function(zombies_tree_lists) { var browser_icon = zombie_array[index]["browser_icon"]; var os_icon = zombie_array[index]["os_icon"]; var os_name = zombie_array[index]["os_name"]; + var hw_name = zombie_array[index]["hw_name"]; + var hw_icon = zombie_array[index]["hw_icon"]; var domain = zombie_array[index]["domain"]; var port = zombie_array[index]["port"]; var has_flash = zombie_array[index]["has_flash"]; @@ -36,11 +38,13 @@ var ZombiesMgr = function(zombies_tree_lists) { text = " "; text+= " "; + text+= " "; text+= ip; balloon_text = "IP: "+ip; balloon_text+= "
Browser: " + browser_name + " " + browser_version; balloon_text+= "
System: " + os_name; + balloon_text+= "
Hardware: " + hw_name; balloon_text+= "
Domain: " + domain + ":" + port; balloon_text+= "
Flash: " + has_flash; balloon_text+= "
Web Sockets: " + has_web_sockets; diff --git a/extensions/console/lib/shellinterface.rb b/extensions/console/lib/shellinterface.rb index a896184cb..4251347cd 100644 --- a/extensions/console/lib/shellinterface.rb +++ b/extensions/console/lib/shellinterface.rb @@ -358,6 +358,21 @@ class ShellInterface summary_grid_hash['results'].push(page_name_row) # add the row end + # set and add the return values for the os name + hw_name = BD.get(self.targetsession, 'Hardware') + if not hw_name.nil? + encoded_hw_name = CGI.escapeHTML(hw_name) + encoded_hw_name_hash = { 'Hardware' => encoded_hw_name } + + page_name_row = { + 'category' => 'Host', + 'data' => encoded_hw_name_hash, + 'from' => 'Initialization' + } + + summary_grid_hash['results'].push(page_name_row) # add the row + end + # set and add the return values for the browser name browser_name = BD.get(self.targetsession, 'BrowserName') if not browser_name.nil?