Updates & bug fixes.

Plugins & wordlists are now stored in ~/.local/share/AutoRecon.
Default config / global config files are still stored in ~/.config/AutoRecon.
Removed feature which used the cwd's config.toml, global.toml, and plugins dir if detected.
Fixed bug which wouldn't generate combined reports in some cases.
This commit is contained in:
Tib3rius 2022-12-07 15:12:09 -05:00
parent c67909f21b
commit 65fc104b2d
4 changed files with 41 additions and 31 deletions

View File

@ -1,6 +1,7 @@
import appdirs, os import appdirs, os
config_dir = appdirs.user_config_dir('AutoRecon') config_dir = appdirs.user_config_dir('AutoRecon')
data_dir = appdirs.user_data_dir('AutoRecon')
configurable_keys = [ configurable_keys = [
'ports', 'ports',
@ -45,6 +46,7 @@ config = {
'protected_classes': ['autorecon', 'target', 'service', 'commandstreamreader', 'plugin', 'portscan', 'report', 'servicescan', 'global', 'pattern'], 'protected_classes': ['autorecon', 'target', 'service', 'commandstreamreader', 'plugin', 'portscan', 'report', 'servicescan', 'global', 'pattern'],
'service_exceptions': ['infocrypt', 'mc-nmf', 'ncacn_http', 'smux', 'status', 'tcpwrapped', 'unknown'], 'service_exceptions': ['infocrypt', 'mc-nmf', 'ncacn_http', 'smux', 'status', 'tcpwrapped', 'unknown'],
'config_dir': config_dir, 'config_dir': config_dir,
'data_dir': data_dir,
'global_file': None, 'global_file': None,
'ports': None, 'ports': None,
'max_scans': 50, 'max_scans': 50,

View File

@ -14,7 +14,7 @@ class DirBuster(ServiceScan):
def configure(self): def configure(self):
self.add_choice_option('tool', default='feroxbuster', choices=['feroxbuster', 'gobuster', 'dirsearch', 'ffuf', 'dirb'], help='The tool to use for directory busting. Default: %(default)s') self.add_choice_option('tool', default='feroxbuster', choices=['feroxbuster', 'gobuster', 'dirsearch', 'ffuf', 'dirb'], help='The tool to use for directory busting. Default: %(default)s')
self.add_list_option('wordlist', default=[os.path.join(config['config_dir'], 'wordlists', 'dirbuster.txt')], help='The wordlist(s) to use when directory busting. Separate multiple wordlists with spaces. Default: %(default)s') self.add_list_option('wordlist', default=[os.path.join(config['data_dir'], 'wordlists', 'dirbuster.txt')], help='The wordlist(s) to use when directory busting. Separate multiple wordlists with spaces. 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('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')

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.29" VERSION = "2.0.30"
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)
@ -25,19 +25,29 @@ if not os.path.exists(config['config_dir']):
open(os.path.join(config['config_dir'], 'VERSION-' + VERSION), 'a').close() open(os.path.join(config['config_dir'], 'VERSION-' + VERSION), 'a').close()
shutil.copy(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'config.toml'), os.path.join(config['config_dir'], 'config.toml')) shutil.copy(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'config.toml'), os.path.join(config['config_dir'], 'config.toml'))
shutil.copy(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'global.toml'), os.path.join(config['config_dir'], 'global.toml')) shutil.copy(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'global.toml'), os.path.join(config['config_dir'], 'global.toml'))
shutil.copytree(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'default-plugins'), os.path.join(config['config_dir'], 'plugins'))
shutil.copytree(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'wordlists'), os.path.join(config['config_dir'], 'wordlists'))
else: else:
if not os.path.exists(os.path.join(config['config_dir'], 'config.toml')): if not os.path.exists(os.path.join(config['config_dir'], 'config.toml')):
shutil.copy(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'config.toml'), os.path.join(config['config_dir'], 'config.toml')) shutil.copy(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'config.toml'), os.path.join(config['config_dir'], 'config.toml'))
if not os.path.exists(os.path.join(config['config_dir'], 'global.toml')): if not os.path.exists(os.path.join(config['config_dir'], 'global.toml')):
shutil.copy(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'global.toml'), os.path.join(config['config_dir'], 'global.toml')) shutil.copy(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'global.toml'), os.path.join(config['config_dir'], 'global.toml'))
if not os.path.exists(os.path.join(config['config_dir'], 'plugins')):
shutil.copytree(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'default-plugins'), os.path.join(config['config_dir'], 'plugins'))
if not os.path.exists(os.path.join(config['config_dir'], 'wordlists')):
shutil.copytree(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'wordlists'), os.path.join(config['config_dir'], 'wordlists'))
if not os.path.exists(os.path.join(config['config_dir'], 'VERSION-' + VERSION)): if not os.path.exists(os.path.join(config['config_dir'], 'VERSION-' + VERSION)):
warn('It looks like the config/plugins in ' + config['config_dir'] + ' are outdated. Please remove the ' + config['config_dir'] + ' directory and re-run AutoRecon to rebuild them.') warn('It looks like the config in ' + config['config_dir'] + ' is outdated. Please remove the ' + config['config_dir'] + ' directory and re-run AutoRecon to rebuild it.')
if not os.path.exists(config['data_dir']):
shutil.rmtree(config['data_dir'], ignore_errors=True, onerror=None)
os.makedirs(config['data_dir'], exist_ok=True)
open(os.path.join(config['data_dir'], 'VERSION-' + VERSION), 'a').close()
shutil.copytree(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'default-plugins'), os.path.join(config['data_dir'], 'plugins'))
shutil.copytree(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'wordlists'), os.path.join(config['data_dir'], 'wordlists'))
else:
if not os.path.exists(os.path.join(config['data_dir'], 'plugins')):
shutil.copytree(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'default-plugins'), os.path.join(config['data_dir'], 'plugins'))
if not os.path.exists(os.path.join(config['data_dir'], 'wordlists')):
shutil.copytree(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'wordlists'), os.path.join(config['data_dir'], 'wordlists'))
if not os.path.exists(os.path.join(config['data_dir'], 'VERSION-' + VERSION)):
warn('It looks like the plugins in ' + config['data_dir'] + ' are outdated. Please remove the ' + config['data_dir'] + ' directory and re-run AutoRecon to rebuild them.')
# Save current terminal settings so we can restore them. # Save current terminal settings so we can restore them.
terminal_settings = termios.tcgetattr(sys.stdin.fileno()) terminal_settings = termios.tcgetattr(sys.stdin.fileno())
@ -786,26 +796,20 @@ async def scan_target(target):
async def run(): async def run():
# Find config file. # Find config file.
if os.path.isfile(os.path.join(os.getcwd(), 'config.toml')): if os.path.isfile(os.path.join(config['config_dir'], 'config.toml')):
config_file = os.path.join(os.getcwd(), 'config.toml')
elif os.path.isfile(os.path.join(config['config_dir'], 'config.toml')):
config_file = os.path.join(config['config_dir'], 'config.toml') config_file = os.path.join(config['config_dir'], 'config.toml')
else: else:
config_file = None config_file = None
# Find global file. # Find global file.
if os.path.isfile(os.path.join(os.getcwd(), 'global.toml')): if os.path.isfile(os.path.join(config['config_dir'], 'global.toml')):
config['global_file'] = os.path.join(os.getcwd(), 'global.toml')
elif os.path.isfile(os.path.join(config['config_dir'], 'global.toml')):
config['global_file'] = os.path.join(config['config_dir'], 'global.toml') config['global_file'] = os.path.join(config['config_dir'], 'global.toml')
else: else:
config['global_file'] = None config['global_file'] = None
# Find plugins. # Find plugins.
if os.path.isdir(os.path.join(os.getcwd(), 'plugins')): if os.path.isdir(os.path.join(config['data_dir'], 'plugins')):
config['plugins_dir'] = os.path.join(os.getcwd(), 'plugins') config['plugins_dir'] = os.path.join(config['data_dir'], 'plugins')
elif os.path.isdir(os.path.join(config['config_dir'], 'plugins')):
config['plugins_dir'] = os.path.join(config['config_dir'], 'plugins')
else: else:
config['plugins_dir'] = None config['plugins_dir'] = None
@ -1515,6 +1519,10 @@ async def run():
# If there's only one target we don't need a combined report # If there's only one target we don't need a combined report
if len(autorecon.completed_targets) > 1: if len(autorecon.completed_targets) > 1:
for plugin in autorecon.plugin_types['report']: for plugin in autorecon.plugin_types['report']:
if config['reports'] and plugin.slug in config['reports']:
matching_tags = True
excluded_tags = False
else:
plugin_tag_set = set(plugin.tags) plugin_tag_set = set(plugin.tags)
matching_tags = False matching_tags = False

View File

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "autorecon" name = "autorecon"
version = "2.0.29" version = "2.0.30"
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"