Re: "LAND" Attack Update

Charles M. Hannum (mycroft@MIT.EDU)
Sat, 22 Nov 1997 14:19:11 -0500

[Preface: I'd like to point out that a couple of groups are,
inadvertantly or otherwise, pulling a sneaky little bait-and-switch
trick. Since they've now patched around the `land' bug, they now
claim they are not vulnerable, misleading people into thinking that
their systems are safe, when they may very well not be running code
that predates the patch, and therefore actually be quite vulnerable.
I find this trend very disturbing.]

The changes we've made in NetBSD to deal with the `land' attack are:

1) If a socket in LISTEN state receives a SYN+ACK packet, then send a
RST and drop the packet.

2) If a socket in LISTEN state receives a SYN-only packet claiming to
be from itself, then drop the packet.

The rationale for this is as follows:

1) Since the initial sequence number cannot possibly be known, it is
never correct to send an ACK before an initial SYN has been sent.
A socket in LISTEN state didn't send a SYN, unless it was a
SYN+ACK, in response to a SYN-only packet, in the second stage of
the 3WHS. In this case, we would not expect to get another SYN; we
should instead get an ACK-only packet to complete the 3WHS. We
treat the stray SYN+ACK the same as data for an old connection.

2) A socket in LISTEN state is not initiating a connection attempt, so
if it receives a SYN-only packet from itself, it *must* be a
forgery. A self-connect would cause the socket to no longer be in
LISTEN state before the SYN-only packet arrives. There's no point
in sending a RST in this case, since we'd just be sending it to
ourselves.

(Actually, this change isn't really complete; in theory, if the
LISTEN socket was bound to INADDR_ANY, then we should check whether
the source address of the SYN was any of our local addreses, not
just that it matches the destination. However, a failure to detect
the attack at this point will merely generate an extra SYN+ACK that
will be dropped by the first change.)

Interestingly, SunOS (not Solaris) appears to do #1, but still freezes
up. I haven't investigated why.