ly4k / Certipy

Tool for Active Directory Certificate Services enumeration and abuse
MIT License
2.39k stars 330 forks source link

Problems with passwords that contain '#' ? #60

Closed 7MinSec closed 2 years ago

7MinSec commented 2 years ago

Hello,

I'm using certipy on a pentest where my AD account password has '#' in it. When I run a 'certipy find' I get the below error in the output. I am running the latest/greatest certipy on 2 different pentests right now, and on the pentest where my password is just upper/lower/numbers (and a special character that is not a '#'), certipy runs fine.

[*] Finding certificate templates
[+] Authenticating to LDAP server
[-] Got error: PY_SSIZE_T_CLEAN macro must be defined for '#' formats
Traceback (most recent call last):
  File "/usr/lib/python3.10/hashlib.py", line 160, in __hash_new
    return _hashlib.new(name, data, **kwargs)
ValueError: [digital envelope routines] unsupported

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/ldap3/utils/ntlm.py", line 497, in ntowf_v2
    password_digest = hashlib.new('MD4', self._password.encode('utf-16-le')).digest()
  File "/usr/lib/python3.10/hashlib.py", line 166, in __hash_new
    return __get_builtin_constructor(name)(data)
  File "/usr/lib/python3.10/hashlib.py", line 123, in __get_builtin_constructor
    raise ValueError('unsupported hash type ' + name)
ValueError: unsupported hash type MD4

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/dist-packages/Certipy-3.0.0-py3.10.egg/certipy/entry.py", line 85, in main
    actions[options.action](options)
  File "/usr/local/lib/python3.10/dist-packages/Certipy-3.0.0-py3.10.egg/certipy/find.py", line 736, in entry
    find.find()
  File "/usr/local/lib/python3.10/dist-packages/Certipy-3.0.0-py3.10.egg/certipy/find.py", line 116, in find
    certificate_templates = self.get_certificate_templates()
  File "/usr/local/lib/python3.10/dist-packages/Certipy-3.0.0-py3.10.egg/certipy/find.py", line 691, in get_certificate_templates
    certificate_templates = self.connection.search(
  File "/usr/local/lib/python3.10/dist-packages/Certipy-3.0.0-py3.10.egg/certipy/find.py", line 109, in connection
    self._connection.connect()
  File "/usr/local/lib/python3.10/dist-packages/Certipy-3.0.0-py3.10.egg/certipy/ldap.py", line 53, in connect
    self.connect(version=ssl.PROTOCOL_TLSv1_2)
  File "/usr/local/lib/python3.10/dist-packages/Certipy-3.0.0-py3.10.egg/certipy/ldap.py", line 100, in connect
    bind_result = ldap_conn.bind()
  File "/usr/lib/python3/dist-packages/ldap3/core/connection.py", line 621, in bind
    response = self.do_ntlm_bind(controls)
  File "/usr/lib/python3/dist-packages/ldap3/core/connection.py", line 1388, in do_ntlm_bind
    request = bind_operation(self.version, 'SICILY_RESPONSE_NTLM', ntlm_client,
  File "/usr/lib/python3/dist-packages/ldap3/operation/bind.py", line 81, in bind_operation
    server_creds = name.create_authenticate_message()
  File "/usr/lib/python3/dist-packages/ldap3/utils/ntlm.py", line 379, in create_authenticate_message
    nt_challenge_response = self.compute_nt_response()
  File "/usr/lib/python3/dist-packages/ldap3/utils/ntlm.py", line 485, in compute_nt_response
    response_key_nt = self.ntowf_v2()
  File "/usr/lib/python3/dist-packages/ldap3/utils/ntlm.py", line 501, in ntowf_v2
    password_digest = MD4.new(self._password.encode('utf-16-le')).digest()
SystemError: PY_SSIZE_T_CLEAN macro must be defined for '#' formats
7MinSec commented 2 years ago

Digging around now it looks like it might be a python version thing. Will update with what I find.

ly4k commented 2 years ago

Hello @braimee. Thanks for reporting. I'm looking into it. It seems like this is caused by Python 3.10 (https://bugs.python.org/issue40943). Nonetheless, I'll try to debug it and see if there's a way around. If you haven't found a temporary solution, I can recommend creating the NT hash yourself and pass it to Certipy with -hashes. It's an MD4 sum of the utf16-le encoded password. So you encode the password as utf16-le (little endian) and then hash it with MD4.

ly4k commented 2 years ago

Can you please try in a clean Python virtual environment? I cannot reproduce with Python 3.10

7MinSec commented 2 years ago

Hey pardon the delay, I started another test and used python3.9 to run the setup file. This time when I do a certipy find I get:

[*] Finding certificate templates
[+] Authenticating to LDAP server
[-] Got error: unsupported hash type MD4
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/ldap3/utils/ntlm.py", line 500, in ntowf_v2
    from Crypto.Hash import MD4  # try with the Crypto library if present
ModuleNotFoundError: No module named 'Crypto'

Googling this error it looks like I might want to install pycryptodome but I did that, and no love. I'll keep looking but any ideas based on the info above?

I'll also try the python virtual environment but I'm a newb at that so will need to research a bit.

7MinSec commented 2 years ago

Hello, I'm thinking it's "just a me thing," but in the meantime I did get around this by requesting a TGT using impacket toolkit first, and then got my certipy req to run using -k -no-pass params.

ly4k commented 2 years ago

Hello @braimee Thanks for returning back. I'm glad you resolved your issue. And even if it has something to do with your Python environment, I would be happy to see if I can do something about it by either specifying a fixed version of something to force it to be compatible. However, I cannot reproduce this error, even in a virtual environment unfortunately.

nionios commented 11 months ago

Hello @7MinSec, this was not just a you thing, this still happens in 2023 in my macOS 13.6.1 with Python 3.11.6 . pycryptodome-only installations output ValueError: unsupported hash type MD4 error, while installations with pycrypto output SystemError: PY_SSIZE_T_CLEAN macro must be defined for '#' formats error.