Subject: | SIGNTICKET creation and verification doesn't always use the right key |
The KDC code to generate and verify AD-SIGNTICKET checksums uses the
krbtgt_key parameter of handle_authdata(). For AS requests this is
the server key chosen by the KDC to encrypt the issued ticket; for
TGS requests this is the server key which was used to decrypt the
header ticket. Neither key necessarily corresponds to a krbtgt
principal.
Here are some scenarios where this won't work:
* A client makes an AS request for a server principal (not a TGT) and
authenticates to that service. The service makes an S4U2Proxy
request, presenting the client's ticket as an evidence ticket. The
checksum will have been created with the service ticket's key, but
will be verified using the krbtgt key for the service's TGT, so
verification will spuriously fail.
* A service gets a TGT when the krbtgt kvno is 1. The krbtgt key is
then rotated, so the current kvno is 2. A client gets a TGT, then
gets a ticket for the service, then authenticates to the service.
The services makes an S4U2Proxy request presenting the client's
ticket as an evidence ticket. The checksum will have been created
using krbtgt kvno 2, but will be verified using krbtgt kvno 1, so
verification will spuriously fail.
* A service prints a ticket to itself containing AD-SIGNTICKET data,
signed using the service's own key. The service makes a ticket
modification request to the KDC, presenting that ticket in the
header. The KDC will verify the checksum using the service's key,
erroneously succeeding. There is no attack here because a ticket
modification request must result in a ticket to the same service as
the header ticket server, and the KDC won't sign the AD-SIGNEDPATH in
the resulting ticket with the krbtgt key because it never loads the
krbtgt principal. But it still represents a failure of the KDC to
correctly evaluate the significance of the AD-SIGNTICKET checksum.
To behave correctly, the KDC needs to load the local TGT principal
when the AS server or TGS header ticket server principal is not the
local TGT. For verification, the KDC may need to try several
different krbtgt key versions, as there is no kvno in the authdata
element.
krbtgt_key parameter of handle_authdata(). For AS requests this is
the server key chosen by the KDC to encrypt the issued ticket; for
TGS requests this is the server key which was used to decrypt the
header ticket. Neither key necessarily corresponds to a krbtgt
principal.
Here are some scenarios where this won't work:
* A client makes an AS request for a server principal (not a TGT) and
authenticates to that service. The service makes an S4U2Proxy
request, presenting the client's ticket as an evidence ticket. The
checksum will have been created with the service ticket's key, but
will be verified using the krbtgt key for the service's TGT, so
verification will spuriously fail.
* A service gets a TGT when the krbtgt kvno is 1. The krbtgt key is
then rotated, so the current kvno is 2. A client gets a TGT, then
gets a ticket for the service, then authenticates to the service.
The services makes an S4U2Proxy request presenting the client's
ticket as an evidence ticket. The checksum will have been created
using krbtgt kvno 2, but will be verified using krbtgt kvno 1, so
verification will spuriously fail.
* A service prints a ticket to itself containing AD-SIGNTICKET data,
signed using the service's own key. The service makes a ticket
modification request to the KDC, presenting that ticket in the
header. The KDC will verify the checksum using the service's key,
erroneously succeeding. There is no attack here because a ticket
modification request must result in a ticket to the same service as
the header ticket server, and the KDC won't sign the AD-SIGNEDPATH in
the resulting ticket with the krbtgt key because it never loads the
krbtgt principal. But it still represents a failure of the KDC to
correctly evaluate the significance of the AD-SIGNTICKET checksum.
To behave correctly, the KDC needs to load the local TGT principal
when the AS server or TGS header ticket server principal is not the
local TGT. For verification, the KDC may need to try several
different krbtgt key versions, as there is no kvno in the authdata
element.