Updated plugin check()

Return value of check() will deregister the plugin if it is False.
Updated several plugins which use check() to return False where appropriate.
Added "Report" class to protected classes.
This commit is contained in:
Tib3rius 2022-10-28 01:41:22 -04:00
parent 25050606c2
commit f086edce34
10 changed files with 41 additions and 25 deletions

View File

@ -42,7 +42,7 @@ configurable_boolean_keys = [
] ]
config = { config = {
'protected_classes': ['autorecon', 'target', 'service', 'commandstreamreader', 'plugin', 'portscan', 'servicescan', 'global', 'pattern'], 'protected_classes': ['autorecon', 'target', 'service', 'commandstreamreader', 'plugin', 'portscan', 'report', 'servicescan', 'global', 'pattern'],
'service_exceptions': ['mc-nmf', 'ncacn_http', 'smux', 'status', 'tcpwrapped', 'unknown'], 'service_exceptions': ['mc-nmf', 'ncacn_http', 'smux', 'status', 'tcpwrapped', 'unknown'],
'config_dir': config_dir, 'config_dir': config_dir,
'global_file': None, 'global_file': None,

View File

@ -18,63 +18,70 @@ class DirBuster(ServiceScan):
self.add_option('threads', default=10, help='The number of threads to use when directory busting. Default: %(default)s') self.add_option('threads', default=10, help='The number of threads to use when directory busting. Default: %(default)s')
self.add_option('ext', default='txt,html,php,asp,aspx,jsp', help='The extensions you wish to fuzz (no dot, comma separated). Default: %(default)s') self.add_option('ext', default='txt,html,php,asp,aspx,jsp', help='The extensions you wish to fuzz (no dot, comma separated). Default: %(default)s')
self.add_true_option('recursive', help='Enables recursive searching (where available). Warning: This may cause significant increases to scan times. Default: %(default)s') self.add_true_option('recursive', help='Enables recursive searching (where available). Warning: This may cause significant increases to scan times. Default: %(default)s')
self.add_option('extras', default='', help='Any extra options you wish to pass to the tool when it runs. e.g. --dirbuster.extras=\'-s 200,301 --discover-backup\'')
self.match_service_name('^http') self.match_service_name('^http')
self.match_service_name('^nacn_http$', negative_match=True) self.match_service_name('^nacn_http$', negative_match=True)
def check(self): def check(self):
tool = self.get_option('tool') tool = self.get_option('tool')
if tool == 'feroxbuster': if tool == 'feroxbuster' and which('feroxbuster') is None:
if which('feroxbuster') is None: self.error('The feroxbuster program could not be found. Make sure it is installed. (On Kali, run: sudo apt install feroxbuster)')
self.error('The feroxbuster program could not be found. Make sure it is installed. (On Kali, run: sudo apt install feroxbuster)') return False
elif tool == 'gobuster': elif tool == 'gobuster' and which('gobuster') is None:
if which('gobuster') is None: self.error('The gobuster program could not be found. Make sure it is installed. (On Kali, run: sudo apt install gobuster)')
self.error('The gobuster program could not be found. Make sure it is installed. (On Kali, run: sudo apt install gobuster)') return False
elif tool == 'dirsearch': elif tool == 'dirsearch' and which('dirsearch') is None:
if which('dirsearch') is None: self.error('The dirsearch program could not be found. Make sure it is installed. (On Kali, run: sudo apt install dirsearch)')
self.error('The dirsearch program could not be found. Make sure it is installed. (On Kali, run: sudo apt install dirsearch)') return False
elif tool == 'ffuf' and which('ffuf') is None:
self.error('The ffuf program could not be found. Make sure it is installed. (On Kali, run: sudo apt install ffuf)')
return False
elif tool == 'dirb' and which('dirb') is None:
self.error('The dirb program could not be found. Make sure it is installed. (On Kali, run: sudo apt install dirb)')
return False
async def run(self, service): async def run(self, service):
dot_extensions = ','.join(['.' + x for x in self.get_option('ext').split(',')]) dot_extensions = ','.join(['.' + x for x in self.get_option('ext').split(',')])
for wordlist in self.get_option('wordlist'): for wordlist in self.get_option('wordlist'):
name = os.path.splitext(os.path.basename(wordlist))[0] name = os.path.splitext(os.path.basename(wordlist))[0]
if self.get_option('tool') == 'feroxbuster': if self.get_option('tool') == 'feroxbuster':
await service.execute('feroxbuster -u {http_scheme}://{addressv6}:{port}/ -t ' + str(self.get_option('threads')) + ' -w ' + wordlist + ' -x "' + self.get_option('ext') + '" -v -k ' + ('' if self.get_option('recursive') else '-n ') + '-q -e -o "{scandir}/{protocol}_{port}_{http_scheme}_feroxbuster_' + name + '.txt"') await service.execute('feroxbuster -u {http_scheme}://{addressv6}:{port}/ -t ' + str(self.get_option('threads')) + ' -w ' + wordlist + ' -x "' + self.get_option('ext') + '" -v -k ' + ('' if self.get_option('recursive') else '-n ') + '-q -e -o "{scandir}/{protocol}_{port}_{http_scheme}_feroxbuster_' + name + '.txt"' + (' ' + self.get_option('extras') if self.get_option('extras') else ''))
elif self.get_option('tool') == 'gobuster': elif self.get_option('tool') == 'gobuster':
await service.execute('gobuster dir -u {http_scheme}://{addressv6}:{port}/ -t ' + str(self.get_option('threads')) + ' -w ' + wordlist + ' -e -k -x "' + self.get_option('ext') + '" -z -o "{scandir}/{protocol}_{port}_{http_scheme}_gobuster_' + name + '.txt"') await service.execute('gobuster dir -u {http_scheme}://{addressv6}:{port}/ -t ' + str(self.get_option('threads')) + ' -w ' + wordlist + ' -e -k -x "' + self.get_option('ext') + '" -z -o "{scandir}/{protocol}_{port}_{http_scheme}_gobuster_' + name + '.txt"' + (' ' + self.get_option('extras') if self.get_option('extras') else ''))
elif self.get_option('tool') == 'dirsearch': elif self.get_option('tool') == 'dirsearch':
if service.target.ipversion == 'IPv6': if service.target.ipversion == 'IPv6':
service.error('dirsearch does not support IPv6.') service.error('dirsearch does not support IPv6.')
else: else:
await service.execute('dirsearch -u {http_scheme}://{address}:{port}/ -t ' + str(self.get_option('threads')) + ' -e "' + self.get_option('ext') + '" -f -q ' + ('-r ' if self.get_option('recursive') else '') + '-w ' + wordlist + ' --format=plain -o "{scandir}/{protocol}_{port}_{http_scheme}_dirsearch_' + name + '.txt"') await service.execute('dirsearch -u {http_scheme}://{address}:{port}/ -t ' + str(self.get_option('threads')) + ' -e "' + self.get_option('ext') + '" -f -q ' + ('-r ' if self.get_option('recursive') else '') + '-w ' + wordlist + ' --format=plain -o "{scandir}/{protocol}_{port}_{http_scheme}_dirsearch_' + name + '.txt"' + (' ' + self.get_option('extras') if self.get_option('extras') else ''))
elif self.get_option('tool') == 'ffuf': elif self.get_option('tool') == 'ffuf':
await service.execute('ffuf -u {http_scheme}://{addressv6}:{port}/FUZZ -t ' + str(self.get_option('threads')) + ' -w ' + wordlist + ' -e "' + dot_extensions + '" -v ' + ('-recursion ' if self.get_option('recursive') else '') + '-noninteractive | tee {scandir}/{protocol}_{port}_{http_scheme}_ffuf_' + name + '.txt') await service.execute('ffuf -u {http_scheme}://{addressv6}:{port}/FUZZ -t ' + str(self.get_option('threads')) + ' -w ' + wordlist + ' -e "' + dot_extensions + '" -v ' + ('-recursion ' if self.get_option('recursive') else '') + '-noninteractive' + (' ' + self.get_option('extras') if self.get_option('extras') else '') + ' | tee {scandir}/{protocol}_{port}_{http_scheme}_ffuf_' + name + '.txt')
elif self.get_option('tool') == 'dirb': elif self.get_option('tool') == 'dirb':
await service.execute('dirb {http_scheme}://{addressv6}:{port}/ ' + wordlist + ' -l ' + ('' if self.get_option('recursive') else '-r ') + '-S -X ",' + dot_extensions + '" -o "{scandir}/{protocol}_{port}_{http_scheme}_dirb_' + name + '.txt"') await service.execute('dirb {http_scheme}://{addressv6}:{port}/ ' + wordlist + ' -l ' + ('' if self.get_option('recursive') else '-r ') + '-S -X ",' + dot_extensions + '" -o "{scandir}/{protocol}_{port}_{http_scheme}_dirb_' + name + '.txt"' + (' ' + self.get_option('extras') if self.get_option('extras') else ''))
def manual(self, service, plugin_was_run): def manual(self, service, plugin_was_run):
dot_extensions = ','.join(['.' + x for x in self.get_option('ext').split(',')]) dot_extensions = ','.join(['.' + x for x in self.get_option('ext').split(',')])
if self.get_option('tool') == 'feroxbuster': if self.get_option('tool') == 'feroxbuster':
service.add_manual_command('(feroxbuster) Multi-threaded recursive directory/file enumeration for web servers using various wordlists:', [ service.add_manual_command('(feroxbuster) Multi-threaded recursive directory/file enumeration for web servers using various wordlists:', [
'feroxbuster -u {http_scheme}://{addressv6}:{port} -t ' + str(self.get_option('threads')) + ' -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x "' + self.get_option('ext') + '" -v -k ' + ('' if self.get_option('recursive') else '-n ') + '-e -o {scandir}/{protocol}_{port}_{http_scheme}_feroxbuster_dirbuster.txt' 'feroxbuster -u {http_scheme}://{addressv6}:{port} -t ' + str(self.get_option('threads')) + ' -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x "' + self.get_option('ext') + '" -v -k ' + ('' if self.get_option('recursive') else '-n ') + '-e -o {scandir}/{protocol}_{port}_{http_scheme}_feroxbuster_dirbuster.txt' + (' ' + self.get_option('extras') if self.get_option('extras') else '')
]) ])
elif self.get_option('tool') == 'gobuster': elif self.get_option('tool') == 'gobuster':
service.add_manual_command('(gobuster v3) Multi-threaded directory/file enumeration for web servers using various wordlists:', [ service.add_manual_command('(gobuster v3) Multi-threaded directory/file enumeration for web servers using various wordlists:', [
'gobuster dir -u {http_scheme}://{addressv6}:{port}/ -t ' + str(self.get_option('threads')) + ' -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -e -k -x "' + self.get_option('ext') + '" -o "{scandir}/{protocol}_{port}_{http_scheme}_gobuster_dirbuster.txt"' 'gobuster dir -u {http_scheme}://{addressv6}:{port}/ -t ' + str(self.get_option('threads')) + ' -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -e -k -x "' + self.get_option('ext') + '" -o "{scandir}/{protocol}_{port}_{http_scheme}_gobuster_dirbuster.txt"' + (' ' + self.get_option('extras') if self.get_option('extras') else '')
]) ])
elif self.get_option('tool') == 'dirsearch': elif self.get_option('tool') == 'dirsearch':
if service.target.ipversion == 'IPv4': if service.target.ipversion == 'IPv4':
service.add_manual_command('(dirsearch) Multi-threaded recursive directory/file enumeration for web servers using various wordlists:', [ service.add_manual_command('(dirsearch) Multi-threaded recursive directory/file enumeration for web servers using various wordlists:', [
'dirsearch -u {http_scheme}://{address}:{port}/ -t ' + str(self.get_option('threads')) + ' -e "' + self.get_option('ext') + '" -f ' + ('-r ' if self.get_option('recursive') else '') + '-w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt --format=plain --output="{scandir}/{protocol}_{port}_{http_scheme}_dirsearch_dirbuster.txt"' 'dirsearch -u {http_scheme}://{address}:{port}/ -t ' + str(self.get_option('threads')) + ' -e "' + self.get_option('ext') + '" -f ' + ('-r ' if self.get_option('recursive') else '') + '-w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt --format=plain --output="{scandir}/{protocol}_{port}_{http_scheme}_dirsearch_dirbuster.txt"' + (' ' + self.get_option('extras') if self.get_option('extras') else '')
]) ])
elif self.get_option('tool') == 'ffuf': elif self.get_option('tool') == 'ffuf':
service.add_manual_command('(ffuf) Multi-threaded recursive directory/file enumeration for web servers using various wordlists:', [ service.add_manual_command('(ffuf) Multi-threaded recursive directory/file enumeration for web servers using various wordlists:', [
'ffuf -u {http_scheme}://{addressv6}:{port}/FUZZ -t ' + str(self.get_option('threads')) + ' -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -e "' + dot_extensions + '" -v ' + ('-recursion ' if self.get_option('recursive') else '') + '-noninteractive | tee {scandir}/{protocol}_{port}_{http_scheme}_ffuf_dirbuster.txt' 'ffuf -u {http_scheme}://{addressv6}:{port}/FUZZ -t ' + str(self.get_option('threads')) + ' -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -e "' + dot_extensions + '" -v ' + ('-recursion ' if self.get_option('recursive') else '') + '-noninteractive' + (' ' + self.get_option('extras') if self.get_option('extras') else '') + ' | tee {scandir}/{protocol}_{port}_{http_scheme}_ffuf_dirbuster.txt'
]) ])
elif self.get_option('tool') == 'dirb': elif self.get_option('tool') == 'dirb':
service.add_manual_command('(dirb) Recursive directory/file enumeration for web servers using various wordlists:', [ service.add_manual_command('(dirb) Recursive directory/file enumeration for web servers using various wordlists:', [
'dirb {http_scheme}://{addressv6}:{port}/ /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -l ' + ('' if self.get_option('recursive') else '-r ') + '-X ",' + dot_extensions + '" -o "{scandir}/{protocol}_{port}_{http_scheme}_dirb_dirbuster.txt"' 'dirb {http_scheme}://{addressv6}:{port}/ /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -l ' + ('' if self.get_option('recursive') else '-r ') + '-X ",' + dot_extensions + '" -o "{scandir}/{protocol}_{port}_{http_scheme}_dirb_dirbuster.txt"' + (' ' + self.get_option('extras') if self.get_option('extras') else '')
]) ])

View File

@ -16,6 +16,7 @@ class DnsReconSubdomainBruteforce(ServiceScan):
def check(self): def check(self):
if which('dnsrecon') is None: if which('dnsrecon') is None:
self.error('The program dnsrecon could not be found. Make sure it is installed. (On Kali, run: sudo apt install dnsrecon)') self.error('The program dnsrecon could not be found. Make sure it is installed. (On Kali, run: sudo apt install dnsrecon)')
return False
def manual(self, service, plugin_was_run): def manual(self, service, plugin_was_run):
domain_name = '<DOMAIN-NAME>' domain_name = '<DOMAIN-NAME>'

View File

@ -16,6 +16,7 @@ class DnsRecon(ServiceScan):
def check(self): def check(self):
if which('dnsrecon') is None: if which('dnsrecon') is None:
self.error('The program dnsrecon could not be found. Make sure it is installed. (On Kali, run: sudo apt install dnsrecon)') self.error('The program dnsrecon could not be found. Make sure it is installed. (On Kali, run: sudo apt install dnsrecon)')
return False
def manual(self, service, plugin_was_run): def manual(self, service, plugin_was_run):
service.add_manual_command('Use dnsrecon to automatically query data from the DNS server. You must specify the target domain name.', [ service.add_manual_command('Use dnsrecon to automatically query data from the DNS server. You must specify the target domain name.', [

View File

@ -14,6 +14,7 @@ class OracleScanner(ServiceScan):
def check(self): def check(self):
if which('oscanner') is None: if which('oscanner') is None:
self.error('The oscanner program could not be found. Make sure it is installed. (On Kali, run: sudo apt install oscanner)') self.error('The oscanner program could not be found. Make sure it is installed. (On Kali, run: sudo apt install oscanner)')
return False
async def run(self, service): async def run(self, service):
await service.execute('oscanner -v -s {address} -P {port} 2>&1', outfile='{protocol}_{port}_oracle_scanner.txt') await service.execute('oscanner -v -s {address} -P {port} 2>&1', outfile='{protocol}_{port}_oracle_scanner.txt')

View File

@ -14,6 +14,7 @@ class OracleTNScmd(ServiceScan):
def check(self): def check(self):
if which('tnscmd10g') is None: if which('tnscmd10g') is None:
self.error('The tnscmd10g program could not be found. Make sure it is installed. (On Kali, run: sudo apt install tnscmd10g)') self.error('The tnscmd10g program could not be found. Make sure it is installed. (On Kali, run: sudo apt install tnscmd10g)')
return False
async def run(self, service): async def run(self, service):
if service.target.ipversion == 'IPv4': if service.target.ipversion == 'IPv4':

View File

@ -14,6 +14,7 @@ class RedisCli(ServiceScan):
def check(self): def check(self):
if which('redis-cli') is None: if which('redis-cli') is None:
self.error('The redis-cli program could not be found. Make sure it is installed. (On Kali, run: sudo apt install redis-tools)') self.error('The redis-cli program could not be found. Make sure it is installed. (On Kali, run: sudo apt install redis-tools)')
return False
async def run(self, service): async def run(self, service):
if which('redis-cli') is not None: if which('redis-cli') is not None:

View File

@ -15,6 +15,7 @@ class WkHTMLToImage(ServiceScan):
def check(self): def check(self):
if which('wkhtmltoimage') is None: if which('wkhtmltoimage') is None:
self.error('The wkhtmltoimage program could not be found. Make sure it is installed. (On Kali, run: sudo apt install wkhtmltopdf)') self.error('The wkhtmltoimage program could not be found. Make sure it is installed. (On Kali, run: sudo apt install wkhtmltopdf)')
return False
async def run(self, service): async def run(self, service):
if which('wkhtmltoimage') is not None: if which('wkhtmltoimage') is not None:

View File

@ -17,7 +17,7 @@ from autorecon.io import slugify, e, fformat, cprint, debug, info, warn, error,
from autorecon.plugins import Pattern, PortScan, ServiceScan, Report, AutoRecon from autorecon.plugins import Pattern, PortScan, ServiceScan, Report, AutoRecon
from autorecon.targets import Target, Service from autorecon.targets import Target, Service
VERSION = "2.0.26" VERSION = "2.0.27"
if not os.path.exists(config['config_dir']): if not os.path.exists(config['config_dir']):
shutil.rmtree(config['config_dir'], ignore_errors=True, onerror=None) shutil.rmtree(config['config_dir'], ignore_errors=True, onerror=None)
@ -809,7 +809,7 @@ async def run():
else: else:
config['plugins_dir'] = None config['plugins_dir'] = None
parser = argparse.ArgumentParser(add_help=False, description='Network reconnaissance tool to port scan and automatically enumerate services found on multiple targets.') parser = argparse.ArgumentParser(add_help=False, allow_abbrev=False, description='Network reconnaissance tool to port scan and automatically enumerate services found on multiple targets.')
parser.add_argument('targets', action='store', help='IP addresses (e.g. 10.0.0.1), CIDR notation (e.g. 10.0.0.1/24), or resolvable hostnames (e.g. foo.bar) to scan.', nargs='*') parser.add_argument('targets', action='store', help='IP addresses (e.g. 10.0.0.1), CIDR notation (e.g. 10.0.0.1/24), or resolvable hostnames (e.g. foo.bar) to scan.', nargs='*')
parser.add_argument('-t', '--target-file', action='store', type=str, default='', help='Read targets from file.') parser.add_argument('-t', '--target-file', action='store', type=str, default='', help='Read targets from file.')
parser.add_argument('-p', '--ports', action='store', type=str, help='Comma separated list of ports / port ranges to scan. Specify TCP/UDP ports by prepending list with T:/U: To scan both TCP/UDP, put port(s) at start or specify B: e.g. 53,T:21-25,80,U:123,B:123. Default: %(default)s') parser.add_argument('-p', '--ports', action='store', type=str, help='Comma separated list of ports / port ranges to scan. Specify TCP/UDP ports by prepending list with T:/U: To scan both TCP/UDP, put port(s) at start or specify B: e.g. 53,T:21-25,80,U:123,B:123. Default: %(default)s')
@ -1081,6 +1081,7 @@ async def run():
autorecon.argparse.set_defaults(**{key: val}) autorecon.argparse.set_defaults(**{key: val})
parser.add_argument('-h', '--help', action='help', default=argparse.SUPPRESS, help='Show this help message and exit.') parser.add_argument('-h', '--help', action='help', default=argparse.SUPPRESS, help='Show this help message and exit.')
parser.error = lambda s: fail(s[0].upper() + s[1:])
args = parser.parse_args() args = parser.parse_args()
args_dict = vars(args) args_dict = vars(args)
@ -1138,7 +1139,7 @@ async def run():
else: else:
error('Invalid value provided to --max-plugin-global-instances. Values must be in the format PLUGIN:NUMBER.') error('Invalid value provided to --max-plugin-global-instances. Values must be in the format PLUGIN:NUMBER.')
for plugin in autorecon.plugins.values(): for slug, plugin in autorecon.plugins.items():
if hasattr(plugin, 'max_target_instances') and plugin.slug in max_plugin_target_instances: if hasattr(plugin, 'max_target_instances') and plugin.slug in max_plugin_target_instances:
plugin.max_target_instances = max_plugin_target_instances[plugin.slug] plugin.max_target_instances = max_plugin_target_instances[plugin.slug]
@ -1147,7 +1148,9 @@ async def run():
for member_name, _ in inspect.getmembers(plugin, predicate=inspect.ismethod): for member_name, _ in inspect.getmembers(plugin, predicate=inspect.ismethod):
if member_name == 'check': if member_name == 'check':
plugin.check() if plugin.check() == False:
autorecon.plugins.pop(slug)
continue
continue continue
if config['ports']: if config['ports']:

View File

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "autorecon" name = "autorecon"
version = "2.0.26" version = "2.0.27"
description = "A multi-threaded network reconnaissance tool which performs automated enumeration of services." description = "A multi-threaded network reconnaissance tool which performs automated enumeration of services."
authors = ["Tib3rius"] authors = ["Tib3rius"]
license = "GNU GPL v3" license = "GNU GPL v3"