From ae6967418f6f8341a064e8ad5c7399f5a43daa8f Mon Sep 17 00:00:00 2001 From: Tib3rius <48113936+Tib3rius@users.noreply.github.com> Date: Sat, 11 Sep 2021 23:15:28 -0400 Subject: [PATCH] Added new verbose levels. Changed the TCP specific port scan to "All TCP Ports". --- autorecon.py | 40 ++++++++++++++++++------------------ autorecon/io.py | 15 +++++++------- autorecon/targets.py | 6 ++---- plugins/default-port-scan.py | 28 ++++++++++++------------- 4 files changed, 43 insertions(+), 46 deletions(-) diff --git a/autorecon.py b/autorecon.py index 5edeff8..da490d3 100644 --- a/autorecon.py +++ b/autorecon.py @@ -102,7 +102,7 @@ async def keyboard(): if len(input) >= 3: if input[:3] == '\x1b[A': input = '' - if config['verbose'] == 2: + if config['verbose'] == 3: info('Verbosity is already at the highest level.') else: config['verbose'] += 1 @@ -186,18 +186,18 @@ async def port_scan(plugin, target): if config['ports']['udp']: target.ports['udp'] = ','.join(config['ports']['udp']) if plugin.specific_ports is False: - warn('Port scan {bblue}' + plugin.name + ' {green}(' + plugin.slug + '){rst} cannot be used to scan specific ports, and --ports was used. Skipping.') + warn('Port scan {bblue}' + plugin.name + ' {green}(' + plugin.slug + '){rst} cannot be used to scan specific ports, and --ports was used. Skipping.', verbosity=2) return {'type':'port', 'plugin':plugin, 'result':[]} else: if plugin.type == 'tcp' and not config['ports']['tcp']: - warn('Port scan {bblue}' + plugin.name + ' {green}(' + plugin.slug + '){rst} is a TCP port scan but no TCP ports were set using --ports. Skipping') + warn('Port scan {bblue}' + plugin.name + ' {green}(' + plugin.slug + '){rst} is a TCP port scan but no TCP ports were set using --ports. Skipping', verbosity=2) return {'type':'port', 'plugin':plugin, 'result':[]} elif plugin.type == 'udp' and not config['ports']['udp']: - warn('Port scan {bblue}' + plugin.name + ' {green}(' + plugin.slug + '){rst} is a UDP port scan but no UDP ports were set using --ports. Skipping') + warn('Port scan {bblue}' + plugin.name + ' {green}(' + plugin.slug + '){rst} is a UDP port scan but no UDP ports were set using --ports. Skipping', verbosity=2) return {'type':'port', 'plugin':plugin, 'result':[]} async with target.autorecon.port_scan_semaphore: - info('Port scan {bblue}' + plugin.name + ' {green}(' + plugin.slug + '){rst} running against {byellow}' + target.address + '{rst}') + info('Port scan {bblue}' + plugin.name + ' {green}(' + plugin.slug + '){rst} running against {byellow}' + target.address + '{rst}', verbosity=1) start_time = time.time() @@ -213,7 +213,7 @@ async def port_scan(plugin, target): for process_dict in target.running_tasks[plugin.slug]['processes']: if process_dict['process'].returncode is None: - warn('A process was left running after port scan {bblue}' + plugin.name + ' {green}(' + plugin.slug + '){rst} against {byellow}' + target.address + '{rst} finished. Please ensure non-blocking processes are awaited before the run coroutine finishes. Awaiting now.') + warn('A process was left running after port scan {bblue}' + plugin.name + ' {green}(' + plugin.slug + '){rst} against {byellow}' + target.address + '{rst} finished. Please ensure non-blocking processes are awaited before the run coroutine finishes. Awaiting now.', verbosity=2) await process_dict['process'].wait() if process_dict['process'].returncode != 0: @@ -224,7 +224,7 @@ async def port_scan(plugin, target): errors.append(line + '\n') else: break - error('Port scan {bblue}' + plugin.name + ' {green}(' + plugin.slug + '){rst} ran a command against {byellow}' + target.address + '{rst} which returned a non-zero exit code (' + str(process_dict['process'].returncode) + '). Check ' + target.scandir + '/_errors.log for more details.') + error('Port scan {bblue}' + plugin.name + ' {green}(' + plugin.slug + '){rst} ran a command against {byellow}' + target.address + '{rst} which returned a non-zero exit code (' + str(process_dict['process'].returncode) + '). Check ' + target.scandir + '/_errors.log for more details.', verbosity=2) async with target.lock: with open(os.path.join(target.scandir, '_errors.log'), 'a') as file: file.writelines('[*] Port scan ' + plugin.name + ' (' + plugin.slug + ') ran a command which returned a non-zero exit code (' + str(process_dict['process'].returncode) + ').\n') @@ -239,7 +239,7 @@ async def port_scan(plugin, target): async with target.lock: target.running_tasks.pop(plugin.slug, None) - info('Port scan {bblue}' + plugin.name + ' {green}(' + plugin.slug + '){rst} against {byellow}' + target.address + '{rst} finished in ' + elapsed_time) + info('Port scan {bblue}' + plugin.name + ' {green}(' + plugin.slug + '){rst} against {byellow}' + target.address + '{rst} finished in ' + elapsed_time, verbosity=2) return {'type':'port', 'plugin':plugin, 'result':result} async def service_scan(plugin, service): @@ -285,7 +285,7 @@ async def service_scan(plugin, service): tag = service.tag() + '/' + plugin.slug - info('Service scan {bblue}' + plugin.name + ' {green}(' + tag + '){rst} running against {byellow}' + service.target.address + '{rst}') + info('Service scan {bblue}' + plugin.name + ' {green}(' + tag + '){rst} running against {byellow}' + service.target.address + '{rst}', verbosity=1) start_time = time.time() @@ -301,7 +301,7 @@ async def service_scan(plugin, service): for process_dict in service.target.running_tasks[tag]['processes']: if process_dict['process'].returncode is None: - warn('A process was left running after service scan {bblue}' + plugin.name + ' {green}(' + tag + '){rst} against {byellow}' + service.target.address + '{rst} finished. Please ensure non-blocking processes are awaited before the run coroutine finishes. Awaiting now.') + warn('A process was left running after service scan {bblue}' + plugin.name + ' {green}(' + tag + '){rst} against {byellow}' + service.target.address + '{rst} finished. Please ensure non-blocking processes are awaited before the run coroutine finishes. Awaiting now.', verbosity=2) await process_dict['process'].wait() if process_dict['process'].returncode != 0: @@ -312,7 +312,7 @@ async def service_scan(plugin, service): errors.append(line + '\n') else: break - error('Service scan {bblue}' + plugin.name + ' {green}(' + tag + '){rst} ran a command against {byellow}' + service.target.address + '{rst} which returned a non-zero exit code (' + str(process_dict['process'].returncode) + '). Check ' + service.target.scandir + '/_errors.log for more details.') + error('Service scan {bblue}' + plugin.name + ' {green}(' + tag + '){rst} ran a command against {byellow}' + service.target.address + '{rst} which returned a non-zero exit code (' + str(process_dict['process'].returncode) + '). Check ' + service.target.scandir + '/_errors.log for more details.', verbosity=2) async with service.target.lock: with open(os.path.join(service.target.scandir, '_errors.log'), 'a') as file: file.writelines('[*] Service scan ' + plugin.name + ' (' + tag + ') ran a command which returned a non-zero exit code (' + str(process_dict['process'].returncode) + ').\n') @@ -327,7 +327,7 @@ async def service_scan(plugin, service): async with service.target.lock: service.target.running_tasks.pop(tag, None) - info('Service scan {bblue}' + plugin.name + ' {green}(' + tag + '){rst} against {byellow}' + service.target.address + '{rst} finished in ' + elapsed_time) + info('Service scan {bblue}' + plugin.name + ' {green}(' + tag + '){rst} against {byellow}' + service.target.address + '{rst} finished in ' + elapsed_time, verbosity=2) return {'type':'service', 'plugin':plugin, 'result':result} async def generate_report(plugin, targets): @@ -394,7 +394,7 @@ async def scan_target(target): if match: protocol = match.group('protocol') if config['proxychains'] and protocol == 'udp': - error('The service ' + forced_service + ' uses UDP and --proxychains is enabled. Skipping.') + error('The service ' + forced_service + ' uses UDP and --proxychains is enabled. Skipping.', verbosity=2) continue port = int(match.group('port')) service = match.group('service') @@ -481,7 +481,7 @@ async def scan_target(target): else: continue - info('Identified service {bmagenta}' + service.name + '{rst} on {bmagenta}' + service.protocol + '/' + str(service.port) + '{rst} on {byellow}' + target.address + '{rst}') + info('Identified service {bmagenta}' + service.name + '{rst} on {bmagenta}' + service.protocol + '/' + str(service.port) + '{rst} on {byellow}' + target.address + '{rst}', verbosity=1) if not config['only_scans_dir']: with open(os.path.join(target.reportdir, 'notes.txt'), 'a') as file: @@ -575,7 +575,7 @@ async def scan_target(target): for s in target.scans['services']: if plugin.slug in target.scans['services'][s]: plugin_queued = True - warn('{byellow}[' + plugin_tag + ' against ' + target.address + ']{srst} Plugin should only be run once and it appears to have already been queued. Skipping.{rst}') + warn('{byellow}[' + plugin_tag + ' against ' + target.address + ']{srst} Plugin should only be run once and it appears to have already been queued. Skipping.{rst}', verbosity=2) break if plugin_queued: break @@ -588,18 +588,18 @@ async def scan_target(target): # Skip plugin if service port is in ignore_ports: if port in plugin.ignore_ports[protocol]: plugin_service_match = False - warn('{byellow}[' + plugin_tag + ' against ' + target.address + ']{srst} Plugin cannot be run against ' + protocol + ' port ' + str(port) + '. Skipping.{rst}') + warn('{byellow}[' + plugin_tag + ' against ' + target.address + ']{srst} Plugin cannot be run against ' + protocol + ' port ' + str(port) + '. Skipping.{rst}', verbosity=2) break # Skip plugin if plugin has required ports and service port is not in them: if plugin.ports[protocol] and port not in plugin.ports[protocol]: plugin_service_match = False - warn('{byellow}[' + plugin_tag + ' against ' + target.address + ']{srst} Plugin can only run on specific ports. Skipping.{rst}') + warn('{byellow}[' + plugin_tag + ' against ' + target.address + ']{srst} Plugin can only run on specific ports. Skipping.{rst}', verbosity=2) break for i in plugin.ignore_service_names: if re.search(i, service.name): - warn('{byellow}[' + plugin_tag + ' against ' + target.address + ']{srst} Plugin cannot be run against this service. Skipping.{rst}') + warn('{byellow}[' + plugin_tag + ' against ' + target.address + ']{srst} Plugin cannot be run against this service. Skipping.{rst}', verbosity=2) break # TODO: check if plugin matches tags, BUT run manual commands anyway! @@ -646,7 +646,7 @@ async def scan_target(target): for s in target.scans['services']: if plugin_tag in target.scans['services'][s]: plugin_queued = True - warn('{byellow}[' + plugin_tag + ' against ' + target.address + ']{srst} Plugin appears to have already been queued, but it is not marked as run_once. Possible duplicate service tag? Skipping.{rst}') + warn('{byellow}[' + plugin_tag + ' against ' + target.address + ']{srst} Plugin appears to have already been queued, but it is not marked as run_once. Possible duplicate service tag? Skipping.{rst}', verbosity=2) break if plugin_queued: @@ -659,7 +659,7 @@ async def scan_target(target): pending.add(asyncio.create_task(service_scan(plugin, service))) if not service_match: - warn('{byellow}[' + target.address + ']{srst} Service ' + service.full_tag() + ' did not match any plugins based on the service name.{rst}') + warn('{byellow}[' + target.address + ']{srst} Service ' + service.full_tag() + ' did not match any plugins based on the service name.{rst}', verbosity=2) if service.full_tag() not in target.autorecon.missing_services: target.autorecon.missing_services.append(service.full_tag()) diff --git a/autorecon/io.py b/autorecon/io.py index 5d0c574..a813a6a 100644 --- a/autorecon/io.py +++ b/autorecon/io.py @@ -19,7 +19,9 @@ def e(*args, frame_index=1, **kvargs): def fformat(s): return e(s, frame_index=3) -def cprint(*args, color=Fore.RESET, char='*', sep=' ', end='\n', frame_index=1, file=sys.stdout, printmsg=True, **kvargs): +def cprint(*args, color=Fore.RESET, char='*', sep=' ', end='\n', frame_index=1, file=sys.stdout, printmsg=True, verbosity=0, **kvargs): + if printmsg and verbosity > config['verbose']: + return '' frame = sys._getframe(frame_index) vals = { @@ -119,9 +121,8 @@ class CommandStreamReader(object): error('{bright}[{yellow}' + self.target.address + '{crst}/{bgreen}' + self.tag + '{crst}]{rst} A line was longer than 64 KiB and cannot be processed. Ignoring.') continue - if config['verbose'] >= 2: - if line != '': - info('{bright}[{yellow}' + self.target.address + '{crst}/{bgreen}' + self.tag + '{crst}]{rst} ' + line.replace('{', '{{').replace('}', '}}')) + if line != '': + info('{bright}[{yellow}' + self.target.address + '{crst}/{bgreen}' + self.tag + '{crst}]{rst} ' + line.replace('{', '{{').replace('}', '}}'), verbosity=3) # Check lines for pattern matches. for p in self.patterns: @@ -130,12 +131,10 @@ class CommandStreamReader(object): async with self.target.lock: with open(os.path.join(self.target.scandir, '_patterns.log'), 'a') as file: if p.description: - if config['verbose'] >= 1: - info('{bright}[{yellow}' + self.target.address + '{crst}/{bgreen}' + self.tag + '{crst}]{rst} {bmagenta}' + p.description.replace('{match}', match) + '{rst}') + info('{bright}[{yellow}' + self.target.address + '{crst}/{bgreen}' + self.tag + '{crst}]{rst} {bmagenta}' + p.description.replace('{match}', match) + '{rst}', verbosity=2) file.writelines(p.description.replace('{match}', match) + '\n\n') else: - if config['verbose'] >= 1: - info('{bright}[{yellow}' + self.target.address + '{crst}/{bgreen}' + self.tag + '{crst}]{rst} {bmagenta}Matched Pattern: ' + match + '{rst}') + info('{bright}[{yellow}' + self.target.address + '{crst}/{bgreen}' + self.tag + '{crst}]{rst} {bmagenta}Matched Pattern: ' + match + '{rst}', verbosity=2) file.writelines('Matched Pattern: ' + match + '\n\n') if self.outfile is not None: diff --git a/autorecon/targets.py b/autorecon/targets.py index 1cc03e7..014ef71 100644 --- a/autorecon/targets.py +++ b/autorecon/targets.py @@ -59,8 +59,7 @@ class Target: cmd = e(cmd) tag = plugin.slug - if config['verbose'] >= 1: - info('Port scan {bblue}' + plugin.name + ' {green}(' + tag + '){rst} is running the following command against {byellow}' + address + '{rst}: ' + cmd) + info('Port scan {bblue}' + plugin.name + ' {green}(' + tag + '){rst} is running the following command against {byellow}' + address + '{rst}: ' + cmd, verbosity=2) if outfile is not None: outfile = os.path.join(target.scandir, e(outfile)) @@ -166,8 +165,7 @@ class Service: if plugin.run_once_boolean: plugin_tag = plugin.slug - if config['verbose'] >= 1: - info('Service scan {bblue}' + plugin.name + ' {green}(' + tag + '){rst} is running the following command against {byellow}' + address + '{rst}: ' + cmd) + info('Service scan {bblue}' + plugin.name + ' {green}(' + tag + '){rst} is running the following command against {byellow}' + address + '{rst}: ' + cmd, verbosity=2) if outfile is not None: outfile = os.path.join(scandir, e(outfile)) diff --git a/plugins/default-port-scan.py b/plugins/default-port-scan.py index f9ff930..8a4036d 100644 --- a/plugins/default-port-scan.py +++ b/plugins/default-port-scan.py @@ -10,23 +10,19 @@ class QuickTCPPortScan(PortScan): self.name = 'Top TCP Ports' self.description = 'Performs an Nmap scan of the top 1000 TCP ports.' self.type = 'tcp' - self.specific_ports = True self.tags = ['default', 'default-port-scan'] self.priority = 0 async def run(self, target): + if target.ports: # Don't run this plugin if there are custom ports. + return [] + if config['proxychains']: traceroute_os = '' else: traceroute_os = ' -A --osscan-guess' - if target.ports: - if target.ports['tcp']: - process, stdout, stderr = await target.execute('nmap {nmap_extra} -sV -sC --version-all' + traceroute_os + ' -p ' + target.ports['tcp'] + ' -oN "{scandir}/_custom_ports_tcp_nmap.txt" -oX "{scandir}/xml/_custom_ports_tcp_nmap.xml" {address}', blocking=False) - else: - return [] - else: - process, stdout, stderr = await target.execute('nmap {nmap_extra} -sV -sC --version-all' + traceroute_os + ' -oN "{scandir}/_quick_tcp_nmap.txt" -oX "{scandir}/xml/_quick_tcp_nmap.xml" {address}', blocking=False) + process, stdout, stderr = await target.execute('nmap {nmap_extra} -sV -sC --version-all' + traceroute_os + ' -oN "{scandir}/_quick_tcp_nmap.txt" -oX "{scandir}/xml/_quick_tcp_nmap.xml" {address}', blocking=False) services = await target.extract_services(stdout) await process.wait() return services @@ -38,25 +34,29 @@ class AllTCPPortScan(PortScan): self.name = 'All TCP Ports' self.description = 'Performs an Nmap scan of all TCP ports.' self.type = 'tcp' + self.specific_ports = True self.tags = ['default', 'default-port-scan', 'long'] async def run(self, target): - if target.ports: # Don't run this plugin if there are custom ports. - return [] - if config['proxychains']: traceroute_os = '' else: traceroute_os = ' -A --osscan-guess' - process, stdout, stderr = await target.execute('nmap {nmap_extra} -sV -sC --version-all' + traceroute_os + ' -p- -oN "{scandir}/_full_tcp_nmap.txt" -oX "{scandir}/xml/_full_tcp_nmap.xml" {address}', blocking=False) + if target.ports: + if target.ports['tcp']: + process, stdout, stderr = await target.execute('nmap {nmap_extra} -sV -sC --version-all' + traceroute_os + ' -p ' + target.ports['tcp'] + ' -oN "{scandir}/_full_tcp_nmap.txt" -oX "{scandir}/xml/_full_tcp_nmap.xml" {address}', blocking=False) + else: + return [] + else: + process, stdout, stderr = await target.execute('nmap {nmap_extra} -sV -sC --version-all' + traceroute_os + ' -p- -oN "{scandir}/_full_tcp_nmap.txt" -oX "{scandir}/xml/_full_tcp_nmap.xml" {address}', blocking=False) services = [] while True: line = await stdout.readline() if line is not None: match = re.search('^Discovered open port ([0-9]+)/tcp', line) if match: - info('Discovered open port {bmagenta}tcp/' + match.group(1) + '{rst} on {byellow}' + target.address + '{rst}') + info('Discovered open port {bmagenta}tcp/' + match.group(1) + '{rst} on {byellow}' + target.address + '{rst}', verbosity=1) service = target.extract_service(line) if service: services.append(service) @@ -91,7 +91,7 @@ class Top100UDPPortScan(PortScan): if line is not None: match = re.search('^Discovered open port ([0-9]+)/udp', line) if match: - info('Discovered open port {bmagenta}udp/' + match.group(1) + '{rst} on {byellow}' + target.address + '{rst}') + info('Discovered open port {bmagenta}udp/' + match.group(1) + '{rst} on {byellow}' + target.address + '{rst}', verbosity=1) service = target.extract_service(line) if service: services.append(service)