pythongssapi / python-gssapi

A Python interface to RFC 2743/2744 (plus common extensions)
ISC License
104 stars 46 forks source link

Minor (2529639053): Matching credential not found #329

Closed ThePirateWhoSmellsOfSunflowers closed 1 year ago

ThePirateWhoSmellsOfSunflowers commented 1 year ago

Hi all!

What went wrong?

I currently trying to use SASL GSSAPI authentication in ldap3 (source), this lib uses python-gssapi to handle it. CChaches contain TGS for ldap SPN. The ccache for the user themightymosdef works, the ccache for the user cersei.lannister does not. The following error is raised:

Traceback (most recent call last):
  File "/home/user/gssapi/seven_testbed.py", line 6, in <module>
    ctx.step(in_token)
  File "/home/user/gssapi/venv/lib/python3.10/site-packages/decorator.py", line 232, in fun
    return caller(func, *(extras + args), **kw)
  File "/home/user/gssapi/venv/lib/python3.10/site-packages/gssapi/_utils.py", line 165, in check_last_err
    return func(self, *args, **kwargs)
  File "/home/user/gssapi/venv/lib/python3.10/site-packages/decorator.py", line 232, in fun
    return caller(func, *(extras + args), **kw)
  File "/home/user/gssapi/venv/lib/python3.10/site-packages/gssapi/_utils.py", line 131, in catch_and_return_token
    return func(self, *args, **kwargs)
  File "/home/user/gssapi/venv/lib/python3.10/site-packages/gssapi/sec_contexts.py", line 584, in step
    return self._initiator_step(token=token)
  File "/home/user/gssapi/venv/lib/python3.10/site-packages/gssapi/sec_contexts.py", line 606, in _initiator_step
    res = rsec_contexts.init_sec_context(self._target_name, self._creds,
  File "gssapi/raw/sec_contexts.pyx", line 188, in gssapi.raw.sec_contexts.init_sec_context
gssapi.raw.misc.GSSError: Major (851968): Unspecified GSS failure.  Minor code may provide more information, Minor (2529639053): Matching credential not found (filename: /tmp/tickets/cersei.lannister.ccache)

How do we reproduce?

I use this simple code snippets to reproduce

import gssapi
creds = gssapi.Credentials(name=gssapi.Name('themightymosdef@YOLOSEC.ORG'), usage='initiate', store=dict())
target_name = gssapi.Name('ldap@yolosec.org', gssapi.NameType.hostbased_service)
in_token = None
ctx = gssapi.SecurityContext(name=target_name, mech=gssapi.MechType.kerberos, creds=creds)
ctx.step(in_token)

and

import gssapi
creds = gssapi.Credentials(name=gssapi.Name('cersei.lannister@SEVENKINGDOMS.LOCAL'), usage='initiate', store=dict())
target_name = gssapi.Name('ldap@sevenkingdoms.local', gssapi.NameType.hostbased_service)
in_token = None
ctx = gssapi.SecurityContext(name=target_name, mech=gssapi.MechType.kerberos, creds=creds)
ctx.step(in_token)

Launch them via:

KRB5CCNAME=/tmp/tickets/themightymosdef.ccache python3 yolosec_testbed.py or KRB5CCNAME=/tmp/tickets/cersei.lannister.ccache python3 sevenkingdoms_testbed.py

ccaches are attached to this issue (change txt to ccache). cersei.lannister.txt themightymosdef.txt

Component versions (python-gssapi, Kerberos, OS / distro, etc.)

I don't know if it's a ldap3 problem or a gssapi one :confused: Thanks in advance.

:sunflower:

jborean93 commented 1 year ago

While the code they have seems correct this library is mostly just a wrapper for the GSSAPI C API itself. We don't do anything with the ccache lookup, just pass through the values. At a guess it's not liking the .LOCAL part as klist -l only shows cersei.lannister@SEVENKINGDOMS in it's output for that ccache even though the principal is definition cersei.lannister@SEVENKINGDOMS.LOCAL in the ccache itself. You can add KRB5_TRACE=/dev/stdout to get some more logging from the underlying MIT krb5 library here which may help you. I would compare the results with what works and what doesn't. For example on my system the last one that fails is

[16918] 1697570604.179256: Retrieving cersei.lannister@SEVENKINGDOMS.LOCAL -> krbtgt/SEVENKINGDOMS.LOCAL@SEVENKINGDOMS.LOCAL from FILE:/home/jborean/Downloads/cersei.lannister.txt with result: -1765328243/Matching credential not found (filename: /home/jborean/Downloads/cersei.lannister.txt)

This makes sense as it's found the principal in the ccache but there is no krbtgt/SEVENKINGDOMS.LOCAL@SEVENKINGDOMS.LOCAL ticket to retrieve the ldap one for but I'm unsure whether that's just because I don't have access to the KDC it was issues from or not.

Unfortunately there's not much else I can do for you here sorry.

ThePirateWhoSmellsOfSunflowers commented 1 year ago

At a guess it's not liking the .LOCAL part as klist -l only shows cersei.lannister@SEVENKINGDOMS in it's output for that ccache even though the principal is definition cersei.lannister@SEVENKINGDOMS.LOCAL in the ccache itself.

I think it's just because to output is truncated, i've checked with a long name on the yolosec domain:

$ KRB5CCNAME=/tmp/tickets/azertyuiopqsdfghjklmwxcvbn.ccache klist -l 
Principal name                 Cache name
--------------                 ----------
azertyuiopqsdfghjklmwxcvbn@YOL FILE:/tmp/tickets/azertyuiopqsdfghjklmwxcvbn.ccache

Anyway, thanks for the KRB5_TRACE=/dev/stdout trick, exactly what I was looking for! So now, on one hand:

$ KRB5CCNAME=/tmp/tickets/cersei.lannister.ccache python3 seven_testbed.py
[14825] 1697582005.568595: Retrieving cersei.lannister@SEVENKINGDOMS.LOCAL from FILE:/etc/krb5/user/1000/client.keytab (vno 0, enctype 0) with result: 2/Key table file '/etc/krb5/user/1000/client.keytab' not found
[14825] 1697582005.568599: Retrieving cersei.lannister@SEVENKINGDOMS.LOCAL from FILE:/etc/krb5/user/1000/client.keytab (vno 0, enctype 0) with result: 2/Key table file '/etc/krb5/user/1000/client.keytab' not found
[14825] 1697582005.568607: Getting credentials cersei.lannister@SEVENKINGDOMS.LOCAL -> ldap/sevenkingdoms.local@ using ccache FILE:/tmp/tickets/cersei.lannister.ccache
[14825] 1697582005.568608: Retrieving cersei.lannister@SEVENKINGDOMS.LOCAL -> krb5_ccache_conf_data/start_realm@X-CACHECONF: from FILE:/tmp/tickets/cersei.lannister.ccache with result: -1765328243/Matching credential not found (filename: /tmp/tickets/cersei.lannister.ccache)
[14825] 1697582005.568609: Retrieving cersei.lannister@SEVENKINGDOMS.LOCAL -> ldap/sevenkingdoms.local@ from FILE:/tmp/tickets/cersei.lannister.ccache with result: -1765328243/Matching credential not found (filename: /tmp/tickets/cersei.lannister.ccache)
[14825] 1697582005.568610: Retrying cersei.lannister@SEVENKINGDOMS.LOCAL -> ldap/sevenkingdoms.local@SEVENKINGDOMS.LOCAL with result: -1765328243/Matching credential not found (filename: /tmp/tickets/cersei.lannister.ccache)
[14825] 1697582005.568611: Server has referral realm; starting with ldap/sevenkingdoms.local@SEVENKINGDOMS.LOCAL
[14825] 1697582005.568612: Retrieving cersei.lannister@SEVENKINGDOMS.LOCAL -> krbtgt/SEVENKINGDOMS.LOCAL@SEVENKINGDOMS.LOCAL from FILE:/tmp/tickets/cersei.lannister.ccache with result: -1765328243/Matching credential not found (filename: /tmp/tickets/cersei.lannister.ccache)
Traceback (most recent call last):
  File "/home/user/gssapi/seven_testbed.py", line 6, in <module>
    ctx.step(in_token)
  File "/home/user/gssapi/venv/lib/python3.10/site-packages/decorator.py", line 232, in fun
    return caller(func, *(extras + args), **kw)
  File "/home/user/gssapi/venv/lib/python3.10/site-packages/gssapi/_utils.py", line 165, in check_last_err
    return func(self, *args, **kwargs)
  File "/home/user/gssapi/venv/lib/python3.10/site-packages/decorator.py", line 232, in fun
    return caller(func, *(extras + args), **kw)
  File "/home/user/gssapi/venv/lib/python3.10/site-packages/gssapi/_utils.py", line 131, in catch_and_return_token
    return func(self, *args, **kwargs)
  File "/home/user/gssapi/venv/lib/python3.10/site-packages/gssapi/sec_contexts.py", line 584, in step
    return self._initiator_step(token=token)
  File "/home/user/gssapi/venv/lib/python3.10/site-packages/gssapi/sec_contexts.py", line 606, in _initiator_step
    res = rsec_contexts.init_sec_context(self._target_name, self._creds,
  File "gssapi/raw/sec_contexts.pyx", line 188, in gssapi.raw.sec_contexts.init_sec_context
gssapi.raw.misc.GSSError: Major (851968): Unspecified GSS failure.  Minor code may provide more information, Minor (2529639053): Matching credential not found (filename: /tmp/tickets/cersei.lannister.ccache)

on the other hand

$ KRB5CCNAME=/tmp/tickets/themightymosdef.ccache python3 yolo_testbed.py  
[14827] 1697582012.180635: Retrieving themightymosdef@YOLOSEC.ORG from FILE:/etc/krb5/user/1000/client.keytab (vno 0, enctype 0) with result: 2/Key table file '/etc/krb5/user/1000/client.keytab' not found
[14827] 1697582012.180639: Retrieving themightymosdef@YOLOSEC.ORG from FILE:/etc/krb5/user/1000/client.keytab (vno 0, enctype 0) with result: 2/Key table file '/etc/krb5/user/1000/client.keytab' not found
[14827] 1697582012.180647: Getting credentials themightymosdef@YOLOSEC.ORG -> ldap/dc02.yolosec.org@ using ccache FILE:/tmp/tickets/themightymosdef.ccache
[14827] 1697582012.180648: Retrieving themightymosdef@YOLOSEC.ORG -> krb5_ccache_conf_data/start_realm@X-CACHECONF: from FILE:/tmp/tickets/themightymosdef.ccache with result: -1765328243/Matching credential not found (filename: /tmp/tickets/themightymosdef.ccache)
[14827] 1697582012.180649: Retrieving themightymosdef@YOLOSEC.ORG -> ldap/dc02.yolosec.org@ from FILE:/tmp/tickets/themightymosdef.ccache with result: -1765328243/Matching credential not found (filename: /tmp/tickets/themightymosdef.ccache)
[14827] 1697582012.180650: Retrying themightymosdef@YOLOSEC.ORG -> ldap/dc02.yolosec.org@YOLOSEC.ORG with result: 0/Success
[14827] 1697582012.180652: Creating authenticator for themightymosdef@YOLOSEC.ORG -> ldap/dc02.yolosec.org@YOLOSEC.ORG, seqnum 973893885, subkey rc4-hmac/2AD9, session key rc4-hmac/099E

Somehow, on the second example, gssapi is looking for the right SPN bur not in the first one (it misses kingslanding part). Strange because the ccache contains the right SPN:

$ describeTicket.py cersei.lannister.ccache                                                                                                                                      
Impacket v0.12.0.dev1+20231015.203043.419e6f24 - Copyright 2023 Fortra                                                                                                                                             

[*] Number of credentials in cache: 1                                                                                                                                                                              
[*] Parsing credential[0]:                                                                                                                                                                                         
[*] Ticket Session Key            : c55c85dbc3fccf0aa1043b5621364f91                                                                                                                                               
[*] User Name                     : cersei.lannister                                                                                                                                                               
[*] User Realm                    : SEVENKINGDOMS.LOCAL                                                                                                                                                            
[*] Service Name                  : ldap/kingslanding.sevenkingdoms.local                                                                                                                                          
[*] Service Realm                 : SEVENKINGDOMS.LOCAL                                                                                                                                                            
[*] Start Time                    : 17/10/2023 22:33:05 PM
[*] End Time                      : 18/10/2023 08:33:04 AM                                                                                                                                                         
[*] RenewTill                     : 18/10/2023 22:33:04 PM
[*] Flags                         : (0x40a50000) forwardable, renewable, pre_authent, ok_as_delegate, enc_pa_rep
[*] KeyType                       : rc4_hmac
[*] Base64(key)                   : xVyF28P8zwqhBDtWITZPkQ==
[*] Kerberoast hash               :  [...]
[*] Decoding unencrypted data in credential[0]['ticket']:
[*]   Service Name                : ldap/kingslanding.sevenkingdoms.local
[*]   Service Realm               : SEVENKINGDOMS.LOCAL
[*]   Encryption type             : aes256_cts_hmac_sha1_96 (etype 18)
$ describeTicket.py themightymosdef.ccache  
Impacket v0.12.0.dev1+20231015.203043.419e6f24 - Copyright 2023 Fortra

[*] Number of credentials in cache: 1
[*] Parsing credential[0]:
[*] Ticket Session Key            : 24792593c8d5b6f1742bedc45879f974
[*] User Name                     : themightymosdef
[*] User Realm                    : YOLOSEC.ORG
[*] Service Name                  : ldap/dc02.yolosec.org
[*] Service Realm                 : YOLOSEC.ORG
[*] Start Time                    : 17/10/2023 22:32:53 PM
[*] End Time                      : 18/10/2023 08:32:53 AM
[*] RenewTill                     : 18/10/2023 22:32:53 PM
[*] Flags                         : (0x40a50000) forwardable, renewable, pre_authent, ok_as_delegate, enc_pa_rep
[*] KeyType                       : rc4_hmac
[*] Base64(key)                   : JHklk8jVtvF0K+3EWHn5dA==
[*] Kerberoast hash               :  [...]
[*] Decoding unencrypted data in credential[0]['ticket']:
[*]   Service Name                : ldap/dc02.yolosec.org
[*]   Service Realm               : YOLOSEC.ORG
[*]   Encryption type             : aes256_cts_hmac_sha1_96 (etype 18)

:sunflower:

jborean93 commented 1 year ago

Somehow, on the second example, gssapi is looking for the right SPN bur not in the first one (it misses kingslanding part). Strange because the ccache contains the right SPN:

I'm fairly certain this value is just from the SPN you requested. In your code you are doing

target_name = gssapi.Name('ldap@sevenkingdoms.local', gssapi.NameType.hostbased_service)

So it's going to try and lookup the credentials for that principal. Try using ldap/kingslanding.sevenkingdoms.local instead here.

ThePirateWhoSmellsOfSunflowers commented 1 year ago

So it's going to try and lookup the credentials for that principal. Try using ldap/kingslanding.sevenkingdoms.local instead here.

Same error message. Moreover, it works with

target_name = gssapi.Name('ldap@yolosec.org', gssapi.NameType.hostbased_service)

so it should be working with ldap@sevenkingdoms.local :confused:

However, it seems the problem is related to DNS configuration, my VM has 2 network interfaces, with 2 DNS server. Need to test with a clean VM.

Thanks for your help.

ThePirateWhoSmellsOfSunflowers commented 1 year ago

Confirmed! It was a DNS problem, ldap3 works as expected on a fresh VM.

:sunflower: