Skip to content

Commit 0b1a4e4

Browse files
authored
Merge pull request Pennyw0rth#640 from Pennyw0rth/neff-add-gmsa-readPrincipal
Add read principal to GMSA
2 parents bf37152 + 47e4092 commit 0b1a4e4

1 file changed

Lines changed: 26 additions & 2 deletions

File tree

nxc/protocols/ldap.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,7 @@ def gmsa(self):
11061106
attributes=[
11071107
"sAMAccountName",
11081108
"msDS-ManagedPassword",
1109+
"msDS-GroupMSAMembership",
11091110
],
11101111
sizeLimit=0,
11111112
)
@@ -1114,15 +1115,38 @@ def gmsa(self):
11141115
self.logger.debug(f"Total of records returned {len(gmsa_accounts_parsed):d}")
11151116

11161117
for acc in gmsa_accounts_parsed:
1117-
passwd = ""
1118+
# PrincipalAllowedToRetrieveGMSAPassword
1119+
principal_with_read = []
1120+
if "msDS-GroupMSAMembership" in acc:
1121+
msDS_GroupMSAMembership = acc["msDS-GroupMSAMembership"]
1122+
dacl = ldaptypes.SR_SECURITY_DESCRIPTOR(data=bytes(msDS_GroupMSAMembership))
1123+
1124+
# Get all SIDs that have the right to read the password
1125+
sids = [ace["Ace"]["Sid"].formatCanonical() for ace in dacl["Dacl"]["Data"] if ace["AceType"] == 0x00]
1126+
self.logger.debug(f"msDS-GroupMSAMembership: {sids}")
1127+
search_filter = "(|" + "".join([f"(objectSid={sid})" for sid in sids]) + ")"
1128+
resp = self.ldap_connection.search(
1129+
searchBase=self.baseDN,
1130+
searchFilter=search_filter,
1131+
attributes=["sAMAccountName"],
1132+
sizeLimit=0,
1133+
)
1134+
resp_parsed = parse_result_attributes(resp)
1135+
if len(resp_parsed) > 1:
1136+
principal_with_read = [f"{item['sAMAccountName']}" for item in resp_parsed]
1137+
elif len(resp_parsed) == 1:
1138+
principal_with_read = resp_parsed[0]["sAMAccountName"]
1139+
1140+
# Get the password
1141+
passwd = "<no read permissions>"
11181142
if "msDS-ManagedPassword" in acc:
11191143
blob = MSDS_MANAGEDPASSWORD_BLOB()
11201144
blob.fromString(acc["msDS-ManagedPassword"])
11211145
currentPassword = blob["CurrentPassword"][:-2]
11221146
ntlm_hash = MD4.new()
11231147
ntlm_hash.update(currentPassword)
11241148
passwd = hexlify(ntlm_hash.digest()).decode("utf-8")
1125-
self.logger.highlight(f"Account: {acc['sAMAccountName']:<20} NTLM: {passwd}")
1149+
self.logger.highlight(f"Account: {acc['sAMAccountName']:<20} NTLM: {passwd:<36} PrincipalsAllowedToReadPassword: {principal_with_read}")
11261150
return True
11271151

11281152
def decipher_gmsa_name(self, domain_name=None, account_name=None):

0 commit comments

Comments
 (0)