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:
parent
eb003b7f2c
commit
6100333bd7
|
|
@ -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):
|
||||||
|
|
|
||||||
|
|
@ -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')
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue