@@ -1091,7 +1091,7 @@ def find_delegation(self):
10911091 UF_TRUSTED_FOR_DELEGATION = 0x80000
10921092 UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x1000000
10931093 UF_ACCOUNTDISABLE = 0x2
1094- """ SERVER_TRUST_ACCOUNT = 0x2000"""
1094+ SERVER_TRUST_ACCOUNT = 0x2000
10951095
10961096 def printTable (items , header ):
10971097 colLen = []
@@ -1124,7 +1124,7 @@ def printTable(items, header):
11241124 f"(UserAccountControl:1.2.840.113556.1.4.803:={ UF_TRUSTED_FOR_DELEGATION } )"
11251125 "(msDS-AllowedToDelegateTo=*)(msDS-AllowedToActOnBehalfOfOtherIdentity=*))"
11261126 f"(!(UserAccountControl:1.2.840.113556.1.4.803:={ UF_ACCOUNTDISABLE } )))" )
1127- # f"(!(UserAccountControl:1.2.840.113556.1.4.803:={SERVER_TRUST_ACCOUNT})))") To listing RBCD to DCs
1127+ # f"(!(UserAccountControl:1.2.840.113556.1.4.803:={SERVER_TRUST_ACCOUNT})))") This would filter out RBCD to DCs
11281128
11291129 attributes = ["sAMAccountName" , "pwdLastSet" , "userAccountControl" , "objectCategory" ,
11301130 "msDS-AllowedToActOnBehalfOfOtherIdentity" , "msDS-AllowedToDelegateTo" ]
@@ -1143,56 +1143,54 @@ def printTable(items, header):
11431143 protocolTransition = 0
11441144
11451145 try :
1146- sAMAccountName = item .get ("sAMAccountName" )
1147- if sAMAccountName :
1148-
1149- userAccountControl = int (item .get ("userAccountControl" , 0 ))
1150- objectType = item .get ("objectCategory" )
1151-
1152- if userAccountControl & UF_TRUSTED_FOR_DELEGATION :
1153- delegation = "Unconstrained"
1154- rightsTo .append ("N/A" )
1155- elif userAccountControl & UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION :
1156- delegation = "Constrained w/ Protocol Transition"
1157- protocolTransition = 1
1158-
1159- if item .get ("msDS-AllowedToDelegateTo" ) is not None :
1160- if protocolTransition == 0 :
1161- delegation = "Constrained"
1162- rightsTo = item .get ("msDS-AllowedToDelegateTo" )
1163-
1164- # Not an elif as an object could both have RBCD and another type of delegation
1165- if item .get ("msDS-AllowedToActOnBehalfOfOtherIdentity" ) is not None :
1166- databyte = item .get ("msDS-AllowedToActOnBehalfOfOtherIdentity" )
1167- rbcdRights = []
1168- rbcdObjType = []
1169- sd = ldaptypes .SR_SECURITY_DESCRIPTOR (data = bytes (databyte ))
1170- if len (sd ["Dacl" ].aces ) > 0 :
1171- search_filter = "(&(|"
1172- for ace in sd ["Dacl" ].aces :
1173- search_filter += "(objectSid=" + ace ["Ace" ]["Sid" ].formatCanonical () + ")"
1174- search_filter += ")(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))"
1175- delegUserResp = self .search (search_filter , attributes = ["sAMAccountName" , "objectCategory" ], sizeLimit = 999 )
1176- delegUserResp_parse = parse_result_attributes (delegUserResp )
1177-
1178- for rbcd in delegUserResp_parse :
1179- rbcdRights .append (str (rbcd .get ("sAMAccountName" )))
1180- rbcdObjType .append (str (rbcd .get ("objectCategory" )))
1181-
1182-
1183- if int (userAccountControl ) & UF_ACCOUNTDISABLE :
1184- self .logger .debug (f"Bypassing disabled account { sAMAccountName } " )
1185- else :
1186- for rights , objType in zip (rbcdRights , rbcdObjType ):
1187- answers .append ([rights , objType , "Resource-Based Constrained" , sAMAccountName ])
1188-
1189- if delegation in ["Unconstrained" , "Constrained" , "Constrained w/ Protocol Transition" ]:
1146+ sAMAccountName = item ["sAMAccountName" ]
1147+
1148+ userAccountControl = int (item ["userAccountControl" ])
1149+ objectType = item .get ("objectCategory" )
1150+
1151+ if userAccountControl & UF_TRUSTED_FOR_DELEGATION :
1152+ delegation = "Unconstrained"
1153+ rightsTo .append ("N/A" )
1154+ elif userAccountControl & UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION :
1155+ delegation = "Constrained w/ Protocol Transition"
1156+ protocolTransition = 1
1157+
1158+ if item .get ("msDS-AllowedToDelegateTo" ) is not None :
1159+ if protocolTransition == 0 :
1160+ delegation = "Constrained"
1161+ rightsTo = item .get ("msDS-AllowedToDelegateTo" )
1162+
1163+ # Not an elif as an object could both have RBCD and another type of delegation
1164+ if item .get ("msDS-AllowedToActOnBehalfOfOtherIdentity" ) is not None :
1165+ databyte = item .get ("msDS-AllowedToActOnBehalfOfOtherIdentity" )
1166+ rbcdRights = []
1167+ rbcdObjType = []
1168+ sd = ldaptypes .SR_SECURITY_DESCRIPTOR (data = bytes (databyte ))
1169+ if len (sd ["Dacl" ].aces ) > 0 :
1170+ search_filter = "(&(|"
1171+ for ace in sd ["Dacl" ].aces :
1172+ search_filter += "(objectSid=" + ace ["Ace" ]["Sid" ].formatCanonical () + ")"
1173+ search_filter += ")(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))"
1174+ delegUserResp = self .search (search_filter , attributes = ["sAMAccountName" , "objectCategory" ], sizeLimit = 999 )
1175+ delegUserResp_parse = parse_result_attributes (delegUserResp )
1176+
1177+ for rbcd in delegUserResp_parse :
1178+ rbcdRights .append (str (rbcd .get ("sAMAccountName" )))
1179+ rbcdObjType .append (str (rbcd .get ("objectCategory" )))
1180+
11901181 if int (userAccountControl ) & UF_ACCOUNTDISABLE :
11911182 self .logger .debug (f"Bypassing disabled account { sAMAccountName } " )
11921183 else :
1193- # Check if the entry is invalid, i.e., for "Unconstrained N/A"
1194- if not (delegation == "Unconstrained" and rightsTo == ["N/A" ]):
1195- answers .append ([sAMAccountName , objectType , delegation , rightsTo ])
1184+ for rights , objType in zip (rbcdRights , rbcdObjType ):
1185+ answers .append ([rights , objType , "Resource-Based Constrained" , sAMAccountName ])
1186+
1187+ if delegation in ["Unconstrained" , "Constrained" , "Constrained w/ Protocol Transition" ]:
1188+ if int (userAccountControl ) & UF_ACCOUNTDISABLE :
1189+ self .logger .debug (f"Bypassing disabled account { sAMAccountName } " )
1190+ else :
1191+ # Check if the entry is invalid, i.e., for "Unconstrained N/A"
1192+ if not (delegation == "Unconstrained" and rightsTo == ["N/A" ]):
1193+ answers .append ([sAMAccountName , objectType , delegation , rightsTo ])
11961194
11971195 except Exception as e :
11981196 self .logger .error (f"Skipping item, cannot process due to error { e } " )
0 commit comments