Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1184 Find delegation filter edit #51

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
37 changes: 27 additions & 10 deletions examples/findDelegation.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ def __init__(self, username, password, user_domain, target_domain, cmdLineOption
self.__password = password
self.__domain = user_domain
self.__targetDomain = target_domain
self.__requestUser = cmdLineOptions.user
self.__lmhash = ''
self.__nthash = ''
self.__aesKey = cmdLineOptions.aesKey
self.__doKerberos = cmdLineOptions.k
self.__kdcHost = cmdLineOptions.dc_ip
self.__disabled = cmdLineOptions.disabled
if cmdLineOptions.hashes is not None:
self.__lmhash, self.__nthash = cmdLineOptions.hashes.split(':')

Expand Down Expand Up @@ -131,8 +133,18 @@ def run(self):
raise

searchFilter = "(&(|(UserAccountControl:1.2.840.113556.1.4.803:=16777216)(UserAccountControl:1.2.840.113556.1.4.803:=" \
"524288)(msDS-AllowedToDelegateTo=*)(msDS-AllowedToActOnBehalfOfOtherIdentity=*))" \
"(!(UserAccountControl:1.2.840.113556.1.4.803:=2))(!(UserAccountControl:1.2.840.113556.1.4.803:=8192)))"
"524288)(msDS-AllowedToDelegateTo=*)(msDS-AllowedToActOnBehalfOfOtherIdentity=*)"

if self.__disabled:
searchFilter = searchFilter + ")(UserAccountControl:1.2.840.113556.1.4.803:=2)"
else:
searchFilter = searchFilter + ")(!(UserAccountControl:1.2.840.113556.1.4.803:=2))"


if self.__requestUser is not None:
searchFilter += '(sAMAccountName:=%s))' % self.__requestUser
else:
searchFilter += ')'

try:
resp = ldapConnection.search(searchFilter=searchFilter,
Expand All @@ -152,7 +164,7 @@ def run(self):

answers = []
logging.debug('Total of records returned %d' % len(resp))

for item in resp:
if isinstance(item, ldapasn1.SearchResultEntry) is not True:
continue
Expand Down Expand Up @@ -182,37 +194,41 @@ def run(self):
objectType = str(attribute['vals'][0]).split('=')[1].split(',')[0]
elif str(attribute['type']) == 'msDS-AllowedToDelegateTo':
if protocolTransition == 0:
delegation = 'Constrained'
delegation = 'Constrained w/o Protocol Transition'
for delegRights in attribute['vals']:
rightsTo.append(str(delegRights))

#not an elif as an object could both have rbcd and another type of delegation configured for the same object
if str(attribute['type']) == 'msDS-AllowedToActOnBehalfOfOtherIdentity':
rbcdRights = []
rbcdObjType = []
searchFilter = '(&(|'
searchFilter = "(&(|"
sd = ldaptypes.SR_SECURITY_DESCRIPTOR(data=bytes(attribute['vals'][0]))
for ace in sd['Dacl'].aces:
searchFilter = searchFilter + "(objectSid="+ace['Ace']['Sid'].formatCanonical()+")"
searchFilter = searchFilter + ")(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))"
if self.__disabled:
searchFilter = searchFilter + ")(UserAccountControl:1.2.840.113556.1.4.803:=2))"
else:
searchFilter = searchFilter + ")(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))"
delegUserResp = ldapConnection.search(searchFilter=searchFilter,attributes=['sAMAccountName', 'objectCategory'],sizeLimit=999)

for item2 in delegUserResp:
if isinstance(item2, ldapasn1.SearchResultEntry) is not True:
continue
rbcdRights.append(str(item2['attributes'][0]['vals'][0]))
rbcdObjType.append(str(item2['attributes'][1]['vals'][0]).split('=')[1].split(',')[0])

if mustCommit is True:
if int(userAccountControl) & UF_ACCOUNTDISABLE:
if int(userAccountControl) & UF_ACCOUNTDISABLE and self.__disabled is not True:
logging.debug('Bypassing disabled account %s ' % sAMAccountName)
else:
for rights, objType in zip(rbcdRights,rbcdObjType):
answers.append([rights, objType, 'Resource-Based Constrained', sAMAccountName])

#print unconstrained + constrained delegation relationships
if delegation in ['Unconstrained', 'Constrained', 'Constrained w/ Protocol Transition']:
if delegation in ['Unconstrained', 'Constrained w/o Protocol Transition', 'Constrained w/ Protocol Transition']:
if mustCommit is True:
if int(userAccountControl) & UF_ACCOUNTDISABLE:
if int(userAccountControl) & UF_ACCOUNTDISABLE and self.__disabled is not True:
logging.debug('Bypassing disabled account %s ' % sAMAccountName)
else:
for rights in rightsTo:
Expand All @@ -239,9 +255,10 @@ def run(self):
parser.add_argument('target', action='store', help='domain/username[:password]')
parser.add_argument('-target-domain', action='store', help='Domain to query/request if different than the domain of the user. '
'Allows for retrieving delegation info across trusts.')

parser.add_argument('-user', action='store', help='Requests data for specific user')
parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON')

parser.add_argument('-disabled', action='store_true', help='Query only disabled users')
group = parser.add_argument_group('authentication')

group.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH')
Expand Down