Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authentication error for Windows Server 2022? #167

Closed
symmetrisch opened this issue Sep 18, 2023 · 15 comments
Closed

Authentication error for Windows Server 2022? #167

symmetrisch opened this issue Sep 18, 2023 · 15 comments

Comments

@symmetrisch
Copy link

Facing issues when authenticating to Windows Server 2022 (password/ticket valid)

certipy find -scheme ldaps -enabled -dc-only -dc-ip <redacted> -ns <redacted> -target <redacted> -dns-tcp -k -u <redacted> -debug

Certipy v4.8.0 - by Oliver Lyak (ly4k)
...
[+] Getting TGS for 'host/<redacted>'
[+] Got TGS for 'host/<redacted>'
[-] Got error: [{'result': 49, 'description': 'invalidCredentials', 'dn': '', 'message': '80090346: LdapErr: DSID-0C09070F, comment: AcceptSecurityContext error, data 80090346, v4f7c\x00', 'referrals': None, 'saslCreds': None, 'type': 'bindResponse'}]
...


certipy find -enabled -dc-only -dc-ip <redacted> -ns <redacted> -target <redacted> -dns-tcp -u <redacted> -debug

...
[+] Authenticating to LDAP server
[-] Got error: Failed to authenticate to LDAP. Invalid credentials
@ThePirateWhoSmellsOfSunflowers

Hi!
invalidCredentials [...] comment: AcceptSecurityContext error, data 80090346 means that Channel Binding is enabled on LDAPS. The second error message means that LDAP Signing is also enabled.

It's really strange because AFAIK, you can use ldap3 library with kerberos and ldaps even if Channel Bindind is enabled.

🌻

@b1gy7
Copy link

b1gy7 commented Sep 18, 2023

Password:
[+] Authenticating to LDAP server
[-] Got error: Failed to authenticate to LDAP. Invalid credentials
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/certipy/entry.py", line 60, in main
    actions[options.action](options)
  File "/usr/lib/python3/dist-packages/certipy/commands/parsers/find.py", line 12, in entry
    find.entry(options)
  File "/usr/lib/python3/dist-packages/certipy/commands/find.py", line 1185, in entry
    find.find()
  File "/usr/lib/python3/dist-packages/certipy/commands/find.py", line 165, in find
    connection = self.connection
                 ^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/certipy/commands/find.py", line 124, in connection
    self._connection.connect()
  File "/usr/lib/python3/dist-packages/certipy/lib/ldap.py", line 77, in connect
    self.connect(version=ssl.PROTOCOL_TLSv1_2)
  File "/usr/lib/python3/dist-packages/certipy/lib/ldap.py", line 144, in connect
    raise Exception(
Exception: Failed to authenticate to LDAP. Invalid credentials

I have a similar issue. And i tried every possible authentication method and it still fails. I'm kinda stuck on why it doesn't work. The credentials are 100% correct and a simple ldapsearch works like it should.

A simple LDAP bind connection delivers the following output :

{'result': 49, 'description': 'invalidCredentials', 'dn': '', 'message': '80090346: LdapErr: DSID-0C090736, comment: AcceptSecurityContext error, data 80090346, v3839\x00', 'referrals': None, 'saslCreds': None, 'type': 'bindResponse'}

@ly4k
Copy link
Owner

ly4k commented Sep 18, 2023

Thanks for reporting. I am looking into it.

@b1gy7
Copy link

b1gy7 commented Sep 18, 2023

Something interesting to add here is that i can connect and authenticate via the MS-LDP tool. And that both LDAP Signing and Channel Binding are active in our Network . The MS-LDP Tool delivers the following output :

0x0 = ldap_unbind(ld);
ld = ldap_open("<redacted>", 389);
Established connection to <redacted>.
Retrieving base DSA information...
Getting 1 entries:
Dn: (RootDSE)
configurationNamingContext: CN=<redacted>,DC=<redacted>,DC=<redacted>; 
currentTime: 18.09.2023 17:33:49 ; 
defaultNamingContext: DC=<redacted>,DC=<redacted>; 
dnsHostName: <redacted>; 
domainControllerFunctionality: 7 = ( WIN2016 ); 
domainFunctionality: 7 = ( WIN2016 ); 
dsServiceName: <redacted>; 
forestFunctionality: 7 = ( WIN2016 ); 
highestCommittedUSN: 218723935; 
isGlobalCatalogReady: TRUE; 
isSynchronized: TRUE; 
ldapServiceName: <redacted>; 
namingContexts (3): <redacted>; 
rootDomainNamingContext: <redacted>; 
schemaNamingContext: <redacted>; 
serverName: <redacted>; 
subschemaSubentry: CN=Aggregate,CN=Schema,CN=Configuration,<redacted>; 
supportedCapabilities (6): 1.2.840.113556.1.4.800 = ( ACTIVE_DIRECTORY ); 1.2.840.113556.1.4.1670 = ( ACTIVE_DIRECTORY_V51 ); 1.2.840.113556.1.4.1791 = ( ACTIVE_DIRECTORY_LDAP_INTEG ); 1.2.840.113556.1.4.1935 = ( ACTIVE_DIRECTORY_V61 ); 1.2.840.113556.1.4.2080 = ( ACTIVE_DIRECTORY_V61_R2 ); 1.2.840.113556.1.4.2237 = ( ACTIVE_DIRECTORY_W8 ); 
supportedControl (38): 1.2.840.113556.1.4.319 = ( PAGED_RESULT ); 1.2.840.113556.1.4.801 = ( SD_FLAGS ); 1.2.840.113556.1.4.473 = ( SORT ); 1.2.840.113556.1.4.528 = ( NOTIFICATION ); 1.2.840.113556.1.4.417 = ( SHOW_DELETED ); 1.2.840.113556.1.4.619 = ( LAZY_COMMIT ); 1.2.840.113556.1.4.841 = ( DIRSYNC ); 1.2.840.113556.1.4.529 = ( EXTENDED_DN ); 1.2.840.113556.1.4.805 = ( TREE_DELETE ); 1.2.840.113556.1.4.521 = ( CROSSDOM_MOVE_TARGET ); 1.2.840.113556.1.4.970 = ( GET_STATS ); 1.2.840.113556.1.4.1338 = ( VERIFY_NAME ); 1.2.840.113556.1.4.474 = ( RESP_SORT ); 1.2.840.113556.1.4.1339 = ( DOMAIN_SCOPE ); 1.2.840.113556.1.4.1340 = ( SEARCH_OPTIONS ); 1.2.840.113556.1.4.1413 = ( PERMISSIVE_MODIFY ); 2.16.840.1.113730.3.4.9 = ( VLVREQUEST ); 2.16.840.1.113730.3.4.10 = ( VLVRESPONSE ); 1.2.840.113556.1.4.1504 = ( ASQ ); 1.2.840.113556.1.4.1852 = ( QUOTA_CONTROL ); 1.2.840.113556.1.4.802 = ( RANGE_OPTION ); 1.2.840.113556.1.4.1907 = ( SHUTDOWN_NOTIFY ); 1.2.840.113556.1.4.1948 = ( RANGE_RETRIEVAL_NOERR ); 1.2.840.113556.1.4.1974 = ( FORCE_UPDATE ); 1.2.840.113556.1.4.1341 = ( RODC_DCPROMO ); 1.2.840.113556.1.4.2026 = ( DN_INPUT ); 1.2.840.113556.1.4.2064 = ( SHOW_RECYCLED ); 1.2.840.113556.1.4.2065 = ( SHOW_DEACTIVATED_LINK ); 1.2.840.113556.1.4.2066 = ( POLICY_HINTS_DEPRECATED ); 1.2.840.113556.1.4.2090 = ( DIRSYNC_EX ); 1.2.840.113556.1.4.2205 = ( UPDATE_STATS ); 1.2.840.113556.1.4.2204 = ( TREE_DELETE_EX ); 1.2.840.113556.1.4.2206 = ( SEARCH_HINTS ); 1.2.840.113556.1.4.2211 = ( EXPECTED_ENTRY_COUNT ); 1.2.840.113556.1.4.2239 = ( POLICY_HINTS ); 1.2.840.113556.1.4.2255 = ( SET_OWNER ); 1.2.840.113556.1.4.2256 = ( BYPASS_QUOTA ); 1.2.840.113556.1.4.2309 = ( LINK_TTL ); 
supportedLDAPPolicies (20): MaxPoolThreads; MaxPercentDirSyncRequests; MaxDatagramRecv; MaxReceiveBuffer; InitRecvTimeout; MaxConnections; MaxConnIdleTime; MaxPageSize; MaxBatchReturnMessages; MaxQueryDuration; MaxDirSyncDuration; MaxTempTableSize; MaxResultSetSize; MinResultSets; MaxResultSetsPerConn; MaxNotificationPerConn; MaxValRange; MaxValRangeTransitive; ThreadMemoryLimit; SystemMemoryLimitPercent; 
supportedLDAPVersion (2): 3; 2; 
supportedSASLMechanisms (4): GSSAPI; GSS-SPNEGO; EXTERNAL; DIGEST-MD5; 

@ly4k Thank you very much for your time and for looking into it . I've been looking into this issue for some days now and i would heavily appreciate to learn the base and solution of this problem. This issue stops the tool from working at all since we can't connect/authenticate to our DC.

@ThePirateWhoSmellsOfSunflowers

Unfortunately ldap3 library does not support LDAP Signing/Channel binding out of the box, two PR (1087 and 1042) are currently open to implement them but the project seems dead 😢 (full disclosure: I made one of them)
You can try to fallback to Simple authentication on LDAPS, which is not impacted by channel binding. I have also created a fork with those 2 PR merged.

Hope it helps.

🌻

@b1gy7
Copy link

b1gy7 commented Sep 19, 2023

@ThePirateWhoSmellsOfSunflowers By Simple Authentication you mean to send the full DN into the username String and the Password with the ldaps scheme parameter ? AFAIK simple authentication means to send the full DN and the cleartext password into a request or am I wrong ? Thank you very much for your help.

@ThePirateWhoSmellsOfSunflowers

Simple Authentication is a "non NTLM authentication" as defined in the LDAPv3 RFC but Active Directory is compatible with it. You will need to change certipy code to something like

connection = ldap3.Connection(server, authentication=ldap3.SIMPLE, user='my_user@domain.local', password='password')

instead of

connection = ldap3.Connection(server, authentication=ldap3.NTLM, user='domain.local\\my_user', password='password')

Yes the password is sent in cleartext but within a TLS channel, because you are using LDAPS.

@b1gy7
Copy link

b1gy7 commented Sep 19, 2023

Yeah this seemed to fix the invalidCredential issue , which is a step forward in the right direction . But now i have another issue with enum.py :

[-] Got error: module 'enum' has no attribute '_decompose'
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/certipy/commands/find.py", line 782, in security_to_bloodhound_aces
    standard_rights = list(rights["rights"])
                      ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/enum.py", line 1482, in __iter__
    yield from self._iter_member_(self._value_)
  File "/usr/lib/python3.11/enum.py", line 1369, in _iter_member_by_def_
    yield from sorted(
               ^^^^^^^
  File "/usr/lib/python3.11/enum.py", line 1371, in <lambda>
    key=lambda m: m._sort_order_,
                  ^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute '_sort_order_'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/certipy/entry.py", line 60, in main
    actions[options.action](options)
  File "/usr/lib/python3/dist-packages/certipy/commands/parsers/find.py", line 12, in entry
    find.entry(options)
  File "/usr/lib/python3/dist-packages/certipy/commands/find.py", line 1185, in entry
    find.find()
  File "/usr/lib/python3/dist-packages/certipy/commands/find.py", line 455, in find
    self.output_bloodhound_data(prefix, templates, cas)
  File "/usr/lib/python3/dist-packages/certipy/commands/find.py", line 578, in output_bloodhound_data
    aces = self.security_to_bloodhound_aces(security)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/certipy/commands/find.py", line 784, in security_to_bloodhound_aces
    standard_rights = rights["rights"].to_list()
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/certipy/lib/constants.py", line 265, in to_list
    members, _ = enum._decompose(cls, self._value_)
                 ^^^^^^^^^^^^^^^
AttributeError: module 'enum' has no attribute '_decompose'

I have seen some other issues that relate to my new one , I'll try to see If i can fix it like its mentioned in this issue
#159 . Thank you very much for your time and for your help @ThePirateWhoSmellsOfSunflowers @ly4k .

@symmetrisch
Copy link
Author

symmetrisch commented Sep 19, 2023

Simple Authentication is a "non NTLM authentication" as defined in the LDAPv3 RFC but Active Directory is compatible with it. You will need to change certipy code to something like

This worked in my environment with -scheme ldaps - I just adjusted ldap.py quick and dirty. Many thanks, great community!

@ThePirateWhoSmellsOfSunflowers
Copy link

Keep in mind that you cannot use NT hash with Simple authentication so it's a little bit hacky for IRL scenarios.

@ly4k
Copy link
Owner

ly4k commented Sep 19, 2023

Yeah this seemed to fix the invalidCredential issue , which is a step forward in the right direction . But now i have another issue with enum.py :

[-] Got error: module 'enum' has no attribute '_decompose'
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/certipy/commands/find.py", line 782, in security_to_bloodhound_aces
    standard_rights = list(rights["rights"])
                      ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/enum.py", line 1482, in __iter__
    yield from self._iter_member_(self._value_)
  File "/usr/lib/python3.11/enum.py", line 1369, in _iter_member_by_def_
    yield from sorted(
               ^^^^^^^
  File "/usr/lib/python3.11/enum.py", line 1371, in <lambda>
    key=lambda m: m._sort_order_,
                  ^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute '_sort_order_'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/certipy/entry.py", line 60, in main
    actions[options.action](options)
  File "/usr/lib/python3/dist-packages/certipy/commands/parsers/find.py", line 12, in entry
    find.entry(options)
  File "/usr/lib/python3/dist-packages/certipy/commands/find.py", line 1185, in entry
    find.find()
  File "/usr/lib/python3/dist-packages/certipy/commands/find.py", line 455, in find
    self.output_bloodhound_data(prefix, templates, cas)
  File "/usr/lib/python3/dist-packages/certipy/commands/find.py", line 578, in output_bloodhound_data
    aces = self.security_to_bloodhound_aces(security)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/certipy/commands/find.py", line 784, in security_to_bloodhound_aces
    standard_rights = rights["rights"].to_list()
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/certipy/lib/constants.py", line 265, in to_list
    members, _ = enum._decompose(cls, self._value_)
                 ^^^^^^^^^^^^^^^
AttributeError: module 'enum' has no attribute '_decompose'

I have seen some other issues that relate to my new one , I'll try to see If i can fix it like its mentioned in this issue #159 . Thank you very much for your time and for your help @ThePirateWhoSmellsOfSunflowers @ly4k .

@b1gy7 This issue was fixed in version 4.8.0. There was a duplicate issue, and I've only closed one of them.

@b1gy7
Copy link

b1gy7 commented Sep 19, 2023

I've noticed that and I've upgraded and now it works with the Simple Authentication change. Thank you very much @ly4k @ThePirateWhoSmellsOfSunflowers. If there is any way to financially recompensate to this repository lmk i'll gladly contribute with what I can . A great & active helping community.

@ly4k
Copy link
Owner

ly4k commented Sep 19, 2023

I have a Github sponsors profile, which isn't supposed to be public yet, as I'm planning to publish it when my next tool is released, but it is available and live here: https://github.com/sponsors/ly4k 😃

As for Certipy, I am considering making a fork of ldap3 and merging the PRs. I will test later.

@ly4k
Copy link
Owner

ly4k commented Sep 19, 2023

I made a fork of LDAP3 and merged the PR from @ThePirateWhoSmellsOfSunflowers. Thanks a lot for that!

The new Certipy version 4.8.1 now supports LDAP channel binding over LDAPS using NTLM authentication. Kerberos authentication isn't supported, and LDAP signing isn't supported as well. While I'd like to support Kerberos and LDAP signing, I do not have the time or knowledge yet to implement this in the forked LDAP3 module.

If you encounter an environment with LDAP signing, I'd recommend using LDAPS instead of LDAP, and if required, use channel binding as well with the new -ldap-channel-binding switch. To use the new channel binding feature, it is required to pip install the forked module: pip3 install git+https://github.com/ly4k/ldap3. This will uninstall the old module and install the forked module. The old module doesn't seem to have had any commits since May 2023, but I'll try to keep an eye on it.

In the meantime, we'll use this quick and dirty fix, and Certipy will spit out better error messages with relevant information (including the pip install command) if you end up in this scenario.

@ly4k ly4k closed this as completed Sep 26, 2023
@Neustradamus
Copy link

To follow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants