@@ -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