Exemplo n.º 1
0
    def from_buffer(buff, object_type=None):
        sd = SECURITY_DESCRIPTOR(object_type)
        sd.Revision = int.from_bytes(buff.read(1), 'little', signed=False)
        sd.Sbz1 = int.from_bytes(buff.read(1), 'little', signed=False)
        sd.Control = SE_SACL(
            int.from_bytes(buff.read(2), 'little', signed=False))
        OffsetOwner = int.from_bytes(buff.read(4), 'little', signed=False)
        OffsetGroup = int.from_bytes(buff.read(4), 'little', signed=False)
        OffsetSacl = int.from_bytes(buff.read(4), 'little', signed=False)
        OffsetDacl = int.from_bytes(buff.read(4), 'little', signed=False)

        if OffsetOwner > 0:
            buff.seek(OffsetOwner)
            sd.Owner = SID.from_buffer(buff)

        if OffsetGroup > 0:
            buff.seek(OffsetGroup)
            sd.Group = SID.from_buffer(buff)

        if OffsetSacl > 0:
            buff.seek(OffsetSacl)
            sd.Sacl = ACL.from_buffer(buff, object_type)

        if OffsetDacl > 0:
            buff.seek(OffsetDacl)
            sd.Dacl = ACL.from_buffer(buff, object_type)

        return sd
Exemplo n.º 2
0
    async def add_priv_dcsync(self, user_dn, forest_dn=None):
        """Adds DCSync rights to the given user by modifying the forest's Security Descriptor to add GetChanges and GetChangesAll ACE"""
        try:
            #getting SID of target dn
            user_sid, err = await self.get_objectsid_for_dn(user_dn)
            if err is not None:
                raise err

            if forest_dn is None:
                forest_dn = self._ldapinfo.distinguishedName

            res, err = await self.get_objectacl_by_dn(forest_dn)
            if err is not None:
                raise err
            if res is None:
                raise Exception('Failed to get forest\'s SD')
            forest_sd = SECURITY_DESCRIPTOR.from_bytes(res)

            new_sd = copy.deepcopy(forest_sd)

            ace_1 = ACCESS_ALLOWED_OBJECT_ACE()
            ace_1.Sid = SID.from_string(user_sid)
            ace_1.ObjectType = GUID.from_string(
                '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2')
            ace_1.Mask = ADS_ACCESS_MASK.CONTROL_ACCESS
            ace_1.AceFlags = 0

            new_sd.Dacl.aces.append(ace_1)

            ace_2 = ACCESS_ALLOWED_OBJECT_ACE()
            ace_2.Sid = SID.from_string(user_sid)
            ace_2.ObjectType = GUID.from_string(
                '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2')
            ace_2.Mask = ADS_ACCESS_MASK.CONTROL_ACCESS
            ace_2.AceFlags = 0

            new_sd.Dacl.aces.append(ace_2)

            changes = {
                'nTSecurityDescriptor': [('replace', [new_sd.to_bytes()])]
            }
            _, err = await self.modify(forest_dn, changes)
            if err is not None:
                raise err

            return True, None
        except Exception as e:
            return False, e
Exemplo n.º 3
0
def LookupAccountNameW(lpSystemName, accountname):
    _LookupAccountNameW = windll.advapi32.LookupAccountNameW
    _LookupAccountNameW.argtypes = [
        LPWSTR, LPWSTR, PSID, LPDWORD, LPWSTR, LPDWORD, LPDWORD
    ]
    _LookupAccountNameW.restype = BOOL

    cbSid = DWORD(0)
    cchReferencedDomainName = DWORD(0)
    peUse = DWORD(0)
    lpAccountName = ctypes.create_unicode_buffer(accountname)
    _LookupAccountNameW(lpSystemName, lpAccountName, None, byref(cbSid), None,
                        byref(cchReferencedDomainName), byref(peUse))
    error = GetLastError()
    if error != ERROR_INSUFFICIENT_BUFFER:
        raise (ctypes.WinError(error))
    sid = ctypes.create_string_buffer(b'', cbSid.value)
    psid = ctypes.cast(ctypes.pointer(sid), PSID)
    lpReferencedDomainName = ctypes.create_unicode_buffer(
        u'', cchReferencedDomainName.value + 1)
    success = _LookupAccountNameW(lpSystemName, lpAccountName, psid,
                                  byref(cbSid), lpReferencedDomainName,
                                  byref(cchReferencedDomainName), byref(peUse))
    if not success:
        raise ctypes.WinError()

    buff = MemoryBuffer(psid.value)
    sid = SID.from_buffer(buff)
    #LocalFree(psid)
    return sid, lpReferencedDomainName.value, peUse.value
Exemplo n.º 4
0
    def from_ldap(entry):
        adi = MSADDomainTrust()
        adi.sn = entry['attributes'].get('sn')
        adi.cn = entry['attributes'].get('cn')
        adi.distinguishedName = entry['attributes'].get('distinguishedName')
        adi.objectGUID = entry['attributes'].get('objectGUID')
        adi.instanceType = entry['attributes'].get('instanceType')
        adi.whenCreated = entry['attributes'].get('whenCreated')
        adi.whenChanged = entry['attributes'].get('whenChanged')
        adi.name = entry['attributes'].get('name')
        adi.securityIdentifier = entry['attributes'].get('securityIdentifier')
        adi.trustDirection = entry['attributes'].get('trustDirection')
        adi.trustPartner = entry['attributes'].get('trustPartner')
        adi.trustPosixOffset = entry['attributes'].get('trustPosixOffset')
        adi.trustType = entry['attributes'].get('trustType')
        adi.trustAttributes = entry['attributes'].get('trustAttributes')
        adi.flatName = entry['attributes'].get('flatName')
        adi.dSCorePropagationData = entry['attributes'].get(
            'dSCorePropagationData')

        if adi.securityIdentifier is not None:
            adi.securityIdentifier = SID.from_bytes(adi.securityIdentifier)
        if adi.trustType is not None:
            adi.trustType = TrustType(adi.trustType)
        if adi.trustDirection is not None:
            adi.trustDirection = TrustDirection(adi.trustDirection)
        return adi
Exemplo n.º 5
0
 def from_ldap(entry):
     t = MSADTokenGroup()
     t.cn = entry['attributes'].get('cn')
     t.distinguishedName = entry['attributes'].get('distinguishedName')
     t.objectGUID = entry['attributes'].get('objectGUID')
     t.objectSid = entry['attributes'].get('objectSid')
     for sid_data in entry['attributes']['tokenGroups']:
         t.tokengroups.append(SID.from_bytes(sid_data))
     return t
Exemplo n.º 6
0
    async def do_changeowner(self,
                             new_owner_sid,
                             target_dn,
                             target_attribute=None):
        """Changes the owner in a Security Descriptor to the new_owner_sid on an LDAP object or on an LDAP object's attribute identified by target_dn and target_attribute. target_attribute can be omitted to change the target_dn's SD's owner"""
        try:
            await self.do_ldapinfo(False)
            await self.do_adinfo(False)

            try:
                new_owner_sid = SID.from_string(new_owner_sid)
            except:
                print('Incorrect SID!')
                return False, Exception('Incorrect SID')

            target_sd = None
            if target_attribute is None or target_attribute == '':
                target_attribute = 'nTSecurityDescriptor'
                res, err = await self.connection.get_objectacl_by_dn(target_dn)
                if err is not None:
                    raise err
                target_sd = SECURITY_DESCRIPTOR.from_bytes(res)
            else:

                query = '(distinguishedName=%s)' % target_dn
                async for entry, err in self.connection.pagedsearch(
                        query, [target_attribute]):
                    if err is not None:
                        raise err
                    print(entry['attributes'][target_attribute])
                    target_sd = SECURITY_DESCRIPTOR.from_bytes(
                        entry['attributes'][target_attribute])
                    break
                else:
                    print('Target DN not found!')
                    return False, Exception('Target DN not found!')

            new_sd = copy.deepcopy(target_sd)
            new_sd.Owner = new_owner_sid

            changes = {target_attribute: [('replace', [new_sd.to_bytes()])]}
            _, err = await self.connection.modify(target_dn, changes)
            if err is not None:
                raise err

            print('Change OK!')
        except:
            traceback.print_exc()
Exemplo n.º 7
0
def ConvertStringSidToSidW(sid_str):
    _ConvertStringSidToSidW = windll.advapi32.ConvertStringSidToSidW
    _ConvertStringSidToSidW.argtypes = [
        PVOID, PVOID
    ]  #[HANDLE, SE_OBJECT_TYPE, DWORD, PSID, PSID, PACL, PACL, PSECURITY_DESCRIPTOR]
    _ConvertStringSidToSidW.restype = DWORD
    _ConvertStringSidToSidW.errcheck = RaiseIfZero

    cstr_sid = ctypes.create_string_buffer(sid_str.encode('utf-16-le'))
    ppSecurityDescriptor = ctypes.pointer(ctypes.c_uint(0))

    _ConvertStringSidToSidW(cstr_sid, byref(ppSecurityDescriptor))
    buff = MemoryBuffer(ctypes.addressof(ppSecurityDescriptor.contents))
    sd = SID.from_buffer(buff)
    LocalFree(ppSecurityDescriptor)
    return sd
Exemplo n.º 8
0
    async def do_addenrollmentright(self, certtemplatename, user_dn):
        """Grants enrollment rights to a user (by DN) for the specified certificate template."""
        try:
            user_sid, err = await self.connection.get_objectsid_for_dn(user_dn)
            if err is not None:
                raise err

            template = None
            async for template, err in self.connection.list_certificate_templates(
                    certtemplatename):
                if err is not None:
                    raise err
                break

            if template is None:
                raise Exception("Template could not be found!")
            template = typing.cast(MSADCertificateTemplate, template)
            new_sd = copy.deepcopy(template.nTSecurityDescriptor)
            ace = ACCESS_ALLOWED_OBJECT_ACE()
            ace.Sid = SID.from_string(user_sid)
            ace.ObjectType = GUID.from_string(EX_RIGHT_CERTIFICATE_ENROLLMENT)
            ace.AceFlags = AceFlags(0)
            ace.Mask = ADS_ACCESS_MASK.READ_PROP | ADS_ACCESS_MASK.WRITE_PROP | ADS_ACCESS_MASK.CONTROL_ACCESS
            ace.Flags = ACE_OBJECT_PRESENCE.ACE_OBJECT_TYPE_PRESENT
            new_sd.Dacl.aces.append(ace)
            _, err = await self.connection.set_objectacl_by_dn(
                template.distinguishedName,
                new_sd.to_bytes(),
                flags=SDFlagsRequest.DACL_SECURITY_INFORMATION)
            if err is not None:
                raise err
            print('SD set sucessfully')
            return True
        except:
            traceback.print_exc()
            return False
Exemplo n.º 9
0
    async def add_priv_addmember(self, user_dn, group_dn):
        """Adds AddMember rights to the user on the group specified by group_dn"""
        try:
            #getting SID of target dn
            user_sid, err = await self.get_objectsid_for_dn(user_dn)
            if err is not None:
                raise err

            res, err = await self.get_objectacl_by_dn(group_dn)
            if err is not None:
                raise err
            if res is None:
                raise Exception('Failed to get forest\'s SD')
            group_sd = SECURITY_DESCRIPTOR.from_bytes(res)

            new_sd = copy.deepcopy(group_sd)

            ace_1 = ACCESS_ALLOWED_OBJECT_ACE()
            ace_1.Sid = SID.from_string(user_sid)
            ace_1.ObjectType = GUID.from_string(
                'bf9679c0-0de6-11d0-a285-00aa003049e2')
            ace_1.Mask = ADS_ACCESS_MASK.WRITE_PROP
            ace_1.AceFlags = 0

            new_sd.Dacl.aces.append(ace_1)

            changes = {
                'nTSecurityDescriptor': [('replace', [new_sd.to_bytes()])]
            }
            _, err = await self.modify(group_dn, changes)
            if err is not None:
                raise err

            return True, None
        except Exception as e:
            return False, e
Exemplo n.º 10
0
def list_x2sid(x):
	t = []
	for s in x:
		t.append(str(SID.from_bytes(s)))
	return t
Exemplo n.º 11
0
def x2sid(x):
	return str(SID.from_bytes(x[0]))
Exemplo n.º 12
0
    def from_sddl(sddl: str, object_type=None, domain_sid=None):
        sd = SECURITY_DESCRIPTOR(object_type=object_type)
        params = sddl.split(':')
        np = [params[0]]
        i = 1
        while i < len(params):
            np.append(params[i][:-1])
            np.append(params[i][-1])
            i += 1
        params = {}
        i = 0
        while i < len(np):
            if np[i] == ')':
                break
            params[np[i]] = np[i + 1]
            i += 2

        sd.Control = SE_SACL.SE_SELF_RELATIVE
        fk = None
        if 'D' in params:
            fk = 'D'
        elif 'S' in params:
            fk = 'S'

        if fk is not None:
            if '(' in params[fk]:
                flags, acl = params[fk].split('(', 1)
            else:
                flags = params[fk]
            if flags.upper().find('P') != -1:
                sd.Control |= SE_SACL.SE_DACL_PROTECTED
                sd.Control |= SE_SACL.SE_SACL_PROTECTED
                flags = flags.replace('P', '')
            for _ in range(len(flags)):
                x = flags[:2]
                cf = sddl_acl_control_flags[x]
                if cf == SE_SACL.SE_DACL_AUTO_INHERIT_REQ:
                    sd.Control |= SE_SACL.SE_DACL_AUTO_INHERIT_REQ
                    sd.Control |= SE_SACL.SE_SACL_AUTO_INHERIT_REQ
                elif cf == SE_SACL.SE_DACL_AUTO_INHERITED:
                    sd.Control |= SE_SACL.SE_DACL_AUTO_INHERITED
                    sd.Control |= SE_SACL.SE_SACL_AUTO_INHERITED
                else:
                    sd.Control |= cf

                flags = flags[2:]
                if flags == '':
                    break

        if 'O' in params:
            sd.Owner = SID.from_sddl(params['O'], domain_sid=domain_sid)
        if 'G' in params:
            sd.Group = SID.from_sddl(params['G'], domain_sid=domain_sid)
        if 'D' in params:
            sd.Control |= SE_SACL.SE_DACL_PRESENT
            acl = params['D']
            m = acl.find('(')
            if m != -1:
                sd.Dacl = ACL.from_sddl(acl[m:],
                                        object_type=object_type,
                                        domain_sid=domain_sid)
        if 'S' in params:
            sd.Control |= SE_SACL.SE_SACL_PRESENT
            acl = params['S']
            m = acl.find('(')
            if m != -1:
                sd.Sacl = ACL.from_sddl(acl[m:],
                                        object_type=object_type,
                                        domain_sid=domain_sid)

        return sd
Exemplo n.º 13
0
def get_user_for_sid(sid_str):
    sid = SID.from_string(sid_str)
    username, domain, use = LookupAccountSidW(None, sid.to_bytes())
    return '%s\\%s' % (domain, username)