Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Nov 1997 14:47:19 -0800
From:      Don Lewis <Don.Lewis@tsc.tdk.com>
To:        Jim Shankland <jas@flyingfox.com>, Don.Lewis@tsc.tdk.com
Cc:        security@FreeBSD.ORG
Subject:   Re: new TCP/IP bug in win95 (fwd)
Message-ID:  <199711212247.OAA15771@salsa.gv.tsc.tdk.com>
In-Reply-To: Jim Shankland <jas@flyingfox.com> "Re: new TCP/IP bug in win95 (fwd)" (Nov 21,  9:11am)

next in thread | previous in thread | raw e-mail | index | archive | help
On Nov 21,  9:11am, Jim Shankland wrote:
} Subject: Re: new TCP/IP bug in win95 (fwd)
} Hmm, I'm not sure I agree that your fix is optimal for this bug, Don.

I'm not sure myself, but see below.

} Seems like you're relying on the ACK field being out of range to drop
} the packet that the victim machine itself generated.

Yes, because if the ACK is out of range the SYN flag may be cleared.

} Apart from
} generating an extra packet (the bogus response that the victim sends
} in response to the original, forged SYN), it also seems that if the
} attacker can guess the right sequence number, it can circumvent your
} fix.  Granted, that's much harder -- and more platform-variable --
} than the exploit that's been posted.

If the attacker guesses the right sequence number to generate an
in range ACK, then the SYN flag is not cleared, and the connection
is dropped later in the code:

        /*
         * If a SYN is in the window, then this is an
         * error and we send an RST and drop the connection.
         */
        if (tiflags & TH_SYN) {
                tp = tcp_drop(tp, ECONNRESET);
                goto dropwithreset;
        }

I think the RST should be sent because this packet could actually be
from another host.  My change just happens to be source address neutral.

What I'm not sure of is if my sequence number test catches all the
potential problems.  I just moved the existing ACK test earlier in
the code.  Maybe it would be better to change this test to always drop
the packet and send RST if we see a SYN,ACK in the SYN_RCVD state.  I
really need to think about this some more and comments are most welcome.

} The essence of the attack lies in engineering a TCP connection in
} which (src-ip, src-port) is equal to (dst-ip, dst-port); the fact
} that the ACK value in the second packet is out of range seems like
} a sort of side effect.

I think the ACK value being out of range is what makes the attack work,
causing the stack gets into an ACK war with itself trying to synchronize
sequence numbers.  If the ACK is in range, then the stack should see
the SYN flag, send a RST which will end up getting ignored because the
connection will already gone by the time it's processed, and drop the
connection.

I think it's also possible to exploit this using two different ports
on the same host, or two different IP addresses on the host if it's
multihomed.  It's more difficult since it would require sending two
spoofed SYNs back to back, each of which would have to be processed
before either of the responses generated are processed.

} I can't think of any case in which it would
} be legal or desirable to have a TCP connection with (src-ip, src-port)
} equal to (dst-ip, dst-port); so why not just reject such a connection
} attempt out of hand in the TCPS_LISTEN state?

I don't think this completely closes the hole, but it does block the easiest
attack.  BTW, such connections are legal, but the state transition diagram
goes from SYN_SENT -> SYN_RCVD -> ESTABLISHED, so blocking this attack in
the LISTEN state should not be a problem.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199711212247.OAA15771>