The new [hdb] new_service_key_delay parameter should not apply to
principal entries when used as clients. Otherwise new passwords would
not take effect immediately, and that would be very confusing.
Now we'll put the "reason=..." last in the log lines and we won't escape
spaces -- just newlines and other control characters. This makes
reading log lines much easier without complicating parsing of log lines
because interior key=value pairs do get whitespace escaped or removed.
We take all of the kdc_log() and _kdc_r_log() calls in AS and TGS
and move their log levels down to debugging on the assumption that
our new log line subsumes the "informational" requirements. We
collect some additional information in the kv-pair "pe-text" which
is like e-text except it is not returned to the client.
We refactor the code a bit to extend kdc_request_t which until now
was only used for the AS. We make the structure extensible and
start using it for the TGS as well. We leave digest and kx509
alone for the time being.
We also define the concept of kv-pairs in our audit trail which
allows us to define a rigorous but extensible format:
type error from-addr client server key1=val1 key2=val2 ...
We define the meaning of the various log levels in the man page
for krb5_openlog(3). If logging configured and levels are not
specified, we change the default levels to 0-3 which should exclude
debugging messages which are generally only desired in exceptional
circumstances.
We also go through the KDC and adjust the levels to be appropriate.
Drafts 0 through 10 of the Kerberos anonymity internet draft,
https://tools.ietf.org/html/draft-ietf-krb-wg-anon, specified the
TicketFlags.anonymous flag as bit 14 and the KDCOptions.anonymous
flag as bit 14. These were changed to bit 16 by MIT after it was
discovered that Microsoft used KDCOptions bit 14 for S4U2Proxy
cname-in-addl-tkt.
(Feb 2007) Heimdal added constrained delegation support prior to
1.0 but named the KDCOptions flag constrained_delegation instead of
cname-in-addl-tkt as per MS-SFU. It also assigned bit 16 instead
of bit 14. Perhaps this was done in the hope that the conflict
with Microsoft would be resolved in favor of the IETF internet
draft instead of the proprietary protocol extension.
adf9121822 ("Add PA-ClientCanonicalized
and friends.") introduced the KDCOptions.constrained_delegation flag
as bit 16.
(June 2007) In order to make Heimdal's constrained delegation work
with Microsoft's implementation Heimdal began to set both KDCOptions
bits 14 and 16 when requesting constrained delegation.
d5bb7a7c56 ("(krb5_get_creds): if
KRB5_GC_CONSTRAINED_DELEGATION is set, set both") set both the
anonymous and constrained_delegation TicketFlags when issuing a
S4U2Proxy request.
(June 2010) MIT reassigned the KDCOption.anonymous and
TicketFlags.anonymous flags to bit 16. draft-ietf-krb-anon-11
was published with this change.
(July 2014) After the release of Heimdal 1.5.0 and prior to 1.5.1
it was noticed that Heimdal's anonymous TGT support did not
interoperate with MIT.
86554f5a7f ("Use correct value for
anonymous flags") swapped the bit assignments for request_anonymous
and constrained_delegation but failed to remove the setting of
KDCOptions bit 16 ("anonymous") when requesting constrained
delegation.
(May 2019) Prior to the 7.6 release many corrections to Heimdal's
anonymity support were introduced to bring it into compliance
with RFC8062. This included support for requesting anonymous
tickets via the TGS service. Because not all KDC can satisfy
anonymous requests the client must verify if the response was
anonymized. This check wasn't added until after 7.6 was
released.
014e318d6b ("krb5: check KDC
supports anonymous if requested").
The combination of setting KDCOption.anonymous when requesting
constrained delegation and the anonymized ticket validation
broke S4U2Proxy requests to Windows KDCs. Windows KDCs ignore
the KDCOption.anonymous flag when processing a TGS request
with KDCOption.cname-in-addl-tkt set.
ea7615ade3 ("Do not set
anonymous flag in S4U2Proxy request") removed the behavior
of setting the KDCOption.anonymous flag that should have
been removed in July 2014.
(June 2019) The Heimdal KDC includes fallback logic to handle
Heimdal clients from 1.0 to 1.5.0, inclusive, that set the
KDCOptions.anonymous flag as bit 14. Prior to the 7.7 release
this logic only handled AS request but failed to handle the
constrained delegation request case where both bits 14 and 16
were set in the TGS request.
cdd0b70d37 ("kdc: don't misidentify
constrained delegation requests as anonymous") added the TGS
request validation to distinguish anonymous requests from
constrained delegation requests.
This change documents the history in the commit message and
updates some in-tree comments.
Change-Id: I625cd012e2e6c263c71948c6021cc2fad4d2e53a
Earlier (pre-7.6) Heimdal clients would send both the request-anonymous and
cname-in-addl-tkt flags for constrained delegation requests. A true anonymous
TGS request will only have the former flag set. Do not treat TGS requests with
both flags set as anonymous requests.
_kdc_is_anon_request() is only used by the AS, so make it static.
Centralize anonymous poilcy checks shared between AS and TGS into a shared
function, _kdc_check_anon_policy().
When issuing an anonymous ticket, set the ticket flag early and test that
rather than re-testing the request.
When generating KRB5SignedPath in the AS, use the reply client name rather than
the one from the request, so validation will work correctly in the TGS.
even if tgt used an enctype with a different checksum.
Per [MS-SFU] 2.2.1 PA-FOR-USER the checksum is always
HMAC_MD5, and that's what Windows and MIT clients send.
In heimdal both the client and kdc use instead the
checksum of the tgt, and therefore work with each other
but windows and MIT clients fail against heimdal KDC.
Both Windows and MIT KDC would allow any keyed checksum
to be used so Heimdal client work fine against it.
Change Heimdal KDC to allow HMAC_MD5 even for non RC4
based tgt in order to support per-spec clients.
Signed-off-by: Isaac Boukris <iboukris@gmail.com>
S4U2Self is an extension to Kerberos used in Active Directory to allow
a service to request a kerberos ticket to itself from the Kerberos Key
Distribution Center (KDC) for a non-Kerberos authenticated user
(principal in Kerboros parlance). This is useful to allow internal
code paths to be standardized around Kerberos.
S4U2Proxy (constrained-delegation) is an extension of this mechanism
allowing this impersonation to a second service over the network. It
allows a privileged server that obtained a S4U2Self ticket to itself
to then assert the identity of that principal to a second service and
present itself as that principal to get services from the second
service.
There is a flaw in Samba's AD DC in the Heimdal KDC. When the Heimdal
KDC checks the checksum that is placed on the S4U2Self packet by the
server to protect the requested principal against modification, it
does not confirm that the checksum algorithm that protects the user
name (principal) in the request is keyed. This allows a
man-in-the-middle attacker who can intercept the request to the KDC to
modify the packet by replacing the user name (principal) in the
request with any desired user name (principal) that exists in the KDC
and replace the checksum protecting that name with a CRC32 checksum
(which requires no prior knowledge to compute).
This would allow a S4U2Self ticket requested on behalf of user name
(principal) user@EXAMPLE.COM to any service to be changed to a
S4U2Self ticket with a user name (principal) of
Administrator@EXAMPLE.COM. This ticket would then contain the PAC of
the modified user name (principal).
==================
CVSSv3 calculation
==================
CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H (7.5)
=========================
Workaround and Mitigation
=========================
If server does not take privileged actions based on Kerberos tickets
obtained by S4U2Self nor obtains Kerberos tickets via further
S4U2Proxy requests then this issue cannot be exploited.
Note that the path to an exploit is not generic, the KDC is not harmed
by the malicious checksum, it is the client service requesting the
ticket being mislead, because it trusted the KDC to return the correct
ticket and PAC.
It is out of scope for Samba to describe all of the possible tool
chains that might be vulnerable. Here are two examples of possible
exploits in order to explain the issue more clearly.
1). SFU2Self might be used by a web service authenticating an end user
via OAuth, Shibboleth, or other protocols to obtain a S4U2Self
Kerberos service ticket for use by any Kerberos service principal the
web service has a keytab for. One example is acquiring an AFS token
by requesting an afs/cell@REALM service ticket for a client via
SFU2Self. With this exploit an organization that deploys a KDC built
from Heimdal (be it Heimdal directly or vendor versions such as found
in Samba) is vulnerable to privilege escalation attacks.
2). If a server authenticates users using X509 certificates, and then
uses S4U2Self to obtain a Kerberos service ticket on behalf of the
user (principal) in order to authorize access to local resources, a
man-in-the-middle attacker could allow a non-privilaged user to access
privilaged resources being protected by the server, or privilaged
resources being protected by a second server, if the first server uses
the S4U2Proxy extension in order to get a new Kerberos service ticket
to obtain access to the second server.
In both these scenarios under conditions allowing man-in-the-middle
active network protocol manipulation, a malicious user could
authenticate using the non-Kerborized credentials of an unprivileged
user, and then elevate its privileges by intercepting the packet from
the server to the KDC and changing the requested user name (principal).
The only Samba clients that use S4U2Self are:
- the "net ads kerberos pac dump" (debugging) tool.
- the CIFS proxy in the deprecated/developer-only NTVFS file
server. Note this code is not compiled or enabled by default.
In particular, winbindd does *not* use S4U2Self.
Finally, MIT Kerberos and so therefore the experimental MIT KDC backend
for Samba AD is understood not to be impacted.
===============
Further Reading
===============
There is more detail on and a description of the protocols in
[MS-SFU]: Kerberos Protocol Extensions: Service for User and Constrained
Delegation Protocol
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/
=======
Credits
=======
Originally reported by Isaac Boukris and Andrew Bartlett of the Samba
Team and Catalyst.
Patches provided by Isaac Boukris.
Advisory written by Andrew Bartlett of the Samba Team and Catalyst,
with contributions from Isaac Boukris, Jeffrey Altman and Jeremy
Allison.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13685
Change-Id: I4ac69ebf0503eb999a7d497a2c30fe4d293a8cc8
Signed-off-by: Isaac Boukris <iboukris@gmail.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Jeffrey Altman <jaltman@auristor.com>
Signed-off-by: Jeffrey Altman <jaltman@auristor.com>
Allow non-anonymous tickets to be used to obtain an anonymous service ticket,
by setting the anonymous KDC option. Do not include Win2K PAC in anonymous
service tickets. Validate anonymous flags per RFC 8062.
If the salt for the AS-REP client key matches the default password salt for the
client principal in the AS-REQ, then it can be omitted from the PA-ETYPE-INFO,
PA-ETYPE-INFO2 (RFC4120) as the client will assume the default salt in its
absence.
e11abf41 added support in libhdb for always dereferencing principal aliases
during an AS-REQ (where dereferencing refers to enabling alias lookups, and
rewriting the returned entry with the alias name unless canonicalization was
enabled).
Due to the KDC setting HDB_F_FOR_AS_REQ for all lookups from the AS, this
allowed aliases on the TGS itself to be dereferenced during an AS-REQ; however,
on presenting the TGT, the TGS would fail to resolve. Creating an explicit TGS
principal for the aliased realm would work (at least prior to c555ed6a), but
this could be confusing to deploy.
This commit changes enables alias dereferencing when HDB_F_GET_ANY is set,
which essentially means dereference whenever the request is coming from the KDC
(as opposed to, say, kadmin).
We also backout c555ed6a, which changed the TGS to always canonicalize the
server realm, as this breaks serving multiple realms from a single KDC, where
server principals in different realms share a single canonical entry.
HDB_F_CANON is now passed to the backend as a hint only, and per RFC 6806 the
principal name is never changed in TGS replies. (However, for Samba interop,
backends can override this by setting the force-canonicalize HDB flag.)
This is used by Samba to set the canonical realm in
case netbios realm was requested (same as Windows).
Regression introduced by upstream commit:
378f34b4be
Signed-off-by: Isaac Boukris <iboukris@gmail.com>
The ASN.1 functions copy_Realm(), copy_PrincipalName() and
copy_EncryptionKey() can fail. Check the return and perform error
handling as appropriate.
Change-Id: I2b3629d19db96eb41d1cd554cef1dca99745e753
Commit f469fc6 (2010-10-02) inadvertently caused the previous hop realm
to not be added to the transit path of issued tickets. This may, in
some cases, enable bypass of capath policy in Heimdal versions 1.5
through 7.2.
Note, this may break sites that rely on the bug. With the bug some
incomplete [capaths] worked, that should not have. These may now break
authentication in some cross-realm configurations.
When processing a request, current tgs_make_reply uses the requested
set of addrs of the request to establish the set of addresses to
associate with the ticket in reply.
However, when the request input set of addrs is NULL, it reverts to
using the TGT set of addresses instead. As a result, it is not
possible to acquire an addressless TGS (or forwarded TGT) using a
TGT that is addressed.
This patch remove the fallback ensuring that a TGS_REQ with a set
of addrs set to NULL enables to acquire an addressless ticket.
A KVNO is unsigned and this is reflected in the internal
interfaces. However, for compatibility reasons its encoding
is signed and this creates a pointer mismatch when passing a
kvno pointer to _kdc_db_fetch.
Signed-off-by: Uri Simchoni <uri@samba.org>
A backend can return this if asked with HDB_F_GET_CLIENT|HDB_F_FOR_AS_REQ
for a KRB5_NT_ENTERPRISE_PRINCIPAL record or for HDB_F_GET_SERVER | HDB_F_FOR_TGS_REQ.
entry_ex->entry.principal->realm needs to return the real realm of the principal
(or at least a the realm of the next cross-realm trust hop).
This is needed to route enterprise principals between AD domain trusts.
Signed-off-by: Stefan Metzmacher <metze@samba.org>
The checking of the KDC signature is more complex than it looks, it may be of a different
enc type to that which the ticket is encrypted with, and may even be prefixed
with the RODC number.
This is better handled in the plugin which can easily look up the DB for the
correct key to verify this with, and can also quickly determine if this is
an interdomain trust, which we cannot verify the PAC for.
Andrew Bartlett
This fixes a segfault if the _kdc_db_fetch function does not find
the entry in the database (the entry pointer will be NULL if entry
is not found).
Signed-off-by: Samuel Cabrero <scabrero@zentyal.com>
Signed-off-by: Love Hörnquist Åstrand <lha@h5l.org>
This handles referrals for SPNs of the form
E3514235-4B06-11D1-AB04-00C04FC2DCD2/NTDSGUID/REALM, which are
used during DRS replication when we don't know the dnsHostName of the
target DC (which we don't know until the first replication from that
DC completes).
We use the 3rd part of the SPN directly as the realm name in the
referral.
Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>
The TGS was incorrectly using authtime to compute renew_till for new
tickets, which was in turn leading to endtime potentially being equal to
starttime, which caused the TGS to return KRB5KDC_ERR_NEVER_VALID.
This happens when the TGT renewal lifetime is longer than the max renew
lifetime of any other services, after that much time (target services'
max renew life) passes. The TGT is still good but TGS-REQs fail.
The default heimdal KDC chokes when trying to encrypt a ticket with a weak
server key that has a different type than the session key. The problem
happens in the krb5_crypto_init function called from the _kdc_encode_reply
function.
The existing work-around of the problem temporarily enabled the weak
enctype in case it was disabled but the principal was on the (hard-coded)
exception list.
Unfortunately the code used the keytype of the key encoded in the ticked
(the session key) instead of the keytype of the key used to encrypt the ticket
(the serverkey) thus enabling the incorrect encryption type if those two
are different, for instance des-cbc-md5 and des-cbc-crc.
Change-Id: Ia55dc344e3e5fc9ec1eb93c9e8ebb0a58c673d57
Different ticket session key enctype selection options should
distinguish between target principal type (krbtgt vs. not), not
between KDC request types.
We can't test the key rollover support in the TGS in the x-realm
path using just Heimdal because the krb5_get_creds() path will try a
referral, which will produce a cross-realm TGT that has the
enc_part.kvno set. But we can test this for the plain TGT case.
AD issues x-realm TGTs with kvno 0. On key x-realm trust key change
we need to be able to try current and previous keys for trust, else
we will have some failures.
We were using the enctype from the PA-TGS-REQ's AP-REQ's Ticket to
decide what key from the service's realm's krbtgt principal to use.
This breaks when: a) we're doing cross-realm, b) the service's
realm's krbtgt principal doesn't have keys for the enctype used in
the cross-realm TGT.
The fix is to pick the correct key (strongest or first, per-config)
from the service's realm's krbtgt principal.