Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 21 Apr 2004 14:33:55 -0700 (PDT)
From:      Don Lewis <truckman@FreeBSD.org>
To:        silby@silby.com
Cc:        avalon@caligula.anu.edu.au
Subject:   Re: [Full-Disclosure] IETF Draft - Fix for TCP vulnerability (fwd)
Message-ID:  <200404212133.i3LLXu7E047699@gw.catspoiler.org>
In-Reply-To: <20040421133638.S15588@odysseus.silby.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On 21 Apr, Mike Silbersack wrote:
> 
> 
> On Wed, 21 Apr 2004, Don Lewis wrote:
> 
>> On 21 Apr, Mike Silbersack wrote:
> 
>> > Would it be feasible for us to create a four to five element array to
>> > track "resettable" sequence numbers?  This could hold the sequence numbers
>> > of the last few packets transmitted, and account for that edge case as
>> > well.  I'm very uneasy with the IETF step C - sending more packets out
>> > into the network sounds like a new type of amplification attack.
>>
>> I'd be concerned about the extra memory, especially in cases where we
>> want to support very large numbers of connections.
> 
> I don't think the memory would be prohibitive, but upon further thought I
> don't think the idea is advantageous.
> 
>> As far as amplification, step C has a gain of less than one, since
>> packets are only transmitted if the incoming packet hits the window, and
>> they will be the same or smaller in size than the incoming packets.  I
>> don't know if it would be valid to rate limit them ...
> 
> Good point, I had forgotten about that.  However, I'm still worried that
> sending those acks could have a downside.  With all the tcp stacks out
> there, it seems probable that something will go wrong.
> 
>> If this is the only edge case that we have to worry about, we might be
>> able change the test to:
>>
>>                 if (th->th_seq == tp->last_ack_sent ||
>>                     th->th_seq == tp->last_ack_sent + tp->rcv_wnd - 1) {
> 
> Ok, what if we do something like this:
> 
> 1.  Accept all RSTs meeting the criteria you just listed above.

At this step, it would be better if we used the window size that was
advertised it the last packet sent, since that is what the sequence
number of the RST packet will be calculated from, while the window size
could have increased if data was consumed from the receive queue between
the time we sent the last packet and when we received the RST.

It doesn't look like we keep the necessary data for this.  Probably the
easiest thing to do would be to calculate the expected sequence number
in tcp_output() and stash it in the pcb.

> 2.  Keep a global counter of all out of window RSTs that were received
> which corresponded to legitimate connections.  (Don't track _all_ RSTs, or
> backscatter from scanners / etc will falsely be detected as an attack.)
> If we're over a certain threshold, set the "under attack" flag.
> 
> 2a.  This counter could also be per-socket, with a very low threshold.  (I
> think I like this better, actually.)
> 
> 3.  If a RST arrives within the window, check the under attack flag; if
> we're under attack, drop it.  If we're not under attack, accept it.  Add
> to a counter tracking how many of these we received and what we did with
> them.
> 
> With this setup, any attempt to run the brute-force RST attack *should*
> fail, unless the attack gets lucky enough to have one of his first few
> packets land in the window.  However, it should still let oddball TCP
> stacks RST connections, because they're presumably going to land within
> the window on the first packet.
> 
> This would also be easy to implement. :)
> 
> Thoughts?

It would be nice to be able to age invalid RST packets so that things go
back to normal when an attack ends, but this might enable slow speed
attacks.

We have to be careful not to falsely trigger the attack code if we ever
decrease the window size.

RST packets with sequence numbers lower than (to the left of) the window
can be expected under normal circumstances if there are a number of
packets in flight when the peer decides to drop the connection.  This
should not trigger a global attack status.  Trigger a per-socket attack
status should be ok, because if the RST packets are legitimate, they
should trip the exact match test.



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