diff --git a/core/main/models/hookedbrowser.rb b/core/main/models/hookedbrowser.rb index 6db0f5cb1..c18113c65 100644 --- a/core/main/models/hookedbrowser.rb +++ b/core/main/models/hookedbrowser.rb @@ -19,6 +19,7 @@ module Models property :domain, Text, :lazy => false # the domain originating the hook request property :count, Integer, :lazy => false property :has_init, Boolean, :default => false + property :is_proxy, Boolean, :default => false # if true the HB is used as a tunneling proxy has n, :commands has n, :results diff --git a/extensions/admin_ui/api/handler.rb b/extensions/admin_ui/api/handler.rb index 3746c4a03..d95059038 100644 --- a/extensions/admin_ui/api/handler.rb +++ b/extensions/admin_ui/api/handler.rb @@ -22,6 +22,7 @@ module API Dir["#{$root_dir}/extensions/admin_ui/controllers/**/*.rb"].each { |http_module| require http_module mod_name = File.basename http_module, '.rb' + print_debug("Registering controller [#{mod_name}] for extension [AdminUI]") beef_server.mount("/ui/#{mod_name}", true, BeEF::Extension::AdminUI::Handlers::UI, mod_name) } diff --git a/extensions/admin_ui/controllers/proxy/proxy.rb b/extensions/admin_ui/controllers/proxy/proxy.rb new file mode 100644 index 000000000..af29903be --- /dev/null +++ b/extensions/admin_ui/controllers/proxy/proxy.rb @@ -0,0 +1,46 @@ +module BeEF +module Extension +module AdminUI +module Controllers + +# +# HTTP Controller for the Proxy component of BeEF. +# +class Proxy < BeEF::Extension::AdminUI::HttpController + + H = BeEF::Core::Models::Http + HB = BeEF::Core::Models::HookedBrowser + + def initialize + super({ + 'paths' => { + '/setTargetZombie' => method(:set_target_zombie) + } + }) + end + + + def set_target_zombie + hb_session_id = @params['hb_id'].to_s + hooked_browser = HB.first(:session => hb_session_id) + previous_proxy_hb = HB.first(:is_proxy => true) + + # if another HB is currently set as tunneling proxy, unset it + if(previous_proxy_hb != nil) + previous_proxy_hb.update(:is_proxy => false) + print_debug("Unsetting previously HB [#{previous_proxy_hb.ip.to_s}] used as Tunneling Proxy") + end + + # set the HB requested in /setTargetProxy as Tunneling Proxy + if(hooked_browser != nil) + hooked_browser.update(:is_proxy => true) + print_info("Using Hooked Browser with ip [#{hooked_browser.ip.to_s}] as Tunneling Proxy") + end + end + +end + +end +end +end +end diff --git a/extensions/admin_ui/media/css/base.css b/extensions/admin_ui/media/css/base.css index 362c09fc5..7e0ddbb14 100644 --- a/extensions/admin_ui/media/css/base.css +++ b/extensions/admin_ui/media/css/base.css @@ -55,6 +55,10 @@ background-image: url(../images/statusbar/accept.png); } +.zombie-tree-ctxMenu-proxy { + background-image: url(../images/icons/proxy.gif); +} + .x-tree-node-leaf .x-tree-node-icon { width: 13px; height: 13px; diff --git a/extensions/admin_ui/media/images/icons/proxy.gif b/extensions/admin_ui/media/images/icons/proxy.gif new file mode 100644 index 000000000..73065f5b5 Binary files /dev/null and b/extensions/admin_ui/media/images/icons/proxy.gif differ diff --git a/extensions/admin_ui/media/javascript/ui/panel/zombiesTreeList.js b/extensions/admin_ui/media/javascript/ui/panel/zombiesTreeList.js index d1428ff68..a945ed1ca 100644 --- a/extensions/admin_ui/media/javascript/ui/panel/zombiesTreeList.js +++ b/extensions/admin_ui/media/javascript/ui/panel/zombiesTreeList.js @@ -57,6 +57,32 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, { //store the distributed engine rules distributed_engine_rules: null, + + //add a context menu that will contain common action shortcuts for HBs + contextMenu: new Ext.menu.Menu({ + items: [{ + id: 'use_as_proxy', + text: 'Use as Proxy', + iconCls: 'zombie-tree-ctxMenu-proxy' + } + ], + listeners: { + itemclick: function(item, object) { + switch (item.id) { + case 'use_as_proxy': + var hb_id = this.contextNode.id.split('zombie-online-')[1]; + Ext.Ajax.request({ + url: '/ui/proxy/setTargetZombie', + method: 'POST', + params: 'hb_id=' + hb_id //, + //success: alert('set target zombie' + hb_id), + //failure: alert('error setting target zombie' + hb_id) + }); + break; + } + } + } + }), listeners: { //creates a new hooked browser tab when a hooked browser is clicked @@ -69,6 +95,16 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, { mainPanel.activate(node.attributes.session); }, + //show the context menu when a HB is right-clicked + contextmenu: function(node, event){ + if(!node.leaf) return; + + node.select(); + var c = node.getOwnerTree().contextMenu; + c.contextNode = node; + c.showAt(event.getXY()); + + }, //update the set of rules when a checkbox is clicked checkchange: function(node, checked) { diff --git a/extensions/proxy/api.rb b/extensions/proxy/api.rb index c8bd2d125..17b5cc3e0 100644 --- a/extensions/proxy/api.rb +++ b/extensions/proxy/api.rb @@ -14,6 +14,10 @@ module API config = BeEF::Core::Configuration.instance print_success "HTTP Proxy: http://#{config.get('beef.extension.proxy.address')}:#{config.get('beef.extension.proxy.port')}" end + + def self.mount_handlers(beef_server) + beef_server.mount('/proxy', false, BeEF::Extension::Events::Handler) + end end diff --git a/extensions/proxy/handlers/zombie/handler.rb b/extensions/proxy/handlers/zombie/handler.rb index 291731184..2f8336b46 100644 --- a/extensions/proxy/handlers/zombie/handler.rb +++ b/extensions/proxy/handlers/zombie/handler.rb @@ -8,7 +8,6 @@ module Zombie # Variable representing the Http DB model. H = BeEF::Core::Models::Http - # This function will forward requests to the zombie and # the browser will perform the request. Then the results # will be sent back to use @@ -41,15 +40,18 @@ module Zombie # Polls the DB for the response and then sets it when present http_db = H.first(:id => http_id) - + while !http_db.has_ran - sleep 1 + #sleep 1 # adding a sleep here is a bottleneck. Even querying in this way is not a good way. + # By the way removing the sleep instead the proxy response time is 8/10 seconds instead of almost 20 seconds. + # This code should be reimplemented with Threading. http_db = H.first(:id => http_id) end - +# res.body = http_db.response - + res + end module_function :forward_request diff --git a/extensions/proxy/zombie.rb b/extensions/proxy/zombie.rb index 102fac1d4..cc565fa2c 100644 --- a/extensions/proxy/zombie.rb +++ b/extensions/proxy/zombie.rb @@ -6,6 +6,8 @@ module Proxy attr_accessor :proxy_zombie_id + HB = BeEF::Core::Models::HookedBrowser + def initialize @configuration = BeEF::Core::Configuration.instance @@ -21,14 +23,13 @@ module Proxy def service(req, res) - # TODO implement which HB to target - if false - return if proxy_zombie_id.nil? # check if zombie is set - zombie = BeEF::Core::Models::Zombie.get(proxy_zombie_id) - return if not zombie # check if zombie is registered with beef - else - proxy_zombie_id = 1 - end + proxy_zombie = HB.first(:is_proxy => true) + if(proxy_zombie != nil) + proxy_zombie_id = proxy_zombie.id.to_s + else + proxy_zombie_id = 1 + print_debug("Defaulting proxy zombie to the first one in the DB") + end # blocking request res = BeEF::Extension::Proxy::Handlers::Zombie::Handler.forward_request(proxy_zombie_id, req, res)