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:
		
							parent
							
								
									c67909f21b
								
							
						
					
					
						commit
						65fc104b2d
					
				|  | @ -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, | ||||||
|  |  | ||||||
|  | @ -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') | ||||||
|  |  | ||||||
|  | @ -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,19 +1519,23 @@ 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']: | ||||||
| 			plugin_tag_set = set(plugin.tags) | 			if config['reports'] and plugin.slug in config['reports']: | ||||||
|  | 				matching_tags = True | ||||||
|  | 				excluded_tags = False | ||||||
|  | 			else: | ||||||
|  | 				plugin_tag_set = set(plugin.tags) | ||||||
| 
 | 
 | ||||||
| 			matching_tags = False | 				matching_tags = False | ||||||
| 			for tag_group in autorecon.tags: | 				for tag_group in autorecon.tags: | ||||||
| 				if set(tag_group).issubset(plugin_tag_set): | 					if set(tag_group).issubset(plugin_tag_set): | ||||||
| 					matching_tags = True | 						matching_tags = True | ||||||
| 					break | 						break | ||||||
| 
 | 
 | ||||||
| 			excluded_tags = False | 				excluded_tags = False | ||||||
| 			for tag_group in autorecon.excluded_tags: | 				for tag_group in autorecon.excluded_tags: | ||||||
| 				if set(tag_group).issubset(plugin_tag_set): | 					if set(tag_group).issubset(plugin_tag_set): | ||||||
| 					excluded_tags = True | 						excluded_tags = True | ||||||
| 					break | 						break | ||||||
| 
 | 
 | ||||||
| 			if matching_tags and not excluded_tags: | 			if matching_tags and not excluded_tags: | ||||||
| 				pending.add(asyncio.create_task(generate_report(plugin, autorecon.completed_targets))) | 				pending.add(asyncio.create_task(generate_report(plugin, autorecon.completed_targets))) | ||||||
|  |  | ||||||
|  | @ -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" | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue