RFC 1948
Defending Against Sequence Number Attacks
RFC 1948 π Defending Against Sequence Number Attacks
okay bestie, RFC 1948 is here and it's giving TCP drama π S. Bellovin from AT&T Research wrote it in May 1996, and it's marked Informational, so it's sharing info, not setting a standard π The title block doesn't list any RFCs it obsoletes or updates π¦
Status of This Memo β¨
this memo provides information for the Internet community. it does not specify an Internet standard of any kind. distribution of this memo is unlimited π
Abstract πΈ
IP spoofing attacks built on sequence number spoofing have become a serious threat on the Internet (CERT Advisory CA-95:01) π ubiquitous cryptographic authentication is the right answer, but the author proposes a simple tweak to TCP implementations that should be a very substantial block to the current wave of attacks π‘οΈ
Overview and Rational π¦
okay so back in 1985, Morris [1] described an attack based on guessing what sequence numbers TCP [2] will use for new connections π the attacker gags a host that the target trusts, impersonates that trusted host's IP address while talking to the target, and completes the 3-way handshake using their guess at the next initial sequence number. an ordinary connection to the target is used to gather sequence number state information. put that together with address-based authentication and the attacker can execute commands on the target host π
cryptographic authentication [3,4] is the proper solution, obviously π but it's going to take a long time before it's deployed. so many sites had to restrict protocols that rely on address-based authentication, like rlogin and rsh π and then the prevalence of "sniffer attacks" (network eavesdropping, CERT Advisory CA-94:01) made ordinary TELNET [5] super dangerous too π© so the Internet is basically left without a safe, secure mechanism for remote login. iconic behavior from the internet, honestly π
the proposal is a simple change to TCP implementations that will block most sequence number guessing attacks β¨ more precisely, such attacks remain possible if and only if the Bad Guy already has the ability to launch even more devastating attacks π
Details of the Attack π
to get why sequence number guessing works, you have to look at the 3-way handshake used to open a TCP connection [2] π€ say client machine A wants to talk to rsh server B. it sends this:
A->B: SYN, ISNa
that's a packet with the SYN ("synchronize sequence number") bit set and an initial sequence number ISNa π
B replies with:
B->A: SYN, ISNb, ACK(ISNa)
so B is sending its own initial sequence number and acknowledging A's. the actual numeric value ISNa has to show up in the message π
then A wraps up the handshake:
A->B: ACK(ISNb)
the initial sequence numbers are supposed to be more or less random, right? RFC 793 says the 32-bit counter goes up by 1 in the low-order position about every 4 microseconds π§ but Berkeley-derived kernels instead bump it by a constant every second, plus another constant for each new connection π so if you open a connection to a machine, you can know with a very high degree of confidence what sequence number it'll use for its next connection. and that's the attack, bestie π
here's how it goes. the attacker X first opens a real connection to its target B, say to the mail port or the TCP echo port. that gives X ISNb. then X impersonates A and sends:
Ax->B: SYN, ISNx
where "Ax" means a packet X sends while pretending to be A π
B's response to X's original SYN (sort of) goes:
B->A: SYN, ISNb', ACK(ISNx)
that message goes to the legit A, which we'll get to in a sec π X never sees it, but X can still send:
Ax->B: ACK(ISNb')
using the predicted value for ISNb'. if the guess is right, and usually it will be, B's rsh server thinks it has a legit connection with A, when X is actually the one sending the packets π X can't see the output of this session, but it can run commands as more or less any user, and at that point the game is over and X has won π
there's one small snag. if A sees B's message, it'll realize B is acknowledging something it never sent, and it'll send a RST packet to tear the connection down π« there are a few ways to prevent that. the easiest is to wait until the real A is down (possibly because of enemy action, obviously) π in actual practice, X can gag A by exploiting a very common implementation bug, which is described below π«£
The Fix π οΈ
okay the choice of initial sequence numbers for a connection is not random π ββοΈ instead, it has to be chosen to minimize the probability of old stale packets being accepted by new incarnations of the same connection [6, Appendix A]. also, TCP implementations derived from 4.2BSD have special code to deal with those reincarnations when the server end of the original connection is still in TIMEWAIT state [7, pp. 945] π§ so simple randomization, like the one suggested in [8], won't work well. sad but true π€
but duplicate packets, and therefore the restrictions on initial sequence numbers for reincarnations, are peculiar to individual connections. there's no connection, syntactic or semantic, between the sequence numbers used for two different connections π so we can stop sequence number guessing by giving each connection, meaning each 4-tuple of <localhost, localport, remotehost, remoteport>, its own separate sequence number space π¦ inside each space, the initial sequence number is incremented according to [2], but there's no obvious relationship between the numbering in different spaces β¨
the obvious way to do this is to keep state for dead connections. the easiest way to do that is to change the TCP state transition diagram so both ends of every connection go to TIMEWAIT state. that would work, but it's inelegant and eats up storage π© so instead, we use the current 4 microsecond timer M and set:
ISN = M + F(localhost, localport, remotehost, remoteport).
it is vital that F can't be computed from the outside, or an attacker could still guess sequence numbers from the initial sequence number used for some other connection π¨ so we suggest F be a cryptographic hash function of the connection-id and some secret data. MD5 [9] is a good choice, since the code is widely available π the secret data can either be a true random number [10], or the combination of some per-host secret and the boot time of the machine. the boot time is included so the secret gets changed every now and then π other data, like the host's IP address and name, can go in the hash too. that eases administration by letting a network of workstations share the same secret data while still giving each one separate sequence number spaces π₯οΈβ¨
our recommendation, honestly, is to use all three of these items: as random a number as the hardware can generate, an administratively-installed pass phrase, and the machine's IP address. that lets each site make its own call on how secure the secret is π
heads up though: the secret can't easily be changed on a live machine. changing it would change the initial sequence numbers used for reincarnated connections, and to stay safe you'd either have to keep dead connection state or observe a quiet time of two maximum segment lifetimes after the change β³
A Common TCP Bug π
as mentioned earlier, attackers using sequence number guessing have to "gag" the trusted machine first π€ there are a bunch of ways to do that, but most of the attacks detected so far rely on an implementation bug π
when SYN packets come in for a connection, the receiving system creates a new TCB in SYN-RCVD state π¦ to avoid overconsuming resources, 4.2BSD-derived systems only allow a limited number of TCBs in this state per connection. once that limit is hit, future SYN packets for new connections get discarded, and it's assumed the client will retransmit them as needed π
when a packet comes in, the very first thing that has to happen is a search for the TCB for that connection π if no TCB is found, the kernel searches for a "wild card" TCB that servers use to accept connections from all clients. the unfortunate part is that in many kernels this code runs for any incoming packet, not just initial SYN packets π€ so if the SYN-RCVD queue is full for the wildcard TCB, any new packets that specify just that host and port number get discarded, even if they aren't SYN packets. major bug energy π
to gag a host, the attacker sends a few dozen SYN packets to the rlogin port from different port numbers on some non-existent machine π» this fills up the SYN-RCVD queue, while the SYN+ACK packets go off to the bit bucket. the attack on the target machine then looks like it's coming from the rlogin port on the trusted machine π the replies (the SYN+ACKs from the target) get treated as packets belonging to a full queue, and they're dropped silently. this could be avoided if the full queue code checked for the ACK bit, which cannot legally be on for legitimate open requests. if it is on, a RST should be sent in reply π
Security Considerations π
good sequence numbers are not a replacement for cryptographic authentication. at best, they're a palliative measure. π
an eavesdropper who can observe the initial messages for a connection can work out its sequence number state, and may still be able to launch sequence number guessing attacks by impersonating that connection π however, that same eavesdropper can also hijack existing connections [11], so the incremental threat isn't that high π€·ββοΈ still, the offset between a fake connection and a given real connection will be more or less constant for the lifetime of the secret. so it's important to make sure attackers can never capture such packets π¨ typical attacks that could disclose them include both eavesdropping and the variety of routing attacks discussed in [8].
if random numbers are used as the sole source of the secret, they MUST be chosen in accordance with the recommendations given in [10]. π₯
Acknowledgments π«Ά
Matt Blaze and Jim Ellis contributed some crucial ideas to this RFC π Frank Kastenholz contributed constructive comments to this memo π
References β¨
okay bestie, here's the reading list π every single one of these is cited in the doc, so bookmark them π
- [1] R.T. Morris, "A Weakness in the 4.2BSD UNIX TCP/IP Software", CSTR 117, 1985, AT&T Bell Laboratories, Murray Hill, NJ.
- [2] Postel, J., "Transmission Control Protocol", STD 7, RFC 793, September 1981.
- [3] Kohl, J., and C. Neuman, "The Kerberos Network Authentication Service (V5)", RFC 1510, September 1993.
- [4] Atkinson, R., "Security Architecture for the Internet Protocol", RFC 1825, August 1995.
- [5] Postel, J., and J. Reynolds, "Telnet Protocol Specification", STD 8, RFC 854, May 1983.
- [6] Jacobson, V., Braden, R., and L. Zhang, "TCP Extension for High-Speed Paths", RFC 1885, October 1990.
- [7] G.R. Wright, W. R. Stevens, "TCP/IP Illustrated, Volume 2", 1995. Addison-Wesley.
- [8] S. Bellovin, "Security Problems in the TCP/IP Protocol Suite", April 1989, Computer Communications Review, vol. 19, no. 2, pp. 32-48.
- [9] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, April 1992.
- [10] Eastlake, D., Crocker, S., and J. Schiller, "Randomness Recommendations for Security", RFC 1750, December 1994.
- [11] L. Joncheray, "A Simple Active Attack Against TCP, 1995, Proc. Fifth Usenix UNIX Security Symposium.
Author's Address π
this is who wrote it, the legend himself π«Ά
Steven M. Bellovin
AT&T Research
600 Mountain Avenue
Murray Hill, NJ 07974
Phone: (908) 582-5886
EMail: smb@research.att.com
π¦ where this page comes from
- ietf: rfc1948 1996-05
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms