Defending against Sequence Number Attacks
obsoleted by
- rfc-9293 — Transmission Control Protocol (TCP)
obsoletes
- rfc-1948 — Defending Against Sequence Number Attacks
updates
- rfc-793 — Transmission Control Protocol
Extracted elements (17)
MD5 is acceptable as the PRF hash despite known weaknesses (RFC 6151) because the threat model only requires preventing off-path guessing, not resisting a keyed-hash attack; MD5 is faster and used in virtually all existing implementations of this algorithm.
Protection against stale segments from a previous connection incarnation is primarily enforced by the TIME-WAIT state and TCP's quiet-time concept, not by the ISN monotonicity requirement; this makes the ISN free to be per-connection-id rather than globally monotonic.
Pure random ISN selection would mitigate sequence number guessing attacks but would break the 4.4BSD heuristics that allow a new connection to be accepted while a previous incarnation is still in TIME-WAIT. The PRF-based approach preserves monotonic growth per connection-id while obscuring cross-connection relationships.
Rather than keeping state for all recently terminated connections (which wastes memory), the algorithm uses a secret-keyed PRF so that the ISN space per connection-id is unpredictable without that state.
RFC 793's global 32-bit counter incremented every 4 microseconds made ISN prediction trivial for off-path attackers, enabling trust-relationship exploitation attacks (Morris 1985, Shimomura 1995); the per-connection PRF approach was introduced in RFC 1948 to close this window.
The secret key should be 128 bits in length to resist exhaustive search by an attacker who can observe ISNs and knows the hash function in use.
The secret key should be rotated on system bootstrap, after a predefined/random time interval, or after sufficient uses; after rotation, either dead-connection state must be kept or a quiet time of two MSLs must be observed to avoid breaking the 4.4BSD incarnation heuristics.
Address-based trust relationships (e.g., SMTP client authentication by IP, DNS secondary server authentication for zone transfers) remain in use and are vulnerable to blind TCP connection-spoofing when ISN generation is weak.
Some 4.4BSD-derived stacks use the ISN of an incoming SYN to heuristically allow a new connection incarnation while the previous one is still in TIME-WAIT; the proposed algorithm preserves this behavior within a connection-id space, unlike pure random ISN selection.
If random numbers are used as the sole source of the secret key, they MUST be chosen in accordance with the recommendations given in RFC 4086.
TCP SHOULD generate its Initial Sequence Numbers using the expression ISN = M + F(localip, localport, remoteip, remoteport, secretkey), where M is the 4 microsecond timer and F() is a pseudorandom function of the connection-id.
The PRF function F() MUST NOT be computable from the outside; otherwise an attacker could still guess sequence numbers from ISNs observed on other connections.
The ISN generation formula is ISN = M + F(localip, localport, remoteip, remoteport, secretkey), where M is a 4-microsecond timer and F() is a PRF (e.g., a cryptographic hash such as MD5) keyed on the 4-tuple and a secret. This gives each connection a separate sequence number space.
An eavesdropper who observes the initial handshake of a connection learns its ISN state and can still launch guessing attacks by impersonating that connection; since the offset between a fake and real connection is roughly constant for the secret's lifetime, preventing capture of handshake packets is important.
Good sequence numbers are not a replacement for cryptographic authentication such as IPsec (RFC 4301) or TCP-AO (RFC 5925); they are only a palliative measure against off-path attackers.
TCP port number randomization per RFC 6056 complements ISN randomization by further obscuring the four-tuple (localip, localport, remoteip, remoteport) that an off-path attacker must guess to target a connection.
The proposed algorithm may allow an attacker to count the number of hosts behind a NAT by establishing multiple TCP connections to the NAT's public address and identifying distinct sequence number spaces, one per internal host.