diff --git a/certipy/lib/constants.py b/certipy/lib/constants.py index 1b6d13e..4880e46 100755 --- a/certipy/lib/constants.py +++ b/certipy/lib/constants.py @@ -252,6 +252,7 @@ class CERTIFICATE_RIGHTS(IntFlag): GENERIC_ALL = 983551 WRITE_OWNER = 524288 WRITE_DACL = 262144 + EXTENDED_RIGHT = 256 WRITE_PROPERTY = 32 def to_list(self): diff --git a/certipy/lib/security.py b/certipy/lib/security.py index cf2044d..800ae96 100755 --- a/certipy/lib/security.py +++ b/certipy/lib/security.py @@ -10,6 +10,7 @@ ACTIVE_DIRECTORY_RIGHTS, CERTIFICATE_RIGHTS, CERTIFICATION_AUTHORITY_RIGHTS, + EXTENDED_RIGHTS_NAME_MAP, ) @@ -38,26 +39,53 @@ def __init__( "inherited": ace["AceFlags"] & INHERITED_ACE == INHERITED_ACE, } + mask = self.RIGHTS_TYPE(ace["Ace"]["Mask"]["Mask"]) if ace["AceType"] == ldaptypes.ACCESS_ALLOWED_ACE.ACE_TYPE: - self.aces[sid]["rights"] |= self.RIGHTS_TYPE(ace["Ace"]["Mask"]["Mask"]) + self.aces[sid]["rights"] |= mask - if ace["AceType"] == ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ACE_TYPE: - if ace["Ace"]["Flags"] == 2: - uuid = bin_to_string(ace["Ace"]["InheritedObjectType"]).lower() - elif ace["Ace"]["Flags"] == 1: - uuid = bin_to_string(ace["Ace"]["ObjectType"]).lower() - else: - continue + if self.RIGHTS_TYPE.EXTENDED_RIGHT & mask: + self.aces[sid]["extended_rights"].append(EXTENDED_RIGHTS_NAME_MAP["All-Extended-Rights"]) + if ace["AceType"] == ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ACE_TYPE and \ + self.RIGHTS_TYPE.EXTENDED_RIGHT & mask and \ + ace['Ace'].hasFlag(ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ACE_OBJECT_TYPE_PRESENT): + + uuid = bin_to_string(ace["Ace"]["ObjectType"]).lower() self.aces[sid]["extended_rights"].append(uuid) -class CASecurity(ActiveDirectorySecurity): +class CertifcateSecurity(ActiveDirectorySecurity): + RIGHTS_TYPE = CERTIFICATE_RIGHTS + + +class CASecurity: RIGHTS_TYPE = CERTIFICATION_AUTHORITY_RIGHTS + def __init__( + self, + security_descriptor: bytes, + ): + sd = ldaptypes.SR_SECURITY_DESCRIPTOR() + sd.fromString(security_descriptor) + self.sd = sd -class CertifcateSecurity(ActiveDirectorySecurity): - RIGHTS_TYPE = CERTIFICATE_RIGHTS + self.owner = format_sid(sd["OwnerSid"].getData()) + self.aces = {} + + aces = sd["Dacl"]["Data"] + for ace in aces: + sid = format_sid(ace["Ace"]["Sid"].getData()) + + if sid not in self.aces: + self.aces[sid] = { + "rights": self.RIGHTS_TYPE(0), + "extended_rights": [], + "inherited": ace["AceFlags"] & INHERITED_ACE == INHERITED_ACE, + } + + mask = self.RIGHTS_TYPE(ace["Ace"]["Mask"]["Mask"]) + if ace["AceType"] == ldaptypes.ACCESS_ALLOWED_ACE.ACE_TYPE: + self.aces[sid]["rights"] |= mask def is_admin_sid(sid: str):