Python Tools Using ldap3 and Issues with Channel Binding and Signing
Fixing issues in common tools with Python ldap3 when connecting to Domain Controllers with LDAP signing and binding enabled.
On a number of recent internal penetration tests I have come across domain controllers with both LDAP signing and channel binding enabled. This is great for the client's security as it means relaying attacks are a non starter but it also means that a number of tools that we use to query LDAP, dump information and perform attacks are not able to connect.
I first noticed this issue when Crackmapexec would connect to the DC fine over SMB and confirm credentials are valid but using the same credentials to connect over LDAP would return that the credentials were invalid. Additionally ldapdomaindump and certipy would return also return invalid credentials despite them being correct. Additionally, msldap would work fine and connect with no issue.
If you encounter the same issue it is a simple fix to get ldapdomaindump and certipy working (and any other tools that use the python ldap3 library in the same manner)
Both ldapdomaindump and certipy use ldap3, as you can see on lines 118-124 in the source of certipy's ldap.py file, it build the following ldap connection object.
ldap_conn = ldap3.Connection( ldap_server, user=user, password=ldap_pass, authentication=ldap3.NTLM, auto_referrals=False, receive_timeout=self.target.timeout * 10, )
for some reason when LDAP signing and channel binding are enabled this will fail, in order for the connection to work the ldap connection needs to instead be in the following format
ldap_conn = ldap3.Connection( ldap_server, users_distinguished_name, password, )
here is a hard coded example.
ldap_conn = ldap3.Connection( ldap_server, 'CN=pwneduser ,OU=Standard Users,OU=Users,OU=Accounts,OU=Data Management,DC=evilcorp,DC=local', 'supersecurepassword' )
Rebuilding/reinstalling certipy with a hard coded connection string like above will authenticate without issue.
This means you will need to know the distinguished name (DN) of any user credentials you get your hands on, this can be gathered using msldap which handles LDAP signing and binding fine.
I will endeavour to raise an issue/pull request in the relevent projects to get this fixed upstream, but for now the above should enable you to continue hacking when you encouter this issue.