Skip to content
This repository has been archived by the owner on Dec 6, 2023. It is now read-only.

Fixed LDAPS with Kerberos #595

Merged
merged 1 commit into from
Jun 28, 2022
Merged

Fixed LDAPS with Kerberos #595

merged 1 commit into from
Jun 28, 2022

Conversation

lap1nou
Copy link
Contributor

@lap1nou lap1nou commented Jun 28, 2022

Hello,

When I run this command:

poetry run crackmapexec ldap dc.lab.local -k -u 'test' -d lab.local --kdcHost dc.lab.local -k

I get this error:

OpenSSL.SSL.Error: [('SSL routines', '', 'internal error')]

I saw your PR for Impacket, fixing this for MSSQL, but I don't think it was fix for LDAPS, so I fixed it (see PR: mpgn/impacket#2), but after that fix, I encountered another error:

Traceback (most recent call last):
  File "/home/zyzz/CrackMapExec/cme/protocols/ldap.py", line 193, in kerberos_login
    self.ldapConnection.kerberosLogin(self.username, self.password, self.domain, self.lmhash, self.nthash,
  File "/home/zyzz/.cache/pypoetry/virtualenvs/crackmapexec-sr4VS0Ju-py3.9/lib/python3.9/site-packages/impacket/ldap/ldap.py", line 244, in kerberosLogin
    raise LDAPSessionError(
impacket.ldap.ldap.LDAPSessionError: Error in bindRequest -> strongerAuthRequired: 00002028: LdapErr: DSID-0C090259, comment: The server requires binds to turn on integrity checking if SSL\TLS are not already active on the connection, data 0, v4563

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/zyzz/CrackMapExec/cme/crackmapexec.py", line 256, in main
    asyncio.run(
  File "/usr/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.9/asyncio/base_events.py", line 647, in run_until_complete
    return future.result()
  File "/home/zyzz/CrackMapExec/cme/crackmapexec.py", line 104, in start_threadpool
    await asyncio.gather(*jobs)
  File "/home/zyzz/CrackMapExec/cme/crackmapexec.py", line 68, in run_protocol
    await asyncio.wait_for(
  File "/usr/lib/python3.9/asyncio/tasks.py", line 442, in wait_for
    return await fut
  File "/usr/lib/python3.9/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/zyzz/CrackMapExec/cme/protocols/ldap.py", line 53, in __init__
    connection.__init__(self, args, db, host)
  File "/home/zyzz/CrackMapExec/cme/connection.py", line 62, in __init__
    self.proto_flow()
  File "/home/zyzz/CrackMapExec/cme/connection.py", line 98, in proto_flow
    if self.login() or (self.username == '' and self.password == ''):
  File "/home/zyzz/CrackMapExec/cme/connection.py", line 163, in login
    if self.kerberos_login(self.domain, self.aesKey, self.kdcHost): return True
  File "/home/zyzz/CrackMapExec/cme/protocols/ldap.py", line 211, in kerberos_login
    self.logger.success(out)
UnboundLocalError: local variable 'out' referenced before assignment

If we look at the code we can see that the out variable is assigned after a possible error due to the mandatory LDAPS usage:

try:
            self.ldapConnection = ldap_impacket.LDAPConnection('ldap://%s' % target, self.baseDN, self.kdcHost)
            self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash) <---- exception here if LDAPS mandatory
            self.check_if_admin()
            out = u'{}{}:{} {}'.format('{}\\'.format(domain), <----- declared here
                                    username,
                                    nthash if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
                                    highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))
            self.logger.extra['protocol'] = "LDAP"
            self.logger.extra['port'] = "389"
            self.logger.success(out)

            if not self.args.local_auth:
                add_user_bh(self.username, self.domain, self.logger, self.config)
            if not self.args.continue_on_success:
                return True
        except ldap_impacket.LDAPSessionError as e:
            if str(e).find('strongerAuthRequired') >= 0:
                try:
                    # We need to try SSL
                    self.ldapConnection = ldap_impacket.LDAPConnection('ldaps://%s' % target, self.baseDN, self.kdcHost)
                    self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash)
                    self.logger.extra['protocol'] = "LDAPS"
                    self.logger.extra['port'] = "636"
                    self.logger.success(out) <---- used here

Normally, the original command should now work correctly.

@mpgn mpgn merged commit ef76575 into byt3bl33d3r:master Jun 28, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants