For those who are on Best-of-Security, apologies for having to read this
twice, but given the interest in the SYN problem in this forum, I thought
this would interest some folks here, and perhaps stir them to follow upon
Paul D. Robertson "My statements in this message are personal opinions
net which may have no basis whatsoever in fact."
---------- Forwarded message ----------
Date: Mon, 23 Sep 1996 17:26:18 -0400
From: Eric Schenk <schenk @
Reply-To: netdev @
Eric Schenk <schenk @
To: netdev @
Cc: Alan Cox <alan @
Subject: BoS: A new thought on TCP SYN attacks
Resent-Date: Tue, 24 Sep 1996 16:03:33 +1000
Resent-From: best-of-security @
I've been thinking a bit about D.J. Bernstein's proposed method
of dealing with TCP SYN flooding, and I think I've come up with
a new twist that might make it usuable, at least in some reasonable
subset of cases.
The original proposal from D.J. Bernstein was to take a secret,
(changed every 75 seconds or so), the incoming address, port,
and sequence number and the local address and port and run then
through MD5 or some other secure hash to come up with a 32 bit
sequence number for the outgoing response. When a data packet
comes in that does not match a socket, we just check if the
sequence numbers match the appropriate hash, and if so create
a new socket.
Objections to this proposal include:
1. The incoming MSS is not stored anywhere, which we need to
know once we actually create the connection.
2. No initial RTT measurement will be possible, since
we do not save the time.
3. TCP options such as RFC1323, SACK and T/TCP options cannot be used.
4. The sequence numbers generated by this scheme will not
have the required seperation properties in sequence space
to guarantee reliable TCP operation in the presence of
old packets floating around the network.
After some thought, I think I can address most of these concerns.
1. As pointed out in the discussion in comp.protocols.tcp-ip,
there are not a lot of common MSS values. If we reserve 3 bits
of the 32 bit initial sequence number to store a 3 bit index
into a lookup table of likely MSS values, we can cover most cases.
For cases that don't occur in the table, we simply pick the
the largest choice in the table smaller than the proposed MSS.
2. I think this is a red herring. Currently, for various performance
reasons we ignore RTT measures on SYN packets anyway.
3. Currently, we don't even implement any of these.
I believe the timestamps portion of RFC1323 can be dealt with
without needing to remember anything. Similarly for SACK.
This would depend on our implementation beeing able to accept
Timestamp options or SACK options that start occuring after the SYN
packet. This should not be a big deal. The main thing to remember
is that we should never initiate such options without seeing them first.
Window scaling and T/TCP are problematic. I don't see how to deal with
these at this time.
4. Spacing in the initial sequence number space. In my earlier message
I worried that because we want to tie the ISN to a fast clock, that
we would have to search a very large space to check validity, reducing
the number of bits left for the cookie.. In fact, there is a handy
clock we can tie it to that will not require more than a single check:
namely, the ISN provided by the incoming SYN packet. Here is my basic idea:
saddr source address
sport source port
sseq source sequence number
daddr destination address
dport destination port
We combine (saddr, sport, daddr, dport) with a random secret picked
at boot time. Let t be the MD5 hash of this information. [Sharp readers
will note that this is exactly the formula for an ISN in the current
linux code.] Compute the outgoing ISN as (t + sseq). As long as the
remote TCP is generating appropriately spaced initial sequence numbers,
we will generate appropriately spaced initial sequence numbers.
An attack would still need to know our random secret in order to
spoof a connection without seeing any of our outgoing traffic.
If an attacker can see our outgoing traffic, then they will be
able to spoof a connection, but they could have done that anyway,
even under the secure sequence number scheme we currently use.
What I haven't covered yet, is the need to encode the MSS, and the
issue of expiring "old" cookies. We can encode the MSS by replacing
the top 3 or so bits of the cookie with an index into a table of MSS
values. This reduces the security marginally.
This leaves the issue of expiring cookies. Once we issue a cookie,
a respondent on the far end can wait for an arbitrary period before
responding, and still get a connection. This could be avoided by
replacing some of the high order bits of the cookie with a randomly
selected secret that changes once every few minutes.
If we leave enough bits in the cookie depdendent on the incoming ISN,
then we still avoid problems with sequence space wrap around.
I should say that it is not clear to me that this additional
complication is necessary.
So the end result here is that we can deal with SYN flooding using
constant space, provided that we don't want to implement window
scaling or T/TCP. I'll give RFC1323 another look later tonight and
see if I can figure out a way to get window scaling to work. T/TCP
is probably harder.
Eric Schenk www: http://www.cs.toronto.edu/~schenk
Department of Computer Science email: schenk @
University of Toronto