Commit 77151248 by Ben Mz Committed by Marcin Bury

Enhance search & setup options to reduce network impact (#587)

* add advanced options to scanners, and so modules in order to restrict tests and reduce network impact

* avoid committing Pipfile

* correct help which was not working anymore

* enhance search capabilities

* enhance search with existing options based on current modules

* remove display test

* simplify the non interactive execution process

* correct lint errors

* correct lint errors

* correct OptEncoder error, missing advanced parameter
parent 01aac5a4
...@@ -75,3 +75,8 @@ venv/ ...@@ -75,3 +75,8 @@ venv/
# vim # vim
*.swp *.swp
*.swo *.swo
# Pipenv files
Pipfile
Pipfile.lock
...@@ -45,7 +45,7 @@ class ExploitOptionsAggregator(type): ...@@ -45,7 +45,7 @@ class ExploitOptionsAggregator(type):
for key, value in iteritems(attrs): for key, value in iteritems(attrs):
if isinstance(value, Option): if isinstance(value, Option):
value.label = key value.label = key
attrs["exploit_attributes"].update({key: [value.display_value, value.description]}) attrs["exploit_attributes"].update({key: [value.display_value, value.description, value.advanced]})
elif key == "__info__": elif key == "__info__":
attrs["_{}{}".format(name, key)] = value attrs["_{}{}".format(name, key)] = value
del attrs[key] del attrs[key]
...@@ -106,7 +106,7 @@ class Exploit(BaseExploit): ...@@ -106,7 +106,7 @@ class Exploit(BaseExploit):
) )
threads.append(thread) threads.append(thread)
print_status("{} thread is starting...".format(thread.name)) # print_status("{} thread is starting...".format(thread.name))
thread.start() thread.start()
start = time.time() start = time.time()
...@@ -119,9 +119,9 @@ class Exploit(BaseExploit): ...@@ -119,9 +119,9 @@ class Exploit(BaseExploit):
for thread in threads: for thread in threads:
thread.join() thread.join()
print_status("{} thread is terminated.".format(thread.name)) # print_status("{} thread is terminated.".format(thread.name))
print_status("Elapsed time: {} seconds".format(time.time() - start)) print_status("Elapsed time: {0:.4f} seconds".format(round(time.time() - start, 2)))
def multi(fn): def multi(fn):
......
...@@ -11,10 +11,15 @@ from routersploit.core.exploit.utils import ( ...@@ -11,10 +11,15 @@ from routersploit.core.exploit.utils import (
class Option(object): class Option(object):
""" Exploit attribute that is set by the end user """ """ Exploit attribute that is set by the end user """
def __init__(self, default, description=""): def __init__(self, default, description="", advanced=False):
self.label = None self.label = None
self.description = description self.description = description
try:
self.advanced = bool(advanced)
except ValueError:
raise OptionValidationError("Invalid value. Cannot cast '{}' to boolean.".format(advanced))
if default: if default:
self.__set__("", default) self.__set__("", default)
else: else:
...@@ -54,7 +59,7 @@ class OptPort(Option): ...@@ -54,7 +59,7 @@ class OptPort(Option):
class OptBool(Option): class OptBool(Option):
""" Option Bool attribute """ """ Option Bool attribute """
def __init__(self, default, description=""): def __init__(self, default, description="", advanced=False):
self.description = description self.description = description
if default: if default:
...@@ -64,6 +69,11 @@ class OptBool(Option): ...@@ -64,6 +69,11 @@ class OptBool(Option):
self.value = default self.value = default
try:
self.advanced = bool(advanced)
except ValueError:
raise OptionValidationError("Invalid value. Cannot cast '{}' to boolean.".format(advanced))
def __set__(self, instance, value): def __set__(self, instance, value):
if value == "true": if value == "true":
self.value = True self.value = True
...@@ -142,7 +152,7 @@ class OptWordlist(Option): ...@@ -142,7 +152,7 @@ class OptWordlist(Option):
class OptEncoder(Option): class OptEncoder(Option):
""" Option Encoder attribute """ """ Option Encoder attribute """
def __init__(self, default, description=""): def __init__(self, default, description="", advanced=False):
self.description = description self.description = description
if default: if default:
...@@ -152,6 +162,11 @@ class OptEncoder(Option): ...@@ -152,6 +162,11 @@ class OptEncoder(Option):
self.display_value = "" self.display_value = ""
self.value = None self.value = None
try:
self.advanced = bool(advanced)
except ValueError:
raise OptionValidationError("Invalid value. Cannot cast '{}' to boolean.".format(advanced))
def __set__(self, instance, value): def __set__(self, instance, value):
encoder = instance.get_encoder(value) encoder = instance.get_encoder(value)
......
from os import path import os
from routersploit.core.exploit import * from routersploit.core.exploit import *
from routersploit.core.exploit.exploit import Protocol from routersploit.core.exploit.exploit import Protocol
...@@ -19,14 +20,34 @@ class Exploit(Exploit): ...@@ -19,14 +20,34 @@ class Exploit(Exploit):
target = OptIP("", "Target IPv4 or IPv6 address") target = OptIP("", "Target IPv4 or IPv6 address")
http_port = OptPort(80, "Target Web Interface Port") vendor = OptString("any", "Vendor concerned (default: any)")
check_exploits = OptBool(True, "Check exploits against target: true/false", advanced=True)
check_creds = OptBool(True, "Check factory credentials against target: true/false", advanced=True)
http_use = OptBool(True, "Check HTTP[s] service: true/false")
http_port = OptPort(80, "Target Web Interface Port", advanced=True)
http_ssl = OptBool(False, "HTTPS enabled: true/false") http_ssl = OptBool(False, "HTTPS enabled: true/false")
ftp_port = OptPort(21, "Target FTP port (default: 21)") ftp_use = OptBool(True, "Check FTP[s] service: true/false")
ftp_port = OptPort(21, "Target FTP port (default: 21)", advanced=True)
ftp_ssl = OptBool(False, "FTPS enabled: true/false") ftp_ssl = OptBool(False, "FTPS enabled: true/false")
ssh_port = OptPort(22, "Target SSH port (default: 22)") ssh_use = OptBool(True, "Check SSH service: true/false")
telnet_port = OptPort(23, "Target Telnet port (default: 23)") ssh_port = OptPort(22, "Target SSH port (default: 22)", advanced=True)
telnet_use = OptBool(True, "Check Telnet service: true/false")
telnet_port = OptPort(23, "Target Telnet port (default: 23)", advanced=True)
snmp_use = OptBool(True, "Check SNMP service: true/false")
snmp_community = OptString("public", "Target SNMP community name (default: public)", advanced=True)
snmp_port = OptPort(161, "Target SNMP port (default: 161)", advanced=True)
tcp_use = OptBool(True, "Check custom TCP services", advanced=True)
# tcp_port = OptPort(None, "Restrict TCP custom service tests to specific port (default: None)")
udp_use = OptBool(True, "Check custom UDP services", advanced=True)
# udp_port = OptPort(None, "Restrict UDP custom service tests to specific port (default: None)")
threads = OptInteger(8, "Number of threads") threads = OptInteger(8, "Number of threads")
...@@ -34,17 +55,22 @@ class Exploit(Exploit): ...@@ -34,17 +55,22 @@ class Exploit(Exploit):
self.vulnerabilities = [] self.vulnerabilities = []
self.creds = [] self.creds = []
self.not_verified = [] self.not_verified = []
self._exploits_directories = [path.join(utils.MODULES_DIR, "exploits", module) for module in self.modules] self._exploits_directories = [os.path.join(utils.MODULES_DIR, "exploits", module) for module in self.modules]
self._creds_directories = [path.join(utils.MODULES_DIR, "creds", module) for module in self.modules] self._creds_directories = [os.path.join(utils.MODULES_DIR, "creds", module) for module in self.modules]
def run(self): def run(self):
self.vulnerabilities = [] self.vulnerabilities = []
self.creds = [] self.creds = []
self.not_verified = [] self.not_verified = []
# Update list of directories with specific vendor if needed
if self.vendor != 'any':
self._exploits_directories = [os.path.join(utils.MODULES_DIR, "exploits", module, self.vendor) for module in self.modules]
if self.check_exploits:
# vulnerabilities # vulnerabilities
print_info() print_info()
print_info("\033[94m[*]\033[0m", "Starting vulnerablity check...".format(self.target)) print_info("\033[94m[*]\033[0m", "{} Starting vulnerablity check...".format(self.target))
modules = [] modules = []
for directory in self._exploits_directories: for directory in self._exploits_directories:
...@@ -54,6 +80,7 @@ class Exploit(Exploit): ...@@ -54,6 +80,7 @@ class Exploit(Exploit):
data = LockedIterator(modules) data = LockedIterator(modules)
self.run_threads(self.threads, self.exploits_target_function, data) self.run_threads(self.threads, self.exploits_target_function, data)
if self.check_creds:
# default creds # default creds
print_info() print_info()
print_info("\033[94m[*]\033[0m", "{} Starting default credentials check...".format(self.target)) print_info("\033[94m[*]\033[0m", "{} Starting default credentials check...".format(self.target))
...@@ -99,21 +126,46 @@ class Exploit(Exploit): ...@@ -99,21 +126,46 @@ class Exploit(Exploit):
else: else:
exploit.target = self.target exploit.target = self.target
# Avoid checking specific protocol - reduce network impact
if exploit.target_protocol == Protocol.HTTP: if exploit.target_protocol == Protocol.HTTP:
if not self.http_use:
continue
exploit.port = self.http_port exploit.port = self.http_port
if self.http_ssl: if self.http_ssl:
exploit.ssl = "true" exploit.ssl = "true"
exploit.target_protocol = Protocol.HTTPS exploit.target_protocol = Protocol.HTTPS
elif exploit.target_protocol is Protocol.FTP: elif exploit.target_protocol is Protocol.FTP:
if not self.ftp_use:
continue
exploit.port = self.ftp_port exploit.port = self.ftp_port
if self.ftp_ssl: if self.ftp_ssl:
exploit.ssl = "true" exploit.ssl = "true"
exploit.target_protocol = Protocol.FTPS exploit.target_protocol = Protocol.FTPS
elif exploit.target_protocol is Protocol.TELNET: elif exploit.target_protocol is Protocol.TELNET:
if not self.telnet_use:
continue
exploit.port = self.telnet_port exploit.port = self.telnet_port
elif exploit.target_protocol is Protocol.SSH:
if not self.ssh_use:
continue
exploit.port = self.ssh_port
elif exploit.target_protocol is Protocol.SNMP:
if not self.snmp_use:
continue
exploit.port = self.ssh_port
elif exploit.target_protocol is Protocol.TCP:
if not self.tcp_use:
continue
elif exploit.target_protocol is Protocol.UDP:
if not self.udp_use:
continue
# elif exploit.target_protocol not in ["tcp", "udp"]: # elif exploit.target_protocol not in ["tcp", "udp"]:
# exploit.target_protocol = "custom" # exploit.target_protocol = "custom"
......
...@@ -17,10 +17,15 @@ LOGGER.setLevel(logging.DEBUG) ...@@ -17,10 +17,15 @@ LOGGER.setLevel(logging.DEBUG)
LOGGER.addHandler(log_handler) LOGGER.addHandler(log_handler)
def routersploit(): def routersploit(argv):
rsf = RoutersploitInterpreter() rsf = RoutersploitInterpreter()
if len(argv[1:]):
rsf.nonInteractive(argv)
else:
rsf.start() rsf.start()
if __name__ == "__main__": if __name__ == "__main__":
routersploit() try:
routersploit(sys.argv)
except (KeyboardInterrupt, SystemExit):
pass
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment