From e45fd8373c5ea944f97359b9de457d62a3d9fad3 Mon Sep 17 00:00:00 2001 From: Abdul Mhanni Date: Thu, 9 Apr 2026 20:07:06 -0400 Subject: [PATCH 1/3] Added processing to object specific ACEs in search_ous() --- examples/badsuccessor.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/badsuccessor.py b/examples/badsuccessor.py index 7feff0190b..c323564e13 100644 --- a/examples/badsuccessor.py +++ b/examples/badsuccessor.py @@ -281,8 +281,12 @@ def search_ous(self, ldapConnection): dacl = sd['Dacl'] if dacl and hasattr(dacl, 'aces') and dacl.aces: for ace in dacl.aces: - # Only process ALLOW ACEs - if ace['AceType'] != ldaptypes.ACCESS_ALLOWED_ACE.ACE_TYPE: + #Ensure we parse and process standard ACE and Object Specific ACE + allowed_types = [ + ldaptypes.ACCESS_ALLOWED_ACE.ACE_TYPE, + ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ACE_TYPE + ] + if ace['AceType'] not in allowed_types: continue # Check if ACE has relevant rights From efef586d4f14d3380f45af6245f40bbbf6be494f Mon Sep 17 00:00:00 2001 From: Abdul Mhanni Date: Thu, 9 Apr 2026 20:36:19 -0400 Subject: [PATCH 2/3] Fixed GUID parser for ObjectType handling for object-specific ACEs --- examples/badsuccessor.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/badsuccessor.py b/examples/badsuccessor.py index c323564e13..b08fc57e3c 100644 --- a/examples/badsuccessor.py +++ b/examples/badsuccessor.py @@ -32,7 +32,7 @@ from impacket.examples import logger from impacket.examples.utils import parse_identity, parse_target, init_ldap_session from impacket.ldap import ldaptypes - +import uuid #needed for proper GUID conversion class BADSUCCESSOR: def __init__(self, username, password, domain, lmhash, nthash, cmdLineOptions): @@ -281,7 +281,7 @@ def search_ous(self, ldapConnection): dacl = sd['Dacl'] if dacl and hasattr(dacl, 'aces') and dacl.aces: for ace in dacl.aces: - #Ensure we parse and process standard ACE and Object Specific ACE + #Fix 1, Ensure we parse and process standard ACE and Object Specific ACE allowed_types = [ ldaptypes.ACCESS_ALLOWED_ACE.ACE_TYPE, ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ACE_TYPE @@ -294,11 +294,13 @@ def search_ous(self, ldapConnection): has_relevant_right = any(mask & right_value for right_value in relevant_rights.values()) if not has_relevant_right: continue + #Fix two: The guid conversion was wrong and one actually reads the bytes correctly and converts them to real GUIDs for processing later + ace_data = ace['Ace'] + object_type = ace_data['ObjectType'] - # Check object type (must match relevant object types) - object_type = getattr(ace['Ace'], 'ObjectType', None) if object_type: - object_guid = str(object_type).lower() + object_guid = str(uuid.UUID(bytes_le=object_type)).lower() + logging.debug(object_guid) if object_guid not in relevant_object_types: continue From 9ca2d4977633f99126cc426dba12d9a6707620ad Mon Sep 17 00:00:00 2001 From: ThatTotallyRealMyth <106909154+ThatTotallyRealMyth@users.noreply.github.com> Date: Sun, 26 Apr 2026 10:35:53 +1000 Subject: [PATCH 3/3] Apply suggestion from @alexisbalbachan Co-authored-by: alexisbalbachan --- examples/badsuccessor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/badsuccessor.py b/examples/badsuccessor.py index b08fc57e3c..d0ec0b8269 100644 --- a/examples/badsuccessor.py +++ b/examples/badsuccessor.py @@ -296,7 +296,7 @@ def search_ous(self, ldapConnection): continue #Fix two: The guid conversion was wrong and one actually reads the bytes correctly and converts them to real GUIDs for processing later ace_data = ace['Ace'] - object_type = ace_data['ObjectType'] + object_type = ace_data['ObjectType'] if ace['AceType'] == ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ACE_TYPE else None if object_type: object_guid = str(uuid.UUID(bytes_le=object_type)).lower()