Added new verbose levels.

Changed the TCP specific port scan to "All TCP Ports".
This commit is contained in:
Tib3rius 2021-09-11 23:15:28 -04:00
parent 5b05260c19
commit ae6967418f
4 changed files with 43 additions and 46 deletions

View File

@ -102,7 +102,7 @@ async def keyboard():
if len(input) >= 3: if len(input) >= 3:
if input[:3] == '\x1b[A': if input[:3] == '\x1b[A':
input = '' input = ''
if config['verbose'] == 2: if config['verbose'] == 3:
info('Verbosity is already at the highest level.') info('Verbosity is already at the highest level.')
else: else:
config['verbose'] += 1 config['verbose'] += 1
@ -186,18 +186,18 @@ async def port_scan(plugin, target):
if config['ports']['udp']: if config['ports']['udp']:
target.ports['udp'] = ','.join(config['ports']['udp']) target.ports['udp'] = ','.join(config['ports']['udp'])
if plugin.specific_ports is False: 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':[]} return {'type':'port', 'plugin':plugin, 'result':[]}
else: else:
if plugin.type == 'tcp' and not config['ports']['tcp']: 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':[]} return {'type':'port', 'plugin':plugin, 'result':[]}
elif plugin.type == 'udp' and not config['ports']['udp']: 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':[]} return {'type':'port', 'plugin':plugin, 'result':[]}
async with target.autorecon.port_scan_semaphore: 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() start_time = time.time()
@ -213,7 +213,7 @@ async def port_scan(plugin, target):
for process_dict in target.running_tasks[plugin.slug]['processes']: for process_dict in target.running_tasks[plugin.slug]['processes']:
if process_dict['process'].returncode is None: 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() await process_dict['process'].wait()
if process_dict['process'].returncode != 0: if process_dict['process'].returncode != 0:
@ -224,7 +224,7 @@ async def port_scan(plugin, target):
errors.append(line + '\n') errors.append(line + '\n')
else: else:
break 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: async with target.lock:
with open(os.path.join(target.scandir, '_errors.log'), 'a') as file: 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') 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: async with target.lock:
target.running_tasks.pop(plugin.slug, None) 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} return {'type':'port', 'plugin':plugin, 'result':result}
async def service_scan(plugin, service): async def service_scan(plugin, service):
@ -285,7 +285,7 @@ async def service_scan(plugin, service):
tag = service.tag() + '/' + plugin.slug 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() start_time = time.time()
@ -301,7 +301,7 @@ async def service_scan(plugin, service):
for process_dict in service.target.running_tasks[tag]['processes']: for process_dict in service.target.running_tasks[tag]['processes']:
if process_dict['process'].returncode is None: 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() await process_dict['process'].wait()
if process_dict['process'].returncode != 0: if process_dict['process'].returncode != 0:
@ -312,7 +312,7 @@ async def service_scan(plugin, service):
errors.append(line + '\n') errors.append(line + '\n')
else: else:
break 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: async with service.target.lock:
with open(os.path.join(service.target.scandir, '_errors.log'), 'a') as file: 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') 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: async with service.target.lock:
service.target.running_tasks.pop(tag, None) 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} return {'type':'service', 'plugin':plugin, 'result':result}
async def generate_report(plugin, targets): async def generate_report(plugin, targets):
@ -394,7 +394,7 @@ async def scan_target(target):
if match: if match:
protocol = match.group('protocol') protocol = match.group('protocol')
if config['proxychains'] and protocol == 'udp': 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 continue
port = int(match.group('port')) port = int(match.group('port'))
service = match.group('service') service = match.group('service')
@ -481,7 +481,7 @@ async def scan_target(target):
else: else:
continue 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']: if not config['only_scans_dir']:
with open(os.path.join(target.reportdir, 'notes.txt'), 'a') as file: 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']: for s in target.scans['services']:
if plugin.slug in target.scans['services'][s]: if plugin.slug in target.scans['services'][s]:
plugin_queued = True 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 break
if plugin_queued: if plugin_queued:
break break
@ -588,18 +588,18 @@ async def scan_target(target):
# Skip plugin if service port is in ignore_ports: # Skip plugin if service port is in ignore_ports:
if port in plugin.ignore_ports[protocol]: if port in plugin.ignore_ports[protocol]:
plugin_service_match = False 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 break
# Skip plugin if plugin has required ports and service port is not in them: # 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]: if plugin.ports[protocol] and port not in plugin.ports[protocol]:
plugin_service_match = False 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 break
for i in plugin.ignore_service_names: for i in plugin.ignore_service_names:
if re.search(i, service.name): 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 break
# TODO: check if plugin matches tags, BUT run manual commands anyway! # 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']: for s in target.scans['services']:
if plugin_tag in target.scans['services'][s]: if plugin_tag in target.scans['services'][s]:
plugin_queued = True 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 break
if plugin_queued: if plugin_queued:
@ -659,7 +659,7 @@ async def scan_target(target):
pending.add(asyncio.create_task(service_scan(plugin, service))) pending.add(asyncio.create_task(service_scan(plugin, service)))
if not service_match: 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: if service.full_tag() not in target.autorecon.missing_services:
target.autorecon.missing_services.append(service.full_tag()) target.autorecon.missing_services.append(service.full_tag())

View File

@ -19,7 +19,9 @@ def e(*args, frame_index=1, **kvargs):
def fformat(s): def fformat(s):
return e(s, frame_index=3) 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) frame = sys._getframe(frame_index)
vals = { 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.') 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 continue
if config['verbose'] >= 2: if line != '':
if line != '': info('{bright}[{yellow}' + self.target.address + '{crst}/{bgreen}' + self.tag + '{crst}]{rst} ' + line.replace('{', '{{').replace('}', '}}'), verbosity=3)
info('{bright}[{yellow}' + self.target.address + '{crst}/{bgreen}' + self.tag + '{crst}]{rst} ' + line.replace('{', '{{').replace('}', '}}'))
# Check lines for pattern matches. # Check lines for pattern matches.
for p in self.patterns: for p in self.patterns:
@ -130,12 +131,10 @@ class CommandStreamReader(object):
async with self.target.lock: async with self.target.lock:
with open(os.path.join(self.target.scandir, '_patterns.log'), 'a') as file: with open(os.path.join(self.target.scandir, '_patterns.log'), 'a') as file:
if p.description: 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}', verbosity=2)
info('{bright}[{yellow}' + self.target.address + '{crst}/{bgreen}' + self.tag + '{crst}]{rst} {bmagenta}' + p.description.replace('{match}', match) + '{rst}')
file.writelines(p.description.replace('{match}', match) + '\n\n') file.writelines(p.description.replace('{match}', match) + '\n\n')
else: else:
if config['verbose'] >= 1: info('{bright}[{yellow}' + self.target.address + '{crst}/{bgreen}' + self.tag + '{crst}]{rst} {bmagenta}Matched Pattern: ' + match + '{rst}', verbosity=2)
info('{bright}[{yellow}' + self.target.address + '{crst}/{bgreen}' + self.tag + '{crst}]{rst} {bmagenta}Matched Pattern: ' + match + '{rst}')
file.writelines('Matched Pattern: ' + match + '\n\n') file.writelines('Matched Pattern: ' + match + '\n\n')
if self.outfile is not None: if self.outfile is not None:

View File

@ -59,8 +59,7 @@ class Target:
cmd = e(cmd) cmd = e(cmd)
tag = plugin.slug 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, verbosity=2)
info('Port scan {bblue}' + plugin.name + ' {green}(' + tag + '){rst} is running the following command against {byellow}' + address + '{rst}: ' + cmd)
if outfile is not None: if outfile is not None:
outfile = os.path.join(target.scandir, e(outfile)) outfile = os.path.join(target.scandir, e(outfile))
@ -166,8 +165,7 @@ class Service:
if plugin.run_once_boolean: if plugin.run_once_boolean:
plugin_tag = plugin.slug 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, verbosity=2)
info('Service scan {bblue}' + plugin.name + ' {green}(' + tag + '){rst} is running the following command against {byellow}' + address + '{rst}: ' + cmd)
if outfile is not None: if outfile is not None:
outfile = os.path.join(scandir, e(outfile)) outfile = os.path.join(scandir, e(outfile))

View File

@ -10,23 +10,19 @@ class QuickTCPPortScan(PortScan):
self.name = 'Top TCP Ports' self.name = 'Top TCP Ports'
self.description = 'Performs an Nmap scan of the top 1000 TCP ports.' self.description = 'Performs an Nmap scan of the top 1000 TCP ports.'
self.type = 'tcp' self.type = 'tcp'
self.specific_ports = True
self.tags = ['default', 'default-port-scan'] self.tags = ['default', 'default-port-scan']
self.priority = 0 self.priority = 0
async def run(self, target): async def run(self, target):
if target.ports: # Don't run this plugin if there are custom ports.
return []
if config['proxychains']: if config['proxychains']:
traceroute_os = '' traceroute_os = ''
else: else:
traceroute_os = ' -A --osscan-guess' traceroute_os = ' -A --osscan-guess'
if target.ports: 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)
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)
services = await target.extract_services(stdout) services = await target.extract_services(stdout)
await process.wait() await process.wait()
return services return services
@ -38,25 +34,29 @@ class AllTCPPortScan(PortScan):
self.name = 'All TCP Ports' self.name = 'All TCP Ports'
self.description = 'Performs an Nmap scan of all TCP ports.' self.description = 'Performs an Nmap scan of all TCP ports.'
self.type = 'tcp' self.type = 'tcp'
self.specific_ports = True
self.tags = ['default', 'default-port-scan', 'long'] self.tags = ['default', 'default-port-scan', 'long']
async def run(self, target): async def run(self, target):
if target.ports: # Don't run this plugin if there are custom ports.
return []
if config['proxychains']: if config['proxychains']:
traceroute_os = '' traceroute_os = ''
else: else:
traceroute_os = ' -A --osscan-guess' 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 = [] services = []
while True: while True:
line = await stdout.readline() line = await stdout.readline()
if line is not None: if line is not None:
match = re.search('^Discovered open port ([0-9]+)/tcp', line) match = re.search('^Discovered open port ([0-9]+)/tcp', line)
if match: 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) service = target.extract_service(line)
if service: if service:
services.append(service) services.append(service)
@ -91,7 +91,7 @@ class Top100UDPPortScan(PortScan):
if line is not None: if line is not None:
match = re.search('^Discovered open port ([0-9]+)/udp', line) match = re.search('^Discovered open port ([0-9]+)/udp', line)
if match: 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) service = target.extract_service(line)
if service: if service:
services.append(service) services.append(service)