[kitten] Checking the transited list of a kerberos ticket in a transitive cross-realm trust situation...

Stefan Metzmacher metze at samba.org
Wed Aug 23 19:01:44 EDT 2017

Am 22.08.2017 um 17:02 schrieb Greg Hudson:
> On 08/22/2017 07:22 AM, Stefan Metzmacher wrote:
>>> I'm not sure about "any KDC in the trust chain trusts the next hop."
>>> RFC 4120 doesn't think about cross-realm relationships in terms of
>>> trust.  Simply having cross-realm keys with another realm doesn't
>>> necessarily imply that the other realm is trustworthy.
>> At least it allows the other realm to issue cross-realm referral
>> tickets, which the local realm will most likely convert into service
>> tickets which can be used by a principal of the other realm to
>> access services in the local realm.
> To authenticate, yes; whether that provides any access depends on the
> services in the local realm.
>> And the client principal names (including client realm) in the
>> cross-realm ticket can contain any value, which is fully controlled
>> by the other realms KDCs.
> Yes, which makes it the local realm's job (either at the KDC or the
> application server) to decide whether the other realm's KDC should be
> able to claim that client realm name.  Completely trusting the foreign
> realm is one option, but that option mostly restricts cross-realm
> relationships to foreign realms of equal or greater privilege.  (I say
> "mostly" because a KDC can trivially deny a ticket from the foreign
> realm which purport to authenticate a client in the local realm.  So one
> might be willing to trust a foreign realm to authenticate clients in all
> non-local realms if one doesn't grant much privilege to any non-local
> user anyway.)
>> Would be acceptable then if I implement
>> gss_set_cred_option(GSS_KRB5_CRED_NO_TRANSIT_CHECK_X) for
>> MIT and Heimdal in order to let an application service to skip the check
>> if they know what they're doing by checking trusting there KDC and doing
>> the PAC verification.
> I think we should first consider whether it would be sufficient for MIT
> krb5 to suppress the rd_req transited check if the
> TRANSITED-POLICY-CHECKED flag is set in the ticket.  MIT and Heimdal
> KDCs both appear to perform the transited check and set the flag by default.

But Windows KDCs doesn't set this bit (I guess because it's just not

> An application server always trusts its local KDC, but that trust isn't
> useful for cross-realm relationships if the TRANSITED-POLICY-CHECKED
> flag isn't in the ticket.  Clients can, in general, suppress the KDC
> transited check with the DISABLE-TRANSITED-CHECK flag; therefore, a
> ticket issued by the local KDC without the TRANSITED-POLICY-CHECKED flag
> asserts nothing about the acceptability of the KDC path.
> I am not sufficiently familiar with PACs to know whether PAC
> verification is a fitting alternative to a transited policy check.

I've attached network caputures with a keytab that allows wireshark
to decrypt the messages.

We have the computer
FD23-73$@W4EDOM-L4.BASE (fd3a:aaa3:ee87:ff09:200:ff:fe09:73)
that tries to do S4U2Self for
administrator at S2-W2012-L4.S1-W2012-L4.W2012R2-L4.BASE.

W4EDOM-L4.BASE (fd3a:aaa3:ee87:ff09:200:ff:fe09:133)
is it's own forest. It trusts the forest W2012R2-L4.BASE
(fd3a:aaa3:ee87:ff09:200:ff:fe09:183) which has subdomains
S1-W2012-L4.W2012R2-L4.BASE (fd3a:aaa3:ee87:ff09:200:ff:fe09:181)
and S2-W2012-L4.S1-W2012-L4.W2012R2-L4.BASE

The interesting parts are the ticket returned in frames 218
it is a normal cross-realm ticket with transited = W2012R2-L4.BASE.
Frame 242, 285 and 352 are the S4U2Self (reverse) referrals
with more values in the transited field. Note the cname
is still fd23-73$@W4EDOM-L4.BASE, but the PAC within the
authorization-data already belongs to
administrator at S2-W2012-L4.S1-W2012-L4.W2012R2-L4.BASE (e.g. see the
Client Info Type).
The final S4U2Self ticket in frame 377 has also 3 domains
(with a different encoding compared to 285).
In the final ticket the Client Info Name need to match exactly
the cname of the ticket and the Client Info time the authtime
of the ticket, that's verified by krb5_pac_verify().

The 2nd example uses a forest trust from W4EDOM-L4.BASE to
BLA.BASE (fd3a:aaa3:ee87:ff09:200:ff:fe09:219) which has a 2nd tree
root domain in the same forest called BLA2.BASE
We try S4U2Self for administrator at BLA2.BASE here.

There we have transited = BLA.BASE in frame 231, which is the
first S4U2Self (reverse) referral. The final ticket in frame 323
has BLA.BASE and BLA2.BASE in the transited field, which causes
the transited verification to fail unless I manually configure
a [capaths] section.

Each KDC applies some SID-Filtering to the group memberships
of the Logon Info field in the PAC. Which prevents impersonation
of local principals via cross-realm tickets. The PAC contains to
signatures one using the long term key that belongs to
the sname at realm of the ticket (either the cross-realm key or the key of
the final service). This service signature is checksummed by local
krbtgt long term key. So that the service itself can't fool the KDC
and generate it's own PAC.

See [MS-PAC] 4.1.2 Authorization Validation and Filtering
to get more details.

Windows and also Samba basically use the Logon Info part of the
PAC to form the authorization token for the client.
Which means the verification of the PAC service signature is enough
in order to trust our KDC, which already applied the required
SID-Filtering for us.

I hope I was able to bring some light into this complex topic.

In order to work without manual configuration, we need a way
to disable the transited check when we're the service.

If you have wireshark with kerberos decryption support you can use:
wireshark -K all-domains.keytab
wireshark -K all-domains.keytab

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
Url : http://mailman.mit.edu/pipermail/krbdev/attachments/20170823/f7e60671/attachment.bin

More information about the krbdev mailing list