无法使用 python ldap3 设置“用户无法更改密码”ACE

问题描述 投票:0回答:1

我正在尝试通过 Python 中的 Ldap3 库创建一个服务帐户。服务帐户创建成功,但是有一个小问题。未选中“用户无法更改密码”复选框。

我做了一些研究,发现要设置此属性,我需要遵循此处给出的一些步骤:https://learn.microsoft.com/en-us/windows/win32/adsi/modifying-user-cannot-change - 密码 ldap-provider 。此链接中给出的逻辑采用与 Python 不同的编程语言,因此我尝试在 Python 中复制相同的逻辑。据我们了解,我已经实现了该功能,并且执行成功,但在 AD 服务器上没有看到预期的效果(“用户无法更改密码”复选框仍未选中)。

下面是用于创建 ACL 对象并将其添加到服务帐户的代码。

def create_object_ace(privguid, sid):
    print("creating ace object")
    nace = ldaptypes.ACE()
    nace['AceType'] =     ldaptypes.ACCESS_DENIED_OBJECT_ACE.ACE_TYPE
nace['AceFlags'] = 0x00
acedata = ldaptypes.ACCESS_DENIED_OBJECT_ACE()
acedata['Mask'] = ldaptypes.ACCESS_MASK()
acedata['Mask']['Mask'] = ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ADS_RIGHT_DS_CONTROL_ACCESS
acedata['ObjectType'] = string_to_bin(privguid)
acedata['InheritedObjectType'] = b''
acedata['Sid'] = ldaptypes.LDAP_SID()
acedata['Sid'].fromCanonical(sid)
assert sid == acedata['Sid'].formatCanonical()
acedata['Flags'] = ldaptypes.ACCESS_DENIED_OBJECT_ACE.ACE_OBJECT_TYPE_PRESENT
nace['Ace'] = acedata
return nace

s = Server('ad_server.com', get_info=ALL)
c = Connection(s, user="testdomain\\username", password="password", authentication=NTLM)
 c.search(search_base="DC=testad,DC=com", search_filter="(CN=svc_account_47)",
     search_scope=SUBTREE, attributes=['objectSid', 'sAMAccountName'])

entry = c.entries[0]
usersid = entry['objectSid'].value

controls = security_descriptor_control(sdflags=0x04)
 c.search(search_base="DC=testahs,DC=com", search_filter='(&(objectCategory=domain))',
     attributes=['SAMAccountName', 'nTSecurityDescriptor'], controls=controls)
entry = c.entries[0]
secDescData =.    entry['nTSecurityDescriptor'].raw_values[0]
secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData)

secDesc['Dacl']['Data'].append(create_object_ace('ab721a53-1e2f-11d0-9819-00aa0040529b', usersid)) # This GUID is for 'User cannot change password'

dn = entry.entry_dn
data = secDesc.getData()

c.modify(dn, {'nTSecurityDescriptor': (ldap3.MODIFY_REPLACE, [data])}, controls=controls)

print(c.result)  

# gives -> {'result': 0, 'description': 'success', 'dn': '', 'message': '', 'referrals': None, 'type': 'modifyResponse'}

Python代码参考来自以下链接:

https://github.com/SecureAuthCorp/impacket/blob/master/impacket/examples/ntlmrelayx/attacks/ldapattack.py

有人可以帮助我吗?预先感谢。

python python-3.x active-directory python-ldap ldap3
1个回答
0
投票

我在 Python 中做到这一点的唯一方法是:

import uuid
import bonsai
from bonsai import LDAPClient
from bonsai.active_directory import SecurityDescriptor

def set_not_change_pass(self, userdn):
    client = LDAPClient(f"ldap://{self._server}")
    client.set_credentials("SIMPLE", user=f"CN={self._srvaccname},CN=Users,{self._dc}",
                           password=self._srvaccpass)

    with client.connect() as conn:
        entry = conn.search(
            userdn, 0, attrlist=["ntSecurityDescriptor", "userAccountControl"]
        )[0]
        uac = bonsai.active_directory.UserAccountControl(entry["userAccountControl"][0])
        sec_desc = bonsai.active_directory.SecurityDescriptor.from_binary(
            entry["ntSecurityDescriptor"][0]
        )

        new_dacl_aces = []
        for ace in sec_desc.dacl.aces:
            if ace.object_type == uuid.UUID("ab721a53-1e2f-11d0-9819-00aa0040529b"):
                # Find change password ACE and change it to deny.
                new_ace = bonsai.active_directory.ACE(
                    bonsai.active_directory.ACEType.ACCESS_DENIED_OBJECT,
                    ace.flags,
                    ace.mask,
                    ace.trustee_sid,
                    ace.object_type,
                    ace.inherited_object_type,
                    ace.application_data,
                )

                # Insert new deny ACEs to the front of the list.
                new_dacl_aces.insert(0, new_ace)
            else:
                new_dacl_aces.append(ace)

        new_dacl = bonsai.active_directory.ACL(sec_desc.dacl.revision, new_dacl_aces)
        new_sec_desc = bonsai.active_directory.SecurityDescriptor(
            sec_desc.control,
            sec_desc.owner_sid,
            sec_desc.group_sid,
            sec_desc.sacl,
            new_dacl,
            sec_desc.revision,
            sec_desc.sbz1,
        )

        entry.change_attribute(
            "ntSecurityDescriptor", bonsai.LDAPModOp.REPLACE, new_sec_desc.to_binary()
        )
        uac.properties["accountdisable"] = False
        entry.change_attribute("userAccountControl", bonsai.LDAPModOp.REPLACE, uac.value)
        entry.modify()
© www.soinside.com 2019 - 2024. All rights reserved.