Fixed / improved pattern matching.

{match} will output as the entire matched string. {match1} will output as the first matched group. {match2} etc.
This commit is contained in:
Tib3rius 2022-01-18 20:00:33 -05:00
parent eb003b7f2c
commit 6100333bd7
6 changed files with 42 additions and 23 deletions

View File

@ -14,7 +14,7 @@ class NmapHTTP(ServiceScan):
def configure(self): def configure(self):
self.match_service_name('^http') self.match_service_name('^http')
self.match_service_name('^nacn_http$', negative_match=True) self.match_service_name('^nacn_http$', negative_match=True)
self.add_pattern('Server: ([^\n]+)', description='Identified HTTP Server: {match}') self.add_pattern('Server: ([^\n]+)', description='Identified HTTP Server: {match1}')
self.add_pattern('WebDAV is ENABLED', description='WebDAV is enabled') self.add_pattern('WebDAV is ENABLED', description='WebDAV is enabled')
async def run(self, service): async def run(self, service):

View File

@ -51,7 +51,7 @@ class GetArch(ServiceScan):
def configure(self): def configure(self):
self.match_service_name(['^msrpc']) self.match_service_name(['^msrpc'])
self.match_port('tcp', 135) self.match_port('tcp', 135)
self.add_pattern(' is ((32|64)-bit)', description='Identified Architecture: {match}') self.add_pattern(' is ((32|64)-bit)', description='Identified Architecture: {match1}')
async def run(self, service): async def run(self, service):
await service.execute('getArch.py -target {address}', outfile='{protocol}_{port}_rpc_architecture.txt') await service.execute('getArch.py -target {address}', outfile='{protocol}_{port}_rpc_architecture.txt')

View File

@ -53,11 +53,26 @@ class Enum4Linux(ServiceScan):
if service.target.ipversion == 'IPv4': if service.target.ipversion == 'IPv4':
await service.execute('enum4linux -a -M -l -d {address} 2>&1', outfile='enum4linux.txt') await service.execute('enum4linux -a -M -l -d {address} 2>&1', outfile='enum4linux.txt')
class LookupSID(ServiceScan):
def __init__(self):
super().__init__()
self.name = 'lookupsid'
self.tags = ['default', 'safe', 'active-directory']
def configure(self):
self.match_service('tcp', 445, '^microsoft\-ds')
def manual(self, service, plugin_was_run):
service.add_manual_command('Lookup SIDs', [
'lookupsid.py [username]:[password]@{address}'
])
class NBTScan(ServiceScan): class NBTScan(ServiceScan):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.name = "nbtscan" self.name = 'nbtscan'
self.tags = ['default', 'safe', 'netbios', 'active-directory'] self.tags = ['default', 'safe', 'netbios', 'active-directory']
def configure(self): def configure(self):

View File

@ -126,30 +126,34 @@ class CommandStreamReader(object):
# Check lines for pattern matches. # Check lines for pattern matches.
for p in self.patterns: for p in self.patterns:
matches = p.pattern.findall(line)
if len(matches) > 0 and isinstance(matches[0], tuple):
matches = list(matches[0])
match_count = 1
description = '' description = ''
for match in matches:
# Match and replace entire pattern.
match = p.pattern.search(line)
if match:
if p.description: if p.description:
if match_count == 1: description = p.description.replace('{match}', line[match.start():match.end()])
description = p.description.replace('{match}', match)
description = description.replace('{match' + str(match_count) + '}', match) # Match and replace substrings.
else: matches = p.pattern.findall(line)
info('{bright}[{yellow}' + self.target.address + '{crst}/{bgreen}' + self.tag + '{crst}]{rst} {bmagenta}Matched Pattern: ' + match + '{rst}', verbosity=2) if len(matches) > 0 and isinstance(matches[0], tuple):
matches = list(matches[0])
match_count = 1
for match in matches:
if p.description:
description = description.replace('{match' + str(match_count) + '}', match)
match_count += 1
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:
file.writelines('Matched Pattern: ' + match + '\n\n')
match_count += 1
if matches:
async with self.target.lock:
with open(os.path.join(self.target.scandir, '_patterns.log'), 'a') as file:
if p.description:
info('{bright}[{yellow}' + self.target.address + '{crst}/{bgreen}' + self.tag + '{crst}]{rst} {bmagenta}' + description + '{rst}', verbosity=2) info('{bright}[{yellow}' + self.target.address + '{crst}/{bgreen}' + self.tag + '{crst}]{rst} {bmagenta}' + description + '{rst}', verbosity=2)
file.writelines(description + '\n\n') file.writelines(description + '\n\n')
else:
info('{bright}[{yellow}' + self.target.address + '{crst}/{bgreen}' + self.tag + '{crst}]{rst} {bmagenta}Matched Pattern: ' + line[match.start():match.end()] + '{rst}', verbosity=2)
async with self.target.lock:
with open(os.path.join(self.target.scandir, '_patterns.log'), 'a') as file:
file.writelines('Matched Pattern: ' + line[match.start():match.end()] + '\n\n')
if self.outfile is not None: if self.outfile is not None:
with open(self.outfile, 'a') as writer: with open(self.outfile, 'a') as writer:

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.13" VERSION = "2.0.14"
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)

View File

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