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('-', '_')
|
name = 'global.' + slugify(name).replace('-', '_')
|
||||||
|
|
||||||
if name in vars(self.autorecon.args):
|
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:
|
else:
|
||||||
if default:
|
if default:
|
||||||
return default
|
return default
|
||||||
|
@ -323,12 +329,42 @@ class ServiceScan(Plugin):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ports = {'tcp':[], 'udp':[]}
|
self.ports = {'tcp':[], 'udp':[]}
|
||||||
self.ignore_ports = {'tcp':[], 'udp':[]}
|
self.ignore_ports = {'tcp':[], 'udp':[]}
|
||||||
|
self.services = []
|
||||||
self.service_names = []
|
self.service_names = []
|
||||||
self.ignore_service_names = []
|
self.ignore_service_names = []
|
||||||
self.match_all_service_names_boolean = False
|
self.match_all_service_names_boolean = False
|
||||||
self.run_once_boolean = False
|
self.run_once_boolean = False
|
||||||
self.require_ssl_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
|
@final
|
||||||
def match_port(self, protocol, port, negative_match=False):
|
def match_port(self, protocol, port, negative_match=False):
|
||||||
protocol = protocol.lower()
|
protocol = protocol.lower()
|
||||||
|
@ -673,7 +709,7 @@ def calculate_elapsed_time(start_time, short=False):
|
||||||
|
|
||||||
elapsed_time = []
|
elapsed_time = []
|
||||||
if short:
|
if short:
|
||||||
elapsed_time.append(str(h))
|
elapsed_time.append(str(h).zfill(2))
|
||||||
else:
|
else:
|
||||||
if h == 1:
|
if h == 1:
|
||||||
elapsed_time.append(str(h) + ' hour')
|
elapsed_time.append(str(h) + ' hour')
|
||||||
|
@ -681,7 +717,7 @@ def calculate_elapsed_time(start_time, short=False):
|
||||||
elapsed_time.append(str(h) + ' hours')
|
elapsed_time.append(str(h) + ' hours')
|
||||||
|
|
||||||
if short:
|
if short:
|
||||||
elapsed_time.append(str(m))
|
elapsed_time.append(str(m).zfill(2))
|
||||||
else:
|
else:
|
||||||
if m == 1:
|
if m == 1:
|
||||||
elapsed_time.append(str(m) + ' minute')
|
elapsed_time.append(str(m) + ' minute')
|
||||||
|
@ -689,7 +725,7 @@ def calculate_elapsed_time(start_time, short=False):
|
||||||
elapsed_time.append(str(m) + ' minutes')
|
elapsed_time.append(str(m) + ' minutes')
|
||||||
|
|
||||||
if short:
|
if short:
|
||||||
elapsed_time.append(str(s))
|
elapsed_time.append(str(s).zfill(2))
|
||||||
else:
|
else:
|
||||||
if s == 1:
|
if s == 1:
|
||||||
elapsed_time.append(str(s) + ' second')
|
elapsed_time.append(str(s) + ' second')
|
||||||
|
@ -1069,6 +1105,18 @@ async def scan_target(target):
|
||||||
plugin_service_match = False
|
plugin_service_match = False
|
||||||
plugin_tag = service.tag() + '/' + plugin.slug
|
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:
|
for s in plugin.service_names:
|
||||||
if re.search(s, service.name):
|
if re.search(s, service.name):
|
||||||
plugin_service_match = True
|
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'
|
help = 'A wordlist of passwords, useful for bruteforcing. Default: %(default)s'
|
||||||
|
|
||||||
[global.domain]
|
[global.domain]
|
||||||
default = false
|
help = 'The domain to use (if known). Used for DNS and/or Active Directory. Default: %(default)s'
|
||||||
help = 'The domain to use (if known). Used for DNS and/or Active Directory.'
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from autorecon import ServiceScan
|
from autorecon import ServiceScan, fformat
|
||||||
|
|
||||||
class NmapCassandra(ServiceScan):
|
class NmapCassandra(ServiceScan):
|
||||||
|
|
||||||
|
@ -142,3 +142,33 @@ class NmapVNC(ServiceScan):
|
||||||
|
|
||||||
async def run(self, service):
|
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}')
|
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