Bug Fixes

Removed the wkhtmltoimage plugin as this is no longer compatible with Kali Linux.
Fixed bug which crashed AutoRecon if a plugin check() function failed. Now AutoRecon exits gracefully.
Added --ignore-plugin-checks which will ignore failed plugin checks but also disable said plugins at runtime.
This commit is contained in:
Tib3rius 2025-04-04 23:00:48 -04:00
parent 19cc46b4c8
commit 39680e875e
4 changed files with 21 additions and 26 deletions

View File

@ -26,6 +26,7 @@ configurable_keys = [
'proxychains', 'proxychains',
'disable_sanity_checks', 'disable_sanity_checks',
'disable_keyboard_control', 'disable_keyboard_control',
'ignore_plugin_checks',
'force_services', 'force_services',
'max_plugin_target_instances', 'max_plugin_target_instances',
'max_plugin_global_instances', 'max_plugin_global_instances',
@ -39,6 +40,7 @@ configurable_boolean_keys = [
'no_port_dirs', 'no_port_dirs',
'proxychains', 'proxychains',
'disable_sanity_checks', 'disable_sanity_checks',
'ignore_plugin_checks',
'accessible' 'accessible'
] ]
@ -70,6 +72,7 @@ config = {
'proxychains': False, 'proxychains': False,
'disable_sanity_checks': False, 'disable_sanity_checks': False,
'disable_keyboard_control': False, 'disable_keyboard_control': False,
'ignore_plugin_checks': False,
'force_services': None, 'force_services': None,
'max_plugin_target_instances': None, 'max_plugin_target_instances': None,
'max_plugin_global_instances': None, 'max_plugin_global_instances': None,

View File

@ -1,23 +0,0 @@
from autorecon.plugins import ServiceScan
from shutil import which
class WkHTMLToImage(ServiceScan):
def __init__(self):
super().__init__()
self.name = "wkhtmltoimage"
self.tags = ['default', 'safe', 'http']
def configure(self):
self.match_service_name('^http')
self.match_service_name('^nacn_http$', negative_match=True)
def check(self):
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)')
return False
async def run(self, service):
if which('wkhtmltoimage') is not None:
if service.protocol == 'tcp':
await service.execute('wkhtmltoimage --format png {http_scheme}://{addressv6}:{port}/ {scandir}/{protocol}_{port}_{http_scheme}_screenshot.png')

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.35" VERSION = "2.0.36"
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)
@ -899,6 +899,7 @@ async def run():
parser.add_argument('--proxychains', action='store_true', help='Use if you are running AutoRecon via proxychains. Default: %(default)s') parser.add_argument('--proxychains', action='store_true', help='Use if you are running AutoRecon via proxychains. Default: %(default)s')
parser.add_argument('--disable-sanity-checks', action='store_true', help='Disable sanity checks that would otherwise prevent the scans from running. Default: %(default)s') parser.add_argument('--disable-sanity-checks', action='store_true', help='Disable sanity checks that would otherwise prevent the scans from running. Default: %(default)s')
parser.add_argument('--disable-keyboard-control', action='store_true', help='Disables keyboard control ([s]tatus, Up, Down) if you are in SSH or Docker.') parser.add_argument('--disable-keyboard-control', action='store_true', help='Disables keyboard control ([s]tatus, Up, Down) if you are in SSH or Docker.')
parser.add_argument('--ignore-plugin-checks', action='store_true', help='Ignores errors from plugin check functions that would otherwise prevent AutoRecon from running. Default: %(default)s')
parser.add_argument('--force-services', action='store', nargs='+', metavar='SERVICE', help='A space separated list of services in the following style: tcp/80/http tcp/443/https/secure') parser.add_argument('--force-services', action='store', nargs='+', metavar='SERVICE', help='A space separated list of services in the following style: tcp/80/http tcp/443/https/secure')
parser.add_argument('-mpti', '--max-plugin-target-instances', action='store', nargs='+', metavar='PLUGIN:NUMBER', help='A space separated list of plugin slugs with the max number of instances (per target) in the following style: nmap-http:2 dirbuster:1. Default: %(default)s') parser.add_argument('-mpti', '--max-plugin-target-instances', action='store', nargs='+', metavar='PLUGIN:NUMBER', help='A space separated list of plugin slugs with the max number of instances (per target) in the following style: nmap-http:2 dirbuster:1. Default: %(default)s')
parser.add_argument('-mpgi', '--max-plugin-global-instances', action='store', nargs='+', metavar='PLUGIN:NUMBER', help='A space separated list of plugin slugs with the max number of global instances in the following style: nmap-http:2 dirbuster:1. Default: %(default)s') parser.add_argument('-mpgi', '--max-plugin-global-instances', action='store', nargs='+', metavar='PLUGIN:NUMBER', help='A space separated list of plugin slugs with the max number of global instances in the following style: nmap-http:2 dirbuster:1. Default: %(default)s')
@ -1200,6 +1201,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.')
failed_check_plugin_slugs = []
for slug, plugin in autorecon.plugins.items(): 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]
@ -1210,9 +1212,22 @@ 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':
if plugin.check() == False: if plugin.check() == False:
autorecon.plugins.pop(slug) failed_check_plugin_slugs.append(slug)
continue continue
continue continue
# Check for any failed plugin checks.
for slug in failed_check_plugin_slugs:
# If plugin checks should be ignored, remove the affected plugins at runtime.
if config['ignore_plugin_checks']:
autorecon.plugins.pop(slug)
else:
print()
error('The following plugins failed checks that prevent AutoRecon from running: ' + ','.join(failed_check_plugin_slugs))
error('Check above output to fix these issues, disable relevant plugins, or run AutoRecon with --ignore-plugin-checks to disable failed plugins at runtime.')
print()
errors = True
break
if config['ports']: if config['ports']:
ports_to_scan = {'tcp':[], 'udp':[]} ports_to_scan = {'tcp':[], 'udp':[]}

View File

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