forked from p15670423/monkey
Fixed bugs and finished up pypykatz integration
This commit is contained in:
parent
192ac67159
commit
895db8b446
|
@ -39,9 +39,9 @@ class WmiExploiter(HostExploiter):
|
||||||
for user, password, lm_hash, ntlm_hash in creds:
|
for user, password, lm_hash, ntlm_hash in creds:
|
||||||
password_hashed = self._config.hash_sensitive_data(password)
|
password_hashed = self._config.hash_sensitive_data(password)
|
||||||
lm_hash_hashed = self._config.hash_sensitive_data(lm_hash)
|
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): " \
|
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)
|
LOG.debug(("Attempting to connect %r using WMI with " % self.host) + creds_for_logging)
|
||||||
|
|
||||||
wmi_connection = WmiTools.WmiConnection()
|
wmi_connection = WmiTools.WmiConnection()
|
||||||
|
|
|
@ -105,6 +105,7 @@ class InfoCollector(object):
|
||||||
# we might be losing passwords in case of multiple reset attempts on same username
|
# 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
|
# or in case another collector already filled in a password for this user
|
||||||
self.info["credentials"][username]['password'] = password
|
self.info["credentials"][username]['password'] = password
|
||||||
|
self.info["credentials"][username]['username'] = username
|
||||||
if len(azure_creds) != 0:
|
if len(azure_creds) != 0:
|
||||||
self.info["Azure"] = {}
|
self.info["Azure"] = {}
|
||||||
self.info["Azure"]['usernames'] = [cred[0] for cred in azure_creds]
|
self.info["Azure"]['usernames'] = [cred[0] for cred in azure_creds]
|
||||||
|
|
|
@ -18,5 +18,8 @@ class WindowsCredentialCollector(object):
|
||||||
def cred_list_to_cred_dict(creds: List[WindowsCredential]):
|
def cred_list_to_cred_dict(creds: List[WindowsCredential]):
|
||||||
cred_dict = {}
|
cred_dict = {}
|
||||||
for cred in creds:
|
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
|
return cred_dict
|
||||||
|
|
|
@ -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
|
|
|
@ -184,10 +184,13 @@ class ReportService:
|
||||||
continue
|
continue
|
||||||
origin = NodeService.get_monkey_by_guid(telem['monkey_guid'])['hostname']
|
origin = NodeService.get_monkey_by_guid(telem['monkey_guid'])['hostname']
|
||||||
for user in monkey_creds:
|
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 = \
|
cred_row = \
|
||||||
{
|
{
|
||||||
'username': user.replace(',', '.'),
|
'username': username,
|
||||||
'type': PASS_TYPE_DICT[pass_type],
|
'type': PASS_TYPE_DICT[pass_type],
|
||||||
'origin': origin
|
'origin': origin
|
||||||
}
|
}
|
||||||
|
@ -729,8 +732,7 @@ class ReportService:
|
||||||
'stolen_creds': ReportService.get_stolen_creds(),
|
'stolen_creds': ReportService.get_stolen_creds(),
|
||||||
'azure_passwords': ReportService.get_azure_creds(),
|
'azure_passwords': ReportService.get_azure_creds(),
|
||||||
'ssh_keys': ReportService.get_ssh_keys(),
|
'ssh_keys': ReportService.get_ssh_keys(),
|
||||||
'strong_users': PTHReportService.get_strong_users_on_crit_details(),
|
'strong_users': PTHReportService.get_strong_users_on_crit_details()
|
||||||
'pth_map': PTHReportService.get_pth_map()
|
|
||||||
},
|
},
|
||||||
'recommendations':
|
'recommendations':
|
||||||
{
|
{
|
||||||
|
|
|
@ -69,7 +69,7 @@ class WMIHandler(object):
|
||||||
base_entity = self.build_entity_document(user)
|
base_entity = self.build_entity_document(user)
|
||||||
else:
|
else:
|
||||||
base_entity = self.build_entity_document(user, self.monkey_id)
|
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['SAM_secret'] = self.users_secrets.get(base_entity['name'], {}).get('sam')
|
||||||
base_entity['secret_location'] = []
|
base_entity['secret_location'] = []
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue