Fixed bugs and finished up pypykatz integration

This commit is contained in:
VakarisZ 2020-06-05 09:36:35 +03:00
parent 192ac67159
commit 895db8b446
6 changed files with 14 additions and 59 deletions

View File

@ -39,9 +39,9 @@ class WmiExploiter(HostExploiter):
for user, password, lm_hash, ntlm_hash in creds:
password_hashed = self._config.hash_sensitive_data(password)
lm_hash_hashed = self._config.hash_sensitive_data(lm_hash)
mtlm_hash_hashed = self._config.hash_sensitive_data(ntlm_hash)
ntlm_hash_hashed = self._config.hash_sensitive_data(ntlm_hash)
creds_for_logging = "user, password (SHA-512), lm hash (SHA-512), ntlm hash (SHA-512): " \
"({},{},{},{})".format(user, password_hashed, lm_hash_hashed, mtlm_hash_hashed)
"({},{},{},{})".format(user, password_hashed, lm_hash_hashed, ntlm_hash_hashed)
LOG.debug(("Attempting to connect %r using WMI with " % self.host) + creds_for_logging)
wmi_connection = WmiTools.WmiConnection()

View File

@ -105,6 +105,7 @@ class InfoCollector(object):
# we might be losing passwords in case of multiple reset attempts on same username
# or in case another collector already filled in a password for this user
self.info["credentials"][username]['password'] = password
self.info["credentials"][username]['username'] = username
if len(azure_creds) != 0:
self.info["Azure"] = {}
self.info["Azure"]['usernames'] = [cred[0] for cred in azure_creds]

View File

@ -18,5 +18,8 @@ class WindowsCredentialCollector(object):
def cred_list_to_cred_dict(creds: List[WindowsCredential]):
cred_dict = {}
for cred in creds:
cred_dict.update({cred.username: cred.to_dict()})
# Lets not use "." and "$" in keys, because it will confuse mongo.
# Ideally we should refactor island not to use a dict and simply parse credential list.
key = cred.username.replace(".", ",").replace("$", "")
cred_dict.update({key: cred.to_dict()})
return cred_dict

View File

@ -1,51 +0,0 @@
__author__ = 'maor.rayzin'
class MimikatzSecrets(object):
def __init__(self):
# Static class
pass
@staticmethod
def extract_sam_secrets(mim_string, users_dict):
users_secrets = mim_string.split("\n42.")[1].split("\nSAMKey :")[1].split("\n\n")[1:]
if mim_string.count("\n42.") != 2:
return {}
for sam_user_txt in users_secrets:
sam_user = dict([list(map(str.strip, line.split(":"))) for line in
[l for l in sam_user_txt.splitlines() if l.count(":") == 1]])
username = sam_user.get("User")
users_dict[username] = {}
ntlm = sam_user.get("NTLM")
if not ntlm or "[hashed secret]" not in ntlm:
continue
users_dict[username]['SAM'] = ntlm.replace("[hashed secret]", "").strip()
@staticmethod
def extract_ntlm_secrets(mim_string, users_dict):
if mim_string.count("\n42.") != 2:
return {}
ntds_users = mim_string.split("\n42.")[2].split("\nRID :")[1:]
for ntds_user_txt in ntds_users:
user = ntds_user_txt.split("User :")[1].splitlines()[0].replace("User :", "").strip()
ntlm = ntds_user_txt.split("* Primary\n NTLM :")[1].splitlines()[0].replace("NTLM :", "").strip()
ntlm = ntlm.replace("[hashed secret]", "").strip()
users_dict[user] = {}
if ntlm:
users_dict[user]['ntlm'] = ntlm
@staticmethod
def extract_secrets_from_mimikatz(mim_string):
users_dict = {}
MimikatzSecrets.extract_sam_secrets(mim_string, users_dict)
MimikatzSecrets.extract_ntlm_secrets(mim_string, users_dict)
return users_dict

View File

@ -184,10 +184,13 @@ class ReportService:
continue
origin = NodeService.get_monkey_by_guid(telem['monkey_guid'])['hostname']
for user in monkey_creds:
for pass_type in monkey_creds[user]:
for pass_type in PASS_TYPE_DICT:
if pass_type not in monkey_creds[user] or not monkey_creds[user][pass_type]:
continue
username = monkey_creds[user]['username'] if 'username' in monkey_creds[user] else user
cred_row = \
{
'username': user.replace(',', '.'),
'username': username,
'type': PASS_TYPE_DICT[pass_type],
'origin': origin
}
@ -729,8 +732,7 @@ class ReportService:
'stolen_creds': ReportService.get_stolen_creds(),
'azure_passwords': ReportService.get_azure_creds(),
'ssh_keys': ReportService.get_ssh_keys(),
'strong_users': PTHReportService.get_strong_users_on_crit_details(),
'pth_map': PTHReportService.get_pth_map()
'strong_users': PTHReportService.get_strong_users_on_crit_details()
},
'recommendations':
{

View File

@ -69,7 +69,7 @@ class WMIHandler(object):
base_entity = self.build_entity_document(user)
else:
base_entity = self.build_entity_document(user, self.monkey_id)
base_entity['NTLM_secret'] = self.users_secrets.get(base_entity['name'], {}).get('ntlm')
base_entity['NTLM_secret'] = self.users_secrets.get(base_entity['name'], {}).get('ntlm_hash')
base_entity['SAM_secret'] = self.users_secrets.get(base_entity['name'], {}).get('sam')
base_entity['secret_location'] = []