@@ -1087,55 +1087,62 @@ def query(self):
10871087 self .logger .highlight (f"{ attr :<20} { vals } " )
10881088
10891089 def find_delegation (self ):
1090+ # Constants for delegation types
1091+ UF_TRUSTED_FOR_DELEGATION = 0x80000
1092+ UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x1000000
1093+ UF_ACCOUNTDISABLE = 0x2
1094+
1095+ def processAttributeValue (attribute ):
1096+ # Extract the payload value from the AttributeValue object
1097+ if hasattr (attribute , "payload" ):
1098+ return str (attribute .payload )
1099+ return str (attribute )
1100+
10901101 def printTable (items , header ):
10911102 colLen = []
1092- try :
1093- for i , col in enumerate (header ):
1094- rowMaxLen = max (len (str (row [i ])) for row in items )
1095- colLen .append (max (rowMaxLen , len (col )))
1103+ for i , col in enumerate (header ):
1104+ rowMaxLen = max (len (str (row [i ])) for row in items )
1105+ colLen .append (max (rowMaxLen , len (col )))
10961106
1097- # Create the format string for each row
1098- outputFormat = " " .join ([f"{{{ num } :{ width } s}}" for num , width in enumerate (colLen )])
1107+ # Create the format string for each row
1108+ outputFormat = " " .join ([f"{{{ num } :{ width } s}}" for num , width in enumerate (colLen )])
10991109
1100- # Print header
1101- self .logger .highlight (outputFormat .format (* header ))
1102- self .logger .highlight (" " .join (["-" * itemLen for itemLen in colLen ]))
1110+ self .logger .highlight (outputFormat .format (* header ))
1111+ self .logger .highlight (" " .join (["-" * itemLen for itemLen in colLen ]))
11031112
1104- # Print rows
1105- for row in items :
1106- self . logger . highlight ( outputFormat . format ( * row ))
1107- except Exception as e :
1108- self .logger .fail ( "Header Index error " + str ( e ))
1113+ # Print rows
1114+ for row in items :
1115+ # Burada DelegationRightsTo'yu düzeltmek için join() ekleyin
1116+ row [ 3 ] = ", " . join ( str ( x ) for x in row [ 3 ]) if isinstance ( row [ 3 ], list ) else row [ 3 ]
1117+ self .logger .highlight ( outputFormat . format ( * row ))
11091118
11101119 # Building the search filter
1111- search_filter = ("(&(|(UserAccountControl:1.2.840.113556.1.4.803:=16777216)(UserAccountControl:1.2.840.113556.1.4.803:="
1112- "524288)(msDS-AllowedToDelegateTo=*)(msDS-AllowedToActOnBehalfOfOtherIdentity=*))"
1113- "(!(UserAccountControl:1.2.840.113556.1.4.803:=2))(!(UserAccountControl:1.2.840.113556.1.4.803:=8192)))"
1114- )
1115- attributes = ["sAMAccountName" ,
1116- "pwdLastSet" ,
1117- "userAccountControl" ,
1118- "objectCategory" ,
1119- "msDS-AllowedToActOnBehalfOfOtherIdentity" ,
1120- "msDS-AllowedToDelegateTo" ]
1120+ search_filter = ("(&(|(UserAccountControl:1.2.840.113556.1.4.803:=16777216)"
1121+ "(UserAccountControl:1.2.840.113556.1.4.803:=524288)"
1122+ "(msDS-AllowedToDelegateTo=*)(msDS-AllowedToActOnBehalfOfOtherIdentity=*))"
1123+ "(!(UserAccountControl:1.2.840.113556.1.4.803:=2))"
1124+ "(!(UserAccountControl:1.2.840.113556.1.4.803:=8192)))" )
11211125
1126+ attributes = ["sAMAccountName" , "pwdLastSet" , "userAccountControl" , "objectCategory" ,
1127+ "msDS-AllowedToActOnBehalfOfOtherIdentity" , "msDS-AllowedToDelegateTo" ]
1128+
11221129 resp = self .search (search_filter , attributes , 0 )
11231130
11241131 answers = []
11251132 self .logger .debug (f"Total of records returned { len (resp ):d} " )
11261133
11271134 for item in resp :
1128- if isinstance (item , ldapasn1_impacket .SearchResultEntry ) is not True :
1135+ if not isinstance (item , ldapasn1_impacket .SearchResultEntry ):
11291136 continue
1137+
11301138 mustCommit = False
11311139 sAMAccountName = ""
11321140 userAccountControl = 0
11331141 delegation = ""
11341142 objectType = ""
11351143 rightsTo = []
11361144 protocolTransition = 0
1137-
1138- # After receiving responses we parse through to determine the type of delegation configured on each object
1145+
11391146 try :
11401147 for attribute in item ["attributes" ]:
11411148 if str (attribute ["type" ]) == "sAMAccountName" :
@@ -1154,42 +1161,42 @@ def printTable(items, header):
11541161 elif str (attribute ["type" ]) == "msDS-AllowedToDelegateTo" :
11551162 if protocolTransition == 0 :
11561163 delegation = "Constrained"
1157- rightsTo = list ( attribute ["vals" ])
1158-
1159- # Not an elif as an object could both have rbcd and another type of delegation configured for the same object
1164+ rightsTo = [ processAttributeValue ( val ) for val in attribute ["vals" ]]
1165+
1166+ # Not an elif as an object could both have RBCD and another type of delegation
11601167 if str (attribute ["type" ]) == "msDS-AllowedToActOnBehalfOfOtherIdentity" :
11611168 rbcdRights = []
11621169 rbcdObjType = []
1163- search_filter = "(&(|"
11641170 sd = ldaptypes .SR_SECURITY_DESCRIPTOR (data = bytes (attribute ["vals" ][0 ]))
1171+ search_filter = "(&(|"
11651172 for ace in sd ["Dacl" ].aces :
1166- search_filter = search_filter + "(objectSid=" + ace ["Ace" ]["Sid" ].formatCanonical () + ")"
1167- search_filter = search_filter + ")(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))"
1173+ search_filter += "(objectSid=" + ace ["Ace" ]["Sid" ].formatCanonical () + ")"
1174+ search_filter += ")(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))"
11681175 delegUserResp = self .search (search_filter , attributes = ["sAMAccountName" , "objectCategory" ], sizeLimit = 999 )
1176+
11691177 for item2 in delegUserResp :
1170- if isinstance (item2 , ldapasn1_impacket .SearchResultEntry ) is not True :
1178+ if not isinstance (item2 , ldapasn1_impacket .SearchResultEntry ):
11711179 continue
11721180 rbcdRights .append (str (item2 ["attributes" ][0 ]["vals" ][0 ]))
11731181 rbcdObjType .append (str (item2 ["attributes" ][1 ]["vals" ][0 ]).split ("=" )[1 ].split ("," )[0 ])
1174-
1175- if mustCommit is True :
1182+
1183+ if mustCommit :
11761184 if int (userAccountControl ) & UF_ACCOUNTDISABLE :
1177- self .logger .debug ("Bypassing disabled account %s " % sAMAccountName )
1185+ self .logger .debug (f "Bypassing disabled account { sAMAccountName } " )
11781186 else :
11791187 for rights , objType in zip (rbcdRights , rbcdObjType ):
11801188 answers .append ([rights , objType , "Resource-Based Constrained" , sAMAccountName ])
1181-
1182- # Print unconstrained + constrained delegation relationships
1183- if (delegation in ["Unconstrained" , "Constrained" , "Constrained w/ Protocol Transition" ] and mustCommit ):
1189+
1190+ if delegation in ["Unconstrained" , "Constrained" , "Constrained w/ Protocol Transition" ] and mustCommit :
11841191 if int (userAccountControl ) & UF_ACCOUNTDISABLE :
1185- self .logger .debug ("Bypassing disabled account %s " % sAMAccountName )
1192+ self .logger .debug (f "Bypassing disabled account { sAMAccountName } " )
11861193 else :
1187- answers = [sAMAccountName , objectType , delegation , rightsTo ]
1194+ answers . append ( [sAMAccountName , objectType , delegation , rightsTo ])
11881195
11891196 except Exception as e :
1190- self .logger .error ("Skipping item, cannot process due to error %s" % str ( e ) )
1191-
1192- if len ( answers ) > 0 :
1197+ self .logger .error (f "Skipping item, cannot process due to error { e } " )
1198+
1199+ if answers :
11931200 printTable (answers , header = ["AccountName" , "AccountType" , "DelegationType" , "DelegationRightsTo" ])
11941201 else :
11951202 self .logger .fail ("No entries found!" )
0 commit comments