In Kerberos, which exchange does Pass-the-Ticket use, and what does the service check before accepting the stolen service ticket?
answer
- no KDC round trip at all
- possession, not identity
- the ticket alone is not enough
- AP-REQ plus a fresh Authenticator
- ctime inside the skew window
basics
~20 sPass-the-Ticket runs the AP exchange only: an AP-REQ carrying the stolen service ticket plus a fresh Authenticator sealed under that ticket's session key. The service checks decryption, names and timestamp, never who copied the ticket.
solid answer
~40 sThe attack rides entirely on the AP exchange, with **no KDC round trip at all**. A service ticket is useful to its holder only together with the session key that was delivered beside it, so lifting both from a host's ticket cache lifts the whole credential. The attacker builds a fresh `Authenticator` — `cname`, `crealm`, a current `ctime` and `cusec` — seals it under that session key, and sends it in an `AP-REQ` with the stolen `ticket`. The service decrypts `ticket.enc-part` with its own long-term key, reads the session key out of the recovered `EncTicketPart`, decrypts the `Authenticator` with it, and checks that the names match and `ctime` is inside its clock-skew window. Every check passes, because the protocol's proof of identity here *is* possession of the session key.
code
asn1 · 21 linesAP-REQ ::= [APPLICATION 14] SEQUENCE {
pvno [0] INTEGER (5),
msg-type [1] INTEGER (14),
ap-options [2] APOptions,
ticket [3] Ticket, -- stolen; enc-part sealed under the
-- service principal's long-term key
authenticator [4] EncryptedData -- built fresh; sealed under the
-- session key that came with it
}
Authenticator ::= [APPLICATION 2] SEQUENCE {
authenticator-vno [0] INTEGER (5),
crealm [1] Realm,
cname [2] PrincipalName,
cksum [3] Checksum OPTIONAL,
cusec [4] Microseconds,
ctime [5] KerberosTime, -- must fall inside the skew window
subkey [6] EncryptionKey OPTIONAL,
seq-number [7] UInt32 OPTIONAL,
authorization-data [8] AuthorizationData OPTIONAL
}go deeper
Remember that a Kerberos ticket behaves like a bearer credential: whoever holds it together with its session key can use it until its end time passes. Being able to state that much is enough at this stage.
Walk the AP-REQ out loud: the stolen ticket, an Authenticator you build fresh and seal under the ticket's session key, and the service decrypting the ticket with its own long-term key before it can read that Authenticator at all.
Show what the accept path cannot establish - no KDC round trip, no issuance record, an optional and usually absent address field - and name the errors that bound the attack, KRB_AP_ERR_SKEW, KRB_AP_ERR_REPEAT and KRB_AP_ERR_TKT_EXPIRED.
Frame it as a designed trade. The AP exchange authenticates a caller with no round trip to any third party, which is what lets Kerberos scale, and the same property is what makes a copied ticket usable. Any position you take moves cost between those two.
## What Pass-the-Ticket actually moves A Kerberos client that has obtained a service ticket holds two separate things, and the difference between them is the whole attack. The first is the `Ticket` structure, whose `enc-part` is sealed under the **long-term key of the service principal named in `sname`**. The client cannot read it and does not need to — it is carried, not inspected. The second is the **session key**, which arrived in the reply's own `enc-part` sealed under a key the client already held. Everything a client ever does with a ticket, it does with that session key. Pass-the-Ticket is the observation that the two together are the entire credential. Copy both out of wherever a host keeps them — the ticket cache on the operator workstation that reports a paper mill's process data, a memory image of the process holding it, a backup of a cache file — and you can authenticate as the `cname` written inside the ticket, to the service named in `sname`, until its `endtime` passes. No password is involved, nothing is cracked, and **no message is exchanged with the KDC**. ## The exchange it rides on 1. Build an `Authenticator ([APPLICATION 2])`: `crealm` and `cname` copied from the ticket, a current `ctime` and `cusec`, optionally `cksum`, `subkey` and `seq-number`. 2. Encrypt it under the **session key that came with the stolen ticket**. 3. Send an `AP-REQ ([APPLICATION 14])` carrying `ap-options`, the stolen `ticket`, and that encrypted `Authenticator`. 4. The service decrypts `ticket.enc-part` with **its own long-term key**, recovering an `EncTicketPart` — `flags`, `key`, `crealm`, `cname`, `transited`, `authtime`, `starttime`, `endtime`, `renew-till`, `caddr`, `authorization-data`. 5. It lifts `key` out of that structure and decrypts the `Authenticator` with it. 6. It compares the `Authenticator`'s `cname` and `crealm` against the ticket's, checks `ctime` against its own clock, and checks the current time against `starttime` and `endtime`. 7. If `MUTUAL-REQUIRED (ap-options bit 2)` is set it answers with an `AP-REP ([APPLICATION 15])` — which proves the **service** holds its own long-term key, and says nothing whatever about the client. ## What the accept path establishes, and what it does not | The service does establish | It does not establish | |---|---| | The ticket decrypts under its own long-term key, so a KDC holding that key issued it | Which host or process is presenting the ticket now | | The requester could seal a fresh `Authenticator` under the session key | That the requester is the principal in `cname` rather than someone holding the key | | `ctime` falls inside the accepted clock-skew window | That this presentation is the first, unless it keeps a replay cache | | The current time falls between `starttime` and `endtime` | That the ticket has not been copied since it was issued | The `caddr` field can carry client addresses, but it is **optional**, is commonly absent, and binds to an address rather than to a host. There is no issuance record to consult, no revocation list, and no callback: the AP exchange was deliberately designed so a service can authenticate a caller with **no network round trip to anywhere**, and that design is precisely what makes a copied ticket usable. ## The clock-skew window is the replay window The `Authenticator`'s `ctime` must fall inside the skew the service accepts, or the answer is `KRB_AP_ERR_SKEW`. A captured `AP-REQ` resent inside that window decrypts and checks out exactly as the original did — the bytes are identical and every field is still valid. The one thing that rejects it is a service that remembers the authenticators it has already seen and answers `KRB_AP_ERR_REPEAT`. Widening the window to paper over unsynchronised clocks widens the replay opportunity by exactly the same amount. Past `endtime` the answer becomes `KRB_AP_ERR_TKT_EXPIRED`, which is why the ticket's own lifetime is the natural bound on the attack rather than anything the service does. ## Why the protocol is answering correctly Every step above is conformant. The attacker sends a well-formed `AP-REQ` and the service performs every check the specification asks of it. What is being exploited is the **possession model**: a Kerberos ticket plus its session key is a bearer-shaped credential for the lifetime written into it, and the protocol has no mechanism inside the AP exchange for asking whether the holder is the party the KDC had in mind. Say that, name the exchange, and name the two things that had to be copied, and the question is answered.
- Why does setting MUTUAL-REQUIRED in ap-options not help against a presented stolen ticket?Mutual authentication runs in the other direction. When `MUTUAL-REQUIRED (ap-options bit 2)` is set, the service returns an `AP-REP` sealed with the session key, proving to the *client* that the service could decrypt the ticket and therefore holds the right long-term key. It adds no check on who the client is, so an attacker presenting a copied ticket simply receives a valid `AP-REP` like anyone else.
- A captured AP-REQ is resent to the same service ninety seconds later and is accepted. What was missing?A replay cache. The `Authenticator`'s `ctime` was still inside the accepted clock-skew window, so no `KRB_AP_ERR_SKEW` applied, and the ticket was still between `starttime` and `endtime`. Only a service that records the authenticators it has already seen can spot the duplicate and answer `KRB_AP_ERR_REPEAT`. The skew window is therefore the size of the replay opportunity.
- Does a ticket-granting ticket behave the same way if it is copied?The mechanics are the same but the exchange differs. A copied TGT and its session key are spent at the ticket-granting service: the holder sends a `TGS-REQ` with the TGT as `pa-tgs-req (padata-type 1)` padata and an `Authenticator` sealed under the TGT's session key, and receives service tickets for whatever `sname` it asks for, within the TGT's `endtime` and `renew-till`.
A left-luggage receipt and the counterfoil torn from it: the clerk matches the two halves and hands over the case. He is checking that the halves fit each other, not who is holding them.
saying these in an interview costs you the question
- Says the service asks the KDC whether the ticket is still valid
- Says the ticket alone is enough without its session key
- Claims the attacker must decrypt or crack the ticket first
- Believes a ticket is bound to the client's address by default
- Thinks mutual authentication proves the client is genuine