Updates & Bug Fixes
Updated global option parsing to allow default None values by removing the "default=" setting. Added a match_service() function to ServiceScan plugins to match combinations of protocol/port/name. Fixed bug in status times. Removed defaul from global.domain. Added new WinRM detection plugin.
This commit is contained in:
parent
182b071444
commit
b60fcfc9ca
56
autorecon.py
56
autorecon.py
|
@ -288,7 +288,13 @@ class Plugin(object):
|
|||
name = 'global.' + slugify(name).replace('-', '_')
|
||||
|
||||
if name in vars(self.autorecon.args):
|
||||
return vars(self.autorecon.args)[name]
|
||||
if vars(self.autorecon.args)[name] is None:
|
||||
if default:
|
||||
return default
|
||||
else:
|
||||
return None
|
||||
else:
|
||||
return vars(self.autorecon.args)[name]
|
||||
else:
|
||||
if default:
|
||||
return default
|
||||
|
@ -323,12 +329,42 @@ class ServiceScan(Plugin):
|
|||
super().__init__()
|
||||
self.ports = {'tcp':[], 'udp':[]}
|
||||
self.ignore_ports = {'tcp':[], 'udp':[]}
|
||||
self.services = []
|
||||
self.service_names = []
|
||||
self.ignore_service_names = []
|
||||
self.match_all_service_names_boolean = False
|
||||
self.run_once_boolean = False
|
||||
self.require_ssl_boolean = False
|
||||
|
||||
@final
|
||||
def match_service(self, protocol, port, name, negative_match=False):
|
||||
protocol = protocol.lower()
|
||||
if protocol not in ['tcp', 'udp']:
|
||||
print('Invalid protocol.')
|
||||
sys.exit(1)
|
||||
|
||||
if not isinstance(port, list):
|
||||
port = [port]
|
||||
|
||||
port = list(map(int, port))
|
||||
|
||||
if not isinstance(name, list):
|
||||
name = [name]
|
||||
|
||||
valid_regex = True
|
||||
for r in name:
|
||||
try:
|
||||
re.compile(r)
|
||||
except re.error:
|
||||
print('Invalid regex: ' + r)
|
||||
valid_regex = False
|
||||
|
||||
if not valid_regex:
|
||||
sys.exit(1)
|
||||
|
||||
service = {'protocol': protocol, 'port': port, 'name': name, 'negative_match': negative_match}
|
||||
self.services.append(service)
|
||||
|
||||
@final
|
||||
def match_port(self, protocol, port, negative_match=False):
|
||||
protocol = protocol.lower()
|
||||
|
@ -673,7 +709,7 @@ def calculate_elapsed_time(start_time, short=False):
|
|||
|
||||
elapsed_time = []
|
||||
if short:
|
||||
elapsed_time.append(str(h))
|
||||
elapsed_time.append(str(h).zfill(2))
|
||||
else:
|
||||
if h == 1:
|
||||
elapsed_time.append(str(h) + ' hour')
|
||||
|
@ -681,7 +717,7 @@ def calculate_elapsed_time(start_time, short=False):
|
|||
elapsed_time.append(str(h) + ' hours')
|
||||
|
||||
if short:
|
||||
elapsed_time.append(str(m))
|
||||
elapsed_time.append(str(m).zfill(2))
|
||||
else:
|
||||
if m == 1:
|
||||
elapsed_time.append(str(m) + ' minute')
|
||||
|
@ -689,7 +725,7 @@ def calculate_elapsed_time(start_time, short=False):
|
|||
elapsed_time.append(str(m) + ' minutes')
|
||||
|
||||
if short:
|
||||
elapsed_time.append(str(s))
|
||||
elapsed_time.append(str(s).zfill(2))
|
||||
else:
|
||||
if s == 1:
|
||||
elapsed_time.append(str(s) + ' second')
|
||||
|
@ -1069,6 +1105,18 @@ async def scan_target(target):
|
|||
plugin_service_match = False
|
||||
plugin_tag = service.tag() + '/' + plugin.slug
|
||||
|
||||
for service_dict in plugin.services:
|
||||
if service_dict['protocol'] == protocol and port in service_dict['port']:
|
||||
for name in service_dict['name']:
|
||||
if service_dict['negative_match']:
|
||||
if name not in plugin.ignore_service_names:
|
||||
plugin.ignore_service_names.append(name)
|
||||
else:
|
||||
if name not in plugin.service_names:
|
||||
plugin.service_names.append(name)
|
||||
else:
|
||||
continue
|
||||
|
||||
for s in plugin.service_names:
|
||||
if re.search(s, service.name):
|
||||
plugin_service_match = True
|
||||
|
|
|
@ -7,5 +7,4 @@ default = '/usr/share/seclists/Passwords/darkweb2017-top100.txt'
|
|||
help = 'A wordlist of passwords, useful for bruteforcing. Default: %(default)s'
|
||||
|
||||
[global.domain]
|
||||
default = false
|
||||
help = 'The domain to use (if known). Used for DNS and/or Active Directory.'
|
||||
help = 'The domain to use (if known). Used for DNS and/or Active Directory. Default: %(default)s'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from autorecon import ServiceScan
|
||||
from autorecon import ServiceScan, fformat
|
||||
|
||||
class NmapCassandra(ServiceScan):
|
||||
|
||||
|
@ -142,3 +142,33 @@ class NmapVNC(ServiceScan):
|
|||
|
||||
async def run(self, service):
|
||||
await service.execute('nmap {nmap_extra} -sV -p {port} --script="banner,(vnc* or realvnc* or ssl*) and not (brute or broadcast or dos or external or fuzzer)" --script-args="unsafe=1" -oN "{scandir}/{protocol}_{port}_vnc_nmap.txt" -oX "{scandir}/xml/{protocol}_{port}_vnc_nmap.xml" {address}')
|
||||
|
||||
class WinRMDetection(ServiceScan):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.name = 'WinRM Detection'
|
||||
self.tags = ['default', 'safe', 'winrm']
|
||||
|
||||
def configure(self):
|
||||
self.match_service_name('^wsman')
|
||||
self.match_service('tcp', [5985, 5986], '^http')
|
||||
|
||||
async def run(self, service):
|
||||
filename = fformat('{scandir}/{protocol}_{port}_winrm-detection.txt')
|
||||
with open(filename, mode='wt', encoding='utf8') as winrm:
|
||||
winrm.write('WinRM was possibly detected running on ' + service.protocol + ' port ' + str(service.port) + '.\nCheck _manual_commands.txt for manual commands you can run against this service.')
|
||||
|
||||
def manual(self, service, plugin_was_run):
|
||||
service.add_manual_commands('Bruteforce logins:', [
|
||||
'crackmapexec winrm {address} -d ' + self.get_global('domain', default='<domain>') + ' -u ' + self.get_global('username_wordlist', default='/usr/share/seclists/Usernames/top-usernames-shortlist.txt') + ' -p ' + self.get_global('password_wordlist', default='/usr/share/seclists/Passwords/darkweb2017-top100.txt')
|
||||
])
|
||||
|
||||
service.add_manual_commands('Check login (requires credentials):', [
|
||||
'crackmapexec winrm {address} -d ' + self.get_global('domain', default='<domain>') + ' -u <username> -p <password> -x "whoami"'
|
||||
])
|
||||
|
||||
service.add_manual_commands('Evil WinRM (gem install evil-winrm):', [
|
||||
'evil-winrm -u <user> -p <password> -i {address}',
|
||||
'evil-winrm -u <user> -H <hash> -i {address}'
|
||||
])
|
||||
|
|
Loading…
Reference in New Issue