Subject: RE: Matching addresses in INIT and INIT ACK

From: <[email-masked]>
Date: Mon, 3 Mar 2003 15:29:43 +0200

snip...

> >So, it is not necessary to look in the address list of the
> >INIT as a general rule, so don't try to tell me I "SHOULD".
> >
> >The INIT-ACK case can be handled by VT, so don't try to tell
> >me I "SHOULD" there either.
> >  
> >
> If you don't look in the INIT for addresses your VT method only
> works if:
> 
> A) you can assure that you hand out unique VT's
> and
> B) you KNOW all the addresses that the peer can give you apriori
> 
> Both of the above our true in your implementation..
> 
> My point is, for a general implementation that WILL NOT be able
> to assrue <B> above, you need to look in the INIT-ACK...

	And there is another point that Brian never answered:

	Does the general restart/establishment collision procedure (section 5.2 of RFC 2960) work not checking the addresses inside the INIT?

	Because, I don't see how are you going to populate the Tie Tags or not, if you don't know if the INIT comes from an already established (but crashed) association (or one that it is being formed, i.e., INIT collision)...

	But I guess there might be another way of doing it, which I fail to see... :-/

	BR Iván Arias Rodríguez

---

From: "Brian F. G. Bidulock" <[email-masked]>
Date: Mon, 3 Mar 2003 09:11:50 -0700

Ivan.Arias-Rodriguez,

On Mon, 03 Mar 2003, [email-masked] wrote:

> 	Does the general restart/establishment collision procedure (section
> 	5.2 of RFC 2960) work not checking the addresses inside the INIT?

Yes it does, because the destination address and port numbers of the INIT
are sufficient to find an existing TCB.

> 
> 	Because, I don't see how are you going to populate the Tie Tags or
> 	not, if you don't know if the INIT comes from an already established
> 	(but crashed) association (or one that it is being formed, i.e., INIT
> 	collision)...

You didn't read what I wrote in the last note.  The destination address and
port numbers are sufficient to find the existing TCB from which the tie tags
are populated.  It is not necessary to dig the address list.

> 	But I guess there might be another way of doing it, which I fail to see... :-/

Digging the address list is not necessary to find an existing TCB.  All that
is necessary is the destination address and port pair from the INIT.

--brian

-- 
Brian F. G. Bidulock    ¦ The reasonable man adapts himself to the ¦
[email-masked]    ¦ world; the unreasonable one persists in  ¦
http://www.openss7.org/ ¦ trying  to adapt the  world  to himself. ¦
                        ¦ Therefore  all  progress  depends on the ¦
                        ¦ unreasonable man. -- George Bernard Shaw ¦

---

From: Caitlin Bestler <[email-masked]>
Date: Mon, 3 Mar 2003 10:39:03 -0600

Brian,

Is your point that there is no need to check the INIT-ACK
when it arrives because the other end can check the INIT-ACK
inside the State Cookie in the COOKIE-ECHO?

If so, what is the benefit of deferring the check? The extra
costs, delay and a redundant COOKIE-ECHO, are admittedly
minor. But why tolerate any excess network traffic that
could have been prevented by simply using the data already
available?

Caitlin Bestler
http://asomi.com/CaitlinBestler/

---

From: "Brian F. G. Bidulock" <[email-masked]>
Date: Mon, 3 Mar 2003 10:33:16 -0700

Caitlin,

What excess traffic?  None of the actions in RFC 2960 section 5.2.4
can be detected until COOKIE-ECHO is received.  Attempting to determine
these things from the INIT or INIT-ACK is attempting to fortell the
future.  The result of trying to fortell the future is valid init
attempts being refused.

--brian

---

From: Caitlin Bestler <[email-masked]>
Date: Mon, 3 Mar 2003 12:07:45 -0600

On 3/3/03, Brian F. G. Bidulock wrote:

>Caitlin,
>
>What excess traffic?  None of the actions in RFC 2960
>section 5.2.4 can be detected until COOKIE-ECHO is
>received.  Attempting to determine these things from the
>INIT or INIT-ACK is attempting to fortell the future.  The
>result of trying to fortell the future is valid init
>attempts being refused.
>
>--brian
>
>
>> Is your point that there is no need to check the
>> INIT-ACK when it arrives because the other end can check
>> the INIT-ACK inside the State Cookie in the COOKIE-ECHO?
>> 
>> If so, what is the benefit of deferring the check? The
>> extra costs, delay and a redundant COOKIE-ECHO, are
>> admittedly minor. But why tolerate any excess network
>> traffic that could have been prevented by simply using
>> the data already available?
>> 
>> 
>> Caitlin Bestler

INIT from A:1000 to B:1000 ------------------------------>
INIT form A:1000 to C:1000 ------------------------------>
<-------------------------------------INIT-ACK TO A:1000
                                        from [b,c]:1000
<-------------------------------------INIT-ACK TO A:1000
                                        from [b,c]:1000
                                        
If A properly expands the scope of the first association's
TCB upon receipt to cover both b and c, then the second
INIT-ACK will be recognized as redundant. Only a single
COOKIE-ECHO will be sent.

If A shirks the responsibility of examining the address
list within the INIT-ACK, and instead relies upon B/C to
do the check when it/they process their COOKIE-ECHOEs
then there will be *two* COOKIE-ECHOs sent. The second
COOKIE-ECHO is an excess message that should be prevented.

Further, A SHOULD also realize that the TCB it created for 
"A:1000 - C:1000" has been eclipsed by "A:1000 - [B,C]:1000"
That the "A:1000 - C:1000" TCB should be removed. More
importantly it should be prevent from retransmitting its
INIT message. If no action is taken that would be the
logical result as that it never received an INIT-ACK
response.

There is no fortune-telling going on here. The INIT-ACK
clearly informs A that [B,C]:1000 is a single endpoint.
At the time that B/C generates each INIT-ACK it does not
have enough information to know that A is incorrectly
attempting to create two associations with identical
endpoints. After all, *no* records of prior INIT-ACKs
are supposed to be kept on the passive side. Doing so
creates a weakness for a denial-of-service attack. A (the
active side) has the first opportunity to identify and
correct the problem.

If A wants to leave excess TCBs and indexes dangling around
that its business, but generating excess traffic (when there
was sufficient information to prevent those messages) is a
legitimate network issue.

Caitlin Bestler

---

From: "Randall Stewart (cisco)" <[email-masked]>
Date: Mon, 03 Mar 2003 12:21:52 -0600

>future.  The result of trying to fortell the future is valid init
There is nothing special or magical about a cookie. It is NOT fortelling the
future to look in a INIT   (or INIT-ACK for that matter )that has come 
in to
determine if you can setup
an association, if the association is valid you will gain the proper tie-tag
information.. if it is invalid you can dump it up front and save
the bandwidth of generating a cookie (both for the network as well
as your md5 or sha-1 cpu cycles) and dump the packet early... something
you will be doing under the scenarios which Ivan as outlined when you
have a  general purpose stack where you have no pre-knowledge of the
addresses your peer may have...

R

-- 
Randall R. Stewart
ITD
Cisco Systems Inc.
[email-masked] 815-342-5222(cell) or 815-477-2127(office)

---

From: "Brian F. G. Bidulock" <[email-masked]>
Date: Mon, 3 Mar 2003 11:32:13 -0700

Caitlin,

> <-------------------------------------INIT-ACK TO A:1000

Oh, you are back to this example.  There is no need to peer
into the address lists to do what is required here.  The
information from the IP and SCTP headers of the INIT-ACK is
sufficient.

If these are two INITs for the same connection, then VT (and
port pair and destination address) in the INIT-ACK is sufficient
to identify the association and deem one redundant.  No need to
examine address lists.  Only one COOKIE-ECHO will be sent.

If these are INITs for two different connections then the
TCB of the first INIT-ACK is expanded.  The TCB is again
identified by VT (and port pair and destination address).
There is no need to peer into the source address list.
The second INIT-ACK to arrive has a destination address which
corresponds to the TCB of the first.  VT, destination
address, source address and port pair is sufficient to identify
that the second INIT-ACK belongs to the first TCB.  Only one
COOKIE-ECHO will be sent.

Again: it is not necessary to look in the address list of the
INIT or INIT-ACK.  The IP and SCTP header has all of the
information necessary to identify an existing TCB.

Do you see yet?

--brian

---

From: "Randall Stewart (cisco)" <[email-masked]>
Date: Mon, 03 Mar 2003 13:14:53 -0600

>information from the IP and SCTP headers of the INIT-ACK is
Is not this the example that Caitlin as always been talking about??

>examine address lists.  Only one COOKIE-ECHO will be sent.

And how are the V-Tag's going to help? Each V-Tag of the two
INIT's above SHOULD be different... the one to B should be
say X and the one to C should be say Y...

How will hashing the Vtags make it so you find that the
two are redundant.. Remember, there is NO address list in
the TCB on A, A only has one address... (having an address
list is a specialization for a NON-general stack).

>information necessary to identify an existing TCB.
No, and I don't think your statements above work unless
A has pre-knowledge about what addresses the peer will
have... which is NOT what Caitlin is showing here.. we
are discussing a general purpose stack.. not the specialized
one you keep coming back to.

R

---

From: "Brian F. G. Bidulock" <[email-masked]>
Date: Mon, 3 Mar 2003 12:32:32 -0700

Randall,

> Is not this the example that Caitlin as always been talking about??

I'm sorry, I was confusing Ivan and Caitlin's examples.

> one you keep coming back to.

Read above.  No prior knowledge of addresses is necessary.  The
above works fine without looking in address lists.  The IP/SCTP
headers are sufficient.

--brian

---

From: "Brian F. G. Bidulock" <[email-masked]>
Date: Sat, 8 Mar 2003 02:54:53 -0700

Caitlin,

Consider the following vulnerability in your example:

Host A is establishing an association with Host B/C and
malicious Host X at about the same time.

INIT from A:1000 to B:1000 -------------------------------->
INIT from A:1000 to X:1000 -------------------------------->
<-----------------------------------------INIT-ACK to A:1000
                                             from X:1000 (B)
<-----------------------------------------INIT-ACK to A:1000
                                             from B:1000 (C)

Malicious Host X responds with INIT-ACK first with B's address
in the source address list.

When the second INIT-ACK arrives the first INIT is denied.

Now, consider that malicious Host X places a large number of known
addresses in its address list.  The single INIT-ACK returned
from X:1000 to A:1000 will deny service to every outstanding
INIT from A:1000 to any of the addresses listed for the period
of time that the association to X lives.

Malicious Host X doesn't even have to send COOKIE-ACK, leaving
Host A to retry COOKIE-ECHO and deny service until it times out.
If Host A retries the INIT, the INIT-ACK will deny service for
another timeout interval.

Is that really what you want to do?

How can you place any trust the source address list in the INIT
or INIT-ACK?

--brian

---

From: "Randall Stewart (cisco)" <[email-masked]>
Date: Sat, 08 Mar 2003 06:13:01 -0600

Brian:

One key thing I don't think I understand in your scenario below... something
Steve Bellovin once commented upon to me..

Why are you establishing an association to a malicious host?

Its one thing when you are a passiver server... but it is quite
another when YOU choose to make this establishement to
a malicious host...

I would classify this as way beyond a corner case ...

Its quite likely to have a collision case.. where both attempt
to contact at the same time.. but you making the
connections by your choice to a good host and a malicious
host seem a bit over the top...

If you want to look at this case.. what about

----------INIT from A:1000 to X:1000-------------------->
<---------INIT-ACK from X:1000 to A:1000 (IP-X,IP-B)---
<now at this point it is the same as you
  paint below, you can't establish to Host B in fact
  the app THINK's it is already talking to B
   once the rest of the association comes up>

I can't see how you would be concerned about the
case below and not care about the same scenario
with just a bit of different message ordering...

So I don't see the merit in your argument and I think
Caitlin's comments on extra network traffic are
still not addressed by your comments below... especially
since you are arguing from an extreme corner case...

R

---

From: "Brian F. G. Bidulock" <[email-masked]>
Date: Sun, 9 Mar 2003 15:38:50 -0700

Randall,

> host seem a bit over the top...

Malicious web servers exist in the wild.  Two points:

1)  For a general purpose protocol, one should not make
    assumptions about the probability of certain events, because
    to do so makes assumptions about the application.  (I think
    it was You, Ivan or Caitlin that told me this.)

    I can tell you that for any current IETF applications,
    Caitlin's example will not occur (because it relies upon
    static port allocation on both peers and misconfiguration
    (SO_REUSEADDR) on the peer launching multiple INITs).

    You and Ivan tell me on one hand that saying that the
    situation will not occur or will occur with only extremely
    low probabiliy is not good enough, and that sending an
    "extra" packet in this low probability situation is also not
    good enough, but now you say that it is good enough to have
    a vulnerability because it is low probability?

    I think, quite the reverse, that a corner case with a
    vulnerability deserves far more attention than a corner case
    with what seems on the surface to be an "extra" packet.
    Attached is an analysis of why sending the "extra"
    COOKIE-ECHO actually limits the attack but does not solve
    it.

    To solve it requires that Host A has prior knowledge of the
    addresses belonging to the endpoint to which it launches the
    INIT.

2)  It is naive when considering security to assume that just
    because you are launching an INIT to an endpoint that it can
    be trusted, especially on the Internet.  Do you want your
    transport protocol to place trust in every web server that
    you browse?  I think not.

So I don't think that it is over the top at all.

>    once the rest of the association comes up>

Precisely.  Address X has been verified to some level of
confidence.  X actually returned the proper VT to the proper,
destination address with the proper port pair.  But the source
address list has not been verified.  If action is taken on the
source address list that affects whether those addresses will be
accepted from the legitimate hosts that own them, then the
protocol is naive and vulnerable to attack.  See below for a
detailed attack.

> with just a bit of different message ordering...

Actually I am concerned about both message orderings of the
INIT.  See the example below where the message ordering is as
you show above.

> 
> So I don't see the merit in your argument and I think Caitlin's
> comments on extra network traffic are still not addressed by your
> comments below...  especially since you are arguing from an extreme
> corner case...

See the more detailed argument below as to how the "extra"
COOKIE-ECHO limits the vulnerability, but does not solve it.
Solving the vulnerability requires that A know the addresses of
multi-homed hosts to which it launches an init.  (This is not
too unrealistic: DNS can return multiple IP addresses for a
given host name, and DNS is the normal way that an application
discovers IP addresses to send the INIT in the first place.)

Here's the argument:

Host A/B                                       Host X   Host C/D
  |                                               |        |
  |INIT A:1000 -> X:1000                          |        |
  |---------------------------------------------->|        |
  |TCB1:                                          |        |
  |VT: X                                          |        |
  |PT: 0                                          |        |
  |Loc: A:1000                                    |        |
  |Rem: X:1000                                    |        |
  |State: COOKIE-WAIT                             |        |
  |                                               |        |
  |INIT A:1000 -> C:1000                          |        |
  |------------------------------------------------------->|
  |TCB2:                                          |        |
  |VT: Y                                          |        |
  |PT: 0                                          |        |
  |Loc: A:1000                                    |        |
  |Rem: C:1000                                    |        |
  |State: COOKIE-WAIT                             |        |
  |                                               |        |
  |                  INIT-ACK X:1000 -> A:1000 (D)|        |
  |<----------------------------------------------|        |
  |(TCB2 cannot be found on source addr list)     |        |
  |(TCB1 is found)                                |        |
  |                                               |        |
  |COOKIE-ECHO A:1000->X:1000                     |        |
  |---------------------------------------------->|        |
  |TCB1:                                          |        |
  |VT: X                                          |        |
  |PT: W                                          |        |
  |Loc: A:1000                                    |        |
  |Rem: X:1000, D:1000                            |        |
  |State: COOKIE-ECHOED                           |        |
  |                                  X does not   |        |
  |                                  send (or delays)      |
  |                                  COOKIE-ACK   |        |
  |                                               |        |
  |                           INIT-ACK C:1000 -> A:1000 (D)|
  |<-------------------------------------------------------|
  |                                               |        |

Did you expect Host A to not send the COOKIE-ECHO for TCB2 and
error the connection attempt to the user of TCB2?  The user of
TCB2 will retry, resulting in:

  |                                               |        |
  |T1-cookie timeout                              |        |
  |COOKIE-ECHO A:1000->X:1000                     |        |
  |---------------------------------------------->|        |

Note that X can keep the T1-cookie timeout initially high by
delaying the response to the INIT by RTO.Initial.  T1-cookies
double with each retransmission up to 60 seconds, so the
sequence is 3sec, 6sec, 12sec, 24sec, 48sec, 60sec, 60sec, 60sec
which is 273 seconds or about 4 minutes.  This can be extended
another 30 seconds by responding with a COOKIE-ACK just before
the final timeout (or just before the application times out)
and keeping the association established until after 30 more
seconds a HEARTBEAT is sent to D which will illicit an abort and
then go around again.  If the attacker does not SACK any
received data then Host A may heartbeat X before D, or X could
add several of bogus addresses into the list that will be
heartbeated before D.  Since T3-rtx is held at 60 seconds, X can
get an average of 2 minutes out of each bogus destination in the
source address list.  The application may timeout before that
but the timeouts of Internet applications are well known.

  |                                               |        |
  |T1-cookie timeout                              |        |
  |COOKIE-ECHO A:1000->X:1000                     |        |
  |---------------------------------------------->|        |
  |                                               |        |
  |INIT A:1000 -> C:1000                          |        |
  |------------------------------------------------------->|
  |TCB2:                                          |        |
  |VT: Y                                          |        |
  |PT: 0                                          |        |
  |Loc: A:1000                                    |        |
  |Rem: C:1000                                    |        |
  |State: COOKIE-WAIT                             |        |
  |                           INIT-ACK C:1000 -> A:1000 (D)|
  |<-------------------------------------------------------|

Refused, because TCB exists for A:1000<-->D:1000?

  |                                               |        |
  |T1-cookie timeout                              |        |
  |COOKIE-ECHO A:1000->X:1000                     |        |
  |---------------------------------------------->|        |
  |                                               |        |
  |T1-cookie timeout                              |        |
  |COOKIE-ECHO A:1000->X:1000                     |        |
  |---------------------------------------------->|        |
  |           .                                   |        |
  |           .  repeat                           |        |
  |           .                                   |        |

Note that X can find the address to include in its INIT merely
by sending an INIT to C or D and getting an INIT-ACK.

If the INIT-ACK is not refused, and a COOKIE-ECHO is returned
(the "extra" packet), the following occurs:

Host A/B                                       Host X   Host C/D
  |                                               |        |
  |INIT A:1000->X:1000                            |        |
  |---------------------------------------------->|        |
  |TCB1:                                          |        |
  |VT: X                                          |        |
  |PT: 0                                          |        |
  |Loc: A:1000                                    |        |
  |Rem: X:1000                                    |        |
  |State: COOKIE-WAIT                             |        |
  |                                               |        |
  |INIT A:1000->C:1000                            |        |
  |------------------------------------------------------->|
  |TCB2:                                          |        |
  |VT: Y                                          |        |
  |PT: 0                                          |        |
  |Loc: A:1000                                    |        |
  |Rem: C:1000                                    |        |
  |State: COOKIE-WAIT                             |        |
  |                                               |        |
  |                    INIT-ACK X:1000->A:1000 (D)|        |
  |<----------------------------------------------|        |
  |(TCB2 cannot be found on source addr list)     |        |
  |(TCB1 is found)                                |        |
  |                                               |        |
  |COOKIE-ECHO A:1000->X:1000                     |        |
  |---------------------------------------------->|        |
  |TCB1:                            X does not    |        |
  |VT: X                            send (or delays)       |
  |PT: W                            COOKIE-ACK    |        |
  |Loc: A:1000                                    |        |
  |Rem: X:1000, D:1000                            |        |
  |State: COOKIE-ECHOED                           |        |
  |                             INIT-ACK C:1000->A:1000 (D)|
  |<-------------------------------------------------------|
  |                                               |        |
  |COOKIE-ECHO A:1000->C:1000                     |        |
  |------------------------------------------------------->|
  |TCB2:                                          |        |
  |VT: X                                          |        |
  |PT: Z                                          |        |
  |Loc: A:1000                                    |        |
  |Rem: C:1000, D:1000                            |        |
  |State: COOKIE-ECHOED                           |        |
  |                               COOKIE-ACK C:1000->A:1000|
  |<-------------------------------------------------------|
  |TCB2:                                          |        |
  |VT: X                                          |        |
  |PT: Z                                          |        |
  |Loc: A:1000                                    |        |
  |Rem: C:1000, D:1000                            |        |
  |State: ESTABLISHED                             |        |
  |                                               |        |
  |(Discard TCB1, inform user) (attacker thwarted)|        |
  |                                               |        |

What this would do is force attacker X to reply quickly with
a COOKIE-ACK in order to block the legitimate host as in:

Host A/B                                       Host X   Host C/D
  |                                               |        |
  |INIT A:1000->X:1000                            |        |
  |---------------------------------------------->|        |
  |TCB1:                                          |        |
  |VT: X                                          |        |
  |PT: 0                                          |        |
  |Loc: A:1000                                    |        |
  |Rem: X:1000                                    |        |
  |State: COOKIE-WAIT                             |        |
  |                                               |        |
  |INIT A:1000->C:1000                            |        |
  |------------------------------------------------------->|
  |TCB2:                                          |        |
  |VT: Y                                          |        |
  |PT: 0                                          |        |
  |Loc: A:1000                                    |        |
  |Rem: C:1000                                    |        |
  |State: COOKIE-WAIT                             |        |
  |                                               |        |
  |                    INIT-ACK X:1000->A:1000 (D)|        |
  |<----------------------------------------------|        |
  |(TCB2 cannot be found on source addr list)     |        |
  |(TCB1 is found)                                |        |
  |                                               |        |
  |COOKIE-ECHO A:1000->X:1000                     |        |
  |---------------------------------------------->|        |
  |TCB1:                                          |        |
  |VT: X                                          |        |
  |PT: W                                          |        |
  |Loc: A:1000                                    |        |
  |Rem: X:1000, D:1000                            |        |
  |State: COOKIE-ECHOED                           |        |
  |                             INIT-ACK C:1000->A:1000 (D)|
  |<-------------------------------------------------------|
  |                                               |        |
  |                      COOKIE-ACK X:1000->A:1000|        |
  |<----------------------------------------------|        |
  |TCB1:                                          |        |
  |VT: X                                          |        |
  |PT: W                                          |        |
  |Loc: A:1000                                    |        |
  |Rem: X:1000, D:1000                            |        |
  |State: ESTABLISHED                             |        |
  |                                               |        |
  |(Discard TCB2, inform user)                    |        |
  |                                               |        |

What this serves to do is put the attacker immediately into the
ESTABLISHED state.  If the attacker delays the COOKIE-ACK, the
the legitimate peer will win the race and the attack is
thwarted.  The attacker cannot block for the initial 4 minutes,
but can still place bogus addresses in the address list that
will extend the period of time before a HEARTBEAT/ABORT sequence
to D takes the association down.

The major difference is that, in the ESTABLISHED state, the
user of TCB1 can challenge the peer.  In the COOKIE-ECHOED
state, the user of TCB1 is blocked from communicating on the
association and the ULP cannot assist in detecting the attack.

Because X and D are indistinguishable to "A" ("A" has no prior
knowledge of D or X), the only way to limit the attack is by
sending the "extra" COOKIE-ECHO.  So for the sake of security in
this case, whether it be rare or not, it is better to send the
extra COOKIE-ECHO than not.

Taking actions on unverifiable addresses in the source address
list of INIT-ACKs is IMO quite naive.  It opens the protocol up
to an entire spectrum of addresss spoofing attacks.  The only
source address that is verified in INIT and INIT-ACK are the
packet header source addresses.  (The INIT packet source addres
is verified by HMAC on COOKIE-ECHO; the INIT-ACK source address
is verified by port pair, destination address and VT of the
INIT-ACK matching those of the INIT.)

The reason that 2.6 in the COOKIE-WAIT state works for collision
is because the INIT-ACK with the existing VT is sent to the same
address as the INIT.  The receiver of the INIT already has the
VT from the INIT so sending it in the INIT-ACK to same address
does not expose the VT.

In ths case, it is not possible for "A" to determine whether D
truly belongs to X or whether it truly belongs to C without
prior knowledge of address D.  In the case where knowledge of
address D can be easily obtained (e.g. DNS query), "A" is even
the more vulnerable to X if it does not utilize the same
readily available information about D.

This is really scary.  Server X can easily discover the secondary
addresses service to which it wishes to block access by launching
INITs to them and getting INIT-ACKs.  Then server X can place
_all_ the secondardy addresses in the address list (say 200 of
them).  

The one way that I can see to block the attack is by not
permitting sockets bound to a static port address with
SO_REUSEADDR to have their TCBs expanded by the INIT-ACK beyond
the addresses that were supplied to connect() iff any other TCB
is bound to the same static address (i.e., if resuse is actually
in effect, for our imp that means if the bind bucket is not
marked for fastreuse).  Then the attack cannot form, and neither
association will form unless sufficient prior knowledge was
supplied to at least one of the two connect()s.  This is
certainly not too strong a restriction to place on socket users.

This also means that the "extra" COOKIE-ECHO would never occur
because the INIT-ACK can be refused on the basis of the bind
characteristics.

I still don't need to examine the address list when searching
for a matching TCB, because any action taken on the address list
is vulnerable to attack.  The address list has not been
verified.

The only use for the packet source address in the INIT is to
know where to send (in the collision corner case) the INIT-ACK,
and to populate the cookie.

The only use for the packet source address and source address
list in the INIT-ACK is to expand unexpanded TCBs.  (In this
case, if sufficient address information is not supplied I will
refuse to expand the TCB.)

I hope this illustrates why it is unecessary (and is a secuirty
risk) to examine the source address list of INIT-ACK.

I will talk to the "new addresses" of section 2.6 in a separate
mail.  (This one is already way too long ;)

--brian

---

From: "Randall Stewart (cisco)" <[email-masked]>
Date: Mon, 10 Mar 2003 07:27:13 -0600

>    (SO_REUSEADDR) on the peer launching multiple INITs).
In 1999 Motorola had a display at telcom Geneva in that display
a prototype of RSERPOOL was in use. None of the servers used
SO_REUSEADDR and NONE of the servers used fixed ports.

You are assuming that SO_REUSE is being used to gain access
to the port again.. and this is just not the case. As I stated before
it IS possible to listen and connect (We were doing this with
TCP as well)..

There is no mis-configuration and no mis-use.. but instead
peer-2-peer networking..

>    addresses belonging to the endpoint to which it launches the

No I disagree... the security issue you talk about has a fix that does
NOT involve prior knowledge of all addresses.,..

>So I don't think that it is over the top at all.

If an application is concerned in this manner there is another
way that I have mentioned previously...  and it does not
involve pre-programming the peers addresses..

>multi-homed hosts to which it launches an init. 
>

Nope

> (This is not

DNS is a very static thing.. and is much harder to get updated
then you allude to here.. besides its NOT needed 

>  |INIT A:1000 -> X:1000                          |        |

Our implementation would recognize, when processing
the INIT-ACK of TCB2 (from C) and abort the association
setup.. so there would be no timer firing.. the user would
get an error...

This is the same as if our association to X had gone
out and X had included C's address.. aka camping on
someone elses address.

>  |COOKIE-ECHO A:1000->X:1000                     |        |
I dont understand how would you get a cookie-timeout on TCB2? I could see
a TCB2 t1-timeout.. but TCB2 has never seen the INIT-ACK at
this point. TCB1 holds X and D now (if I am following your
case correctly) and so when the arriving INIT-ACK from 'C'
comes in you would find TCB1... not 2.. so TCB2 is still
in COOKIE-WAIT (not COOKIE-ECHOED).. in our
implementation (as I noted above) it would be aborted... so
the app would know something is up...

>then go around again. 

A couple of questions on this scenario in general...

A) Why is A contacting X AND C at the same time? Most likely
      to gain some sort of service.. If so how is X going to know to
      include D, or have any idea that C is being contacted? I would
      think this is huge guess on the part of X and the probabilities
      of getting this right would be somewhere in the order of
      guessing a Vtag that is not dilluded 1 in 4 Billion.. Have to
     ask M Tuexen if he could work up the probabilities :>

B) You of course are assuming that X would pre-know the values that
      are placed on RTO.Initial and max-retran... which of course are
      user settable... granted using the defaults would be a good guess
      but they may not be correct...

C) What does X have to gain from this attack? Does it fool A into
      thinking it is talking to C, I don't think so.. especially since this
      app purposely contacted X... it had a reason to do so and is expecting
      some service/reply from X. If X wants to deny converstations with
      'C' .. then this only works if you just so happen to begin to talk
      to X and C at the same time. And if its just a plain ole DOS attack
      it seems rather a foolish one... since up front generation of lots
      of INIT's would be a far better choice... Basically I just can't see
      what X is trying to gain in this scenario.. this is in the catagory
      of what is the threat? and what is the results? The result is
      that for some minutes you cannot contact one particular host if
      you happen to contact two hosts at about the same time for
      service and one of the hosts just so happens to guess/know
      you are contacting the other one at the same time.. seems like
      very very fine thread.. and a very minimum threat to me. But
      lets continue anyway...

> If the attacker does not SACK any
>heartbeated before D. 
Why would it do that... A INIT/INIT-ACK counts as a RTT updating
thing as well as a COOKIE/COOKIE-ACK.. so in that sense
D is always the first one that A should HB..

> Since T3-rtx is held at 60 seconds, X can
>source address list. 

Why do you say for each? Once the association is up, the first
bogus destination you HB will return an ABORT and knock
the whole thing down. If X never sends anything to A  then
X will not even know when the association collapses...
A will get the ABORT from the first bogus address, kill
the assocation.. so then if C is re-attempted you end up
with that association coming up...

> The application may timeout before that

If the COOKIE-ACK has not yet been returned the association (as
you have pointed out) is not fully formed. As such I would think
another approach one could take in examining the INIT-ACK address
list is find both sets of TCB's and thus put both of them into
question.... we don't do this but one could quite easily.. At the point
we find the other assocaition and abort your "TCB2" it would be
a simple step to check its state.. if it is not fully formed one could:

1) Abort both.
2) Abort one (this is currently what we do).
3) Look at the state of the existing one, if still forming
    let the cookie-echo go out, but instead mark each
    as suspect and needing HB before letting either
    proceed to ESTABLISHED... if you will put a
    delayed for security reasons... kind of like going
    to an airport but not randomly being singled out
    .. instead being singled out due to a problem. Then
   when the COOKIE-ACK arrives back from each
   you can HB each address before proceeding and
   thus find out who is who ...

>  |COOKIE-ECHO A:1000->X:1000                     |        |
And then guessing who is going to contact me at the same
exact time that it is contacting C or D...

>(the "extra" packet), the following occurs:

But how do you still know which is the hacker and which
is the legit server is it X/D or C/D? In this case you
are saying its whoever gets a COOKIE-ACK to me
first... this is not good.. since you can't tie the two associations
(by your refusal to look in the INIT/INIT-ACK) you can't
do anything but hope that the real user is faster or closer...
Instead one can do as I state above in <3>  hmm I think
I will look into getting this coded into the BSD implementation
seems like a good general solution to the issue...

>  |INIT A:1000->X:1000                            |        |
And <3> above will avoid even this...

>extra COOKIE-ECHO than not.
Yes I see the point of the "extra" COOKIE-ECHO... in this  one corner
case where you have non-completely overlapping INIT-ACK's aka
one is saying (X/D) the other (C/D).. Caitlins example was one where
you had the same overlap.. (C/D) and (C/D) in the INIT's.. using
<3> , one could easily tell if the two INIT-ACK's were completely
overlapping or partially overlapping ... this way the legitimate case
would NOT generate the extra COOKIE-ECHO and the "evil
server" case would so that one could proceed carefully and select
the correct address set for the peer... I.e. which is the evil
attacker X/D or C/D.... This is a interesting case and I do think
I will put it on my discussion list with Steve... if I can get some
of his time... I am not sure if it warrents writting the code to
handle it.. I will ask him before I get to deep into coding <3> :-0

>_all_ the secondardy addresses in the address list (say 200 of
I have so far, not stumbled upon any such web servers.. aka that are
hackers that try to block other sites from being hit... Steve may know
a bit more.. I don't as yet believe this is that scary of a problem...
And if it is, the steps in <3> above can be used to correct it..

I think a far more likely DOS attack would be when X gets a
INIT from A it then starts sending ton's of INIT's to A until
it finds a open port.. then it can generate lots and lots and lots
of INIT's from bogus addresses that nicely get you to do
the HMAC algorithms.. I would be much more concerned about
that aspect than this one .. but like I said Steve may have a different
perspective.... if so I will code up <3> for our implementation...

>certainly not too strong a restriction to place on socket users.
I see no reason for this restriction..

>and to populate the cookie.
Far more likely of a corner case than your evil attacker server
(sort of passive agressive actually :>)....

>risk) to examine the source address list of INIT-ACK.

Nope, I don't see it.. sorry Brian there are other ways to deal with
this.

In fact I think your weakening of the V-Tag's security is a far far far
greater risk then the scenario you paint above... and even your scenario
can be easily dealt with.. it will require code.. but it can be dealt with..

A simple 'un-trusted' flag could be added to the socket-api to allow one
to declare.. I don't trust this peer HB every address before we converse..
Not counting the corner case you illustrate above which I laid out
a solution that will immediately bring the bogus peer into suspect
even without a 'un-trusted' flag.

One other thing I want to note... before I read your 2.6 issues..

5.2.1 of RFC2960 states:

"5.2.1 INIT received in COOKIE-WAIT or COOKIE-ECHOED State (Item B)

   This usually indicates an initialization collision, i.e., each
   endpoint is attempting, at about the same time, to establish an
   association with the other endpoint.

   Upon receipt of an INIT in the COOKIE-WAIT or COOKIE-ECHOED state, an
   endpoint MUST respond with an INIT ACK using the same parameters it

Stewart, et al.             Standards Track                    [Page 60]

RFC 2960          Stream Control Transmission Protocol      October 2000

   sent in its original INIT chunk (including its Initiation Tag,
   unchanged).  These original parameters are combined with those from
   the newly received INIT chunk.  The endpoint shall also generate a
   State Cookie with the INIT ACK.  The endpoint uses the parameters
   sent in its INIT to calculate the State Cookie.
"

Note the 'MUST respond with an INIT ACK using the same parameters it
sent in it soriginal INIT chunk (including its Initiation Tag,"

Your implementation, at least from your conversations in this
thread, does NOT do this... (in the double multi-homed case aka
the colliding INIT's that Ivan painted)

R

---

From: "Brian F. G. Bidulock" <[email-masked]>
Date: Mon, 10 Mar 2003 20:34:02 -0700

Randall,

> Brian F. G. Bidulock wrote:

[snip]

> >  |INIT A:1000 -> X:1000                          |        |

<XXX>

> >  |COOKIE-ECHO A:1000->X:1000                     |        |

<YYY>

> setup.. so there would be no timer firing.. the user would

Abort which association setup?  TCB2?  Like so?  This is what
Caitlin wanted me to do as well.  This is where the denial of
service to legitimate host C occurs.

     |                                               |        |
     |ABORT A:1000 -> C:1000                         |        |
     |------------------------------------------------------->|

> I dont understand how would you get a cookie-timeout on TCB2?
> I could see a TCB2 t1-timeout.. but TCB2 has never seen the
> INIT-ACK at this point.

TCB2 received the INIT-ACK at <XXX> above.

> TCB1 holds X and D now (if I am following your case correctly)
> and so when the arriving INIT-ACK from 'C' comes in you would
> find TCB1... not 2.. so TCB2 is still in COOKIE-WAIT (not
> COOKIE-ECHOED)..  in our implementation (as I noted above) it
> would be aborted... so the app would know something is up...

TCB1 is in COOKIE-ECHOED state at <YYY> above, it has already
exchanged INIT-ACK and COOKIE-ECHO.

Please take another look at it because it seems you have missed
the INIT-ACK/COOKIE-ECHO exchange for TCB1 above.

>      ask M Tuexen if he could work up the probabilities :>

X can know C's addresses if it can launch an INIT to it and receive an
INIT-ACK.

The probablilies are application specific.  A "general purpose"
stack would ensure that the attack was not possible regardless
of application.

>       but they may not be correct...

RTO.Initial can be read by X with some accuracy.  X just doesn't respond
to an INIT and see how long it takes to get another.

>       very very fine thread.. and a very minimum threat to me. But

X gains denial of service to an arbitrary list of hosts that it
provides in its host address list for the period of time of the
attack.

If I had a click ad web service, I might want to take this
attack on busy proxy servers to block access to ads of all my
competitors.

> D is always the first one that A should HB..

X just reponds to the second INIT instead of the first and no
RTT update is performed on the INIT/INIT-ACK.  X can also read
RTO.Initial from A by waiting for the second INIT.

> the whole thing down.

No, no.  By "bogus" destination I mean either an address
controlled by X that will either return a HEARTBEAT-ACK
or any address that will not return anything (pick some
firewall completely ignoring protocol 132).

> If X never sends anything to A  then X will not even know when
> the association collapses...  A will get the ABORT from the
> first bogus address, kill the assocation.. so then if C is
> re-attempted you end up with that association coming up...

A doesn't get ABORTs from the "bogus" addresses, only from the
"spoofed" addresses.

If X does not SACK any data, it is likely the first address to
receive a HEARTBEAT.  It can use this interval to determine
A's heartbeat interval.  Even though it never sees the ABORT,
from knowledge of A's selection pattern for HEARTBEATS (code
inspection or detection of how A heartbeats the "bogus"
addresses) it can determine with some accuracy when the ABORT
will occur.

> question.... we don't do this but one could quite easily..
> At the point we find the other assocaition and abort your
> "TCB2" it would be a simple step to check its state.. if it is
> not fully formed one could:
> 
> 1) Abort both.

A similar denial of service attack results:  X can now send INIT
after A with spoofed addresses and drop A's initialization
attempt.

> 2) Abort one (this is currently what we do).

Which one?  If you abort one in half the cases, you are wrong.
If you abort the other, in the other half the cases you are
wrong.  And you would end up with an application specific
tradeoff again.

>    thus find out who is who ...

But then you are sending the "extra" COOKIE-ECHO and the
entire determination can be made at receipt of COOKIE-ACK
(different source address lists) and there is no need to
look in the source address list of the INIT or INIT-ACK.

> exact time that it is contacting C or D...

X does not need to guess who is going to contact it.  It can
attack every host that contacts it.

> seems like a good general solution to the issue...

Looking at the sources address list and finding the other TCB
does nothing to help with the situation.  You still do not know
which is the attacker and which is the legitimate host.  The
ordering of the messages is unimportant.

One can only mark them both as suspect.  But as noting can be
done until after receiving COOKIE-ACK for both, and because the
determination of suspect TCB can be made at that time, it is not
necessary to consider the source address list on INIT or
INIT-ACK, the determination can be deferred to when the second
COOKIE-ACK is sent attempting to establish two associations with
overlapping addresses.

In the case that there is no malicious endpoint, only one
COOKIE-ACK will be returned, and there is no need to mark TCBs
suspect.  If the second COOKIE-ACK is returned attempting to
move the overlapping TCB to the ESTABLISHED state.

HEARTBEAT cannot be used as you suppose, because both TCBs
cannot be moved to the ESTABLISHED state (no two associations to
an overlapping set of trasnport address combinations).

When the first COOKIE-ACK is accepted, the TCB must move the the
established state, making it impossible for the second to move
to the established state.  It is still a race between the
attacker and the legtimate user on the COOKIE-ACK.

One could HEARTBEAT the association immediately after receiving
COOKIE-ACK, but the attacker can give an arbitrarily long list
with "bogus" addresses that will pass the HEARTBEAT.  RFC 2960
also does not permit more than one HEARTBEAT per heartbeat
interval (and rightfully so).  If many destinations where sent a
HEARTBEAT immediately there would be a packet multiplication and
the attacker would have another DoS attack by making A send out
more than one HEARTBEAT for each message in the exchange.

Nevertheless sending the COOKIE-ECHO in this case limits the
attack (the COOKIE-ECHO timeout sequence is not possible), so
I don't see that this is an "extra" COOKIE-ECHO as its purpose
is to limit a vulnerability.

> handle it.. I will ask him before I get to deep into coding <3> :-0

Good, I think you follow me now.

In our implementation where the first connect() has addresses
(C,D) and the second has address (X), the attacker can always be
identified and thwarted.

Also, the implementation is not required to allow users to
launch two inits in this fashion.  (For example, I could delay
sending the second INIT until there is no TCB in a state other
than CLOSED or ESTABLISHED for the same local address and port
pair.  Then neither situation can occur, and there is no extra
COOKIE-ECHO and no vulnerability.

This would, of course, mean that there was no need for me to
look in the source address list of the INIT or INIT-ACK.

> And if it is, the steps in <3> above can be used to correct it..

This is because TCP does not have the vulnerability because it
does not naively consider an source address list.  Such servers
running SCTP will be vulnerable.

> perspective.... if so I will code up <3> for our implementation...

The rate of INIT-ACKs sent to a given destination (the source
address in the INIT packet, whether spoofed or not) can easily
be measured and throttled and alarms generated.  Nevertheless
a system can be design so that all an attacker can do is "delay"
the INIT process of legitimate assocations, not deny them.

> I see no reason for this restriction..

I don't either now.  As I say above, the whole situation could
be avoided by delaying sending the second INIT until the first
association enters the CLOSED or ESTABLISHED state.   There is
no requirement in the RFC or IG that tells me when an implementation
must send an INIT, so I can avoid the situation as I like.

> >risk) to examine the source address list of INIT-ACK.

[snip]

> to declare.. I don't trust this peer HB every address before we converse..

Waiting to HB every address would still deny service for the
period of time it takes to HB.

> the colliding INIT's that Ivan painted)

No it doesn't because to do so for an untrusted address (when D
is not provided to connect()) would hand the verification tag in
the initiate tag to the attacker.

When D is provided to connect (as a known and trusted address),
I following this.

This is what 2.6 was intended to fix.  The 2.6 fix, however,
causes association initializations to be unreliable and I think
that there is yet another attack on 2.6 (because 2.6 does not
stop the implementation from taking action on untrusted
addresses from the souce address list).  The only way that I see
to close all the attacks is to not trust the source address list
and take no action on it.  This is what I have done from the
start, ignored the source address list and provided a way for
the user to provide a list of known and trusted addresses to
connect().

I'll work up a DoS attack for 2.6 collision case for you in a
separate mail.  It should be easy.  I will just replace C with
the attacker (the place to which the INIT-ACK will be sent).
Then X will forward the INIT-ACK to the legitimate host spoofed
from A and X will have hijacked at least part of the
association.

--brian

---

From: "Randall Stewart (cisco)" <[email-masked]>
Date: Tue, 11 Mar 2003 06:38:36 -0600

>Randall,

ok, now we change sides again?

>look in the source address list of the INIT or INIT-ACK.
No, you missed my point.. you LOOK in the INIT-ACK and
FIND the other association... ONLY in this case do
you send the Heartbeat.. this way you ONLY send the
"extra" cookie if you get the very scenario you painted.

If the peer gives you completely overlapping addresses
(the legit collision case) you do as you are supposed to
and use the tag that you sent in the INIT... something
your implementation can not do...

This way it is only in this little corner case that one needs to do
anything... And your argument about which addresses to
heartbeat assuming the evil guy supplied you with a
large list of "bogus" addresses.. well you would HB only
the over-lapping ones first.. since these would be standing
out as possible incorrect addresses... so guess what first
HB will be valid or return an ABORT..

And as to your why a web server would do this.. if a proxy
is worried about displaying adds of the competition why even
show them in the first place.. if it is that sophisticated that
it can play in the kernel.. it is far easier to filter the web
sites and other addresses of the competitors at the app
level... and more effective as well..

>attack every host that contacts it.
But only if X can guess which host the client will contact
next... Your http issue does not hold water... and a simple
HB to the conflicting addresses will quickly prove X to
be a problem...

>ordering of the messages is unimportant.
Yes it does since you then can find that the conflict exists.. besides
it does allow one to follow RFC2960 and use the same tag
when you get the true colliding INIT case ...

>COOKIE-ACK is sent attempting to establish two associations with
But you can't reuse the correct I-Tag per RFC2960 without
looking at the INIT's address list...

>an overlapping set of trasnport address combinations).
Take a closer look at the IG.. the peer WILL respond to a HB
since it sent the COOKIE-ACK it is in ESTABLISHED and is
assured of response..

Yes we may need to add another exception.. but I won't go
down that path unless Steve thinks that this case is worth
being concerned about... which quite frankly.. based
on some of my other conversations with him.. I don't
think he will be...

>attacker and the legtimate user on the COOKIE-ACK.
But using HB's it is no longer a race... sorry if this situation
is worth considering I would rather instead of having a race
have a assured mechanism to deal with it...

>more than one HEARTBEAT for each message in the exchange.
But you KNOW up front which addresses are suspect.. the ones
that collide with the other association... so it is quite easy to
HB just the correct address.. no matter if the peer gives you
1000 bogus addresses.. you can quickly know which one is the
overlapping one...

>is to limit a vulnerability.
And leaves things completely up to a "race" which is not
a solution..

>COOKIE-ECHO and no vulnerability.

The nano-second you send the INIT, you can get back an INIT from
the very peer you just sent to.. using one of his alternate addresses
as the source.. you are required by RFC2960 to use the
same tag and send back the INIT-ACK... You need to
look at the address list to do this...  so yes there is a need
to look at the INIT/INIT-ACK address list...

>running SCTP will be vulnerable.
Like I said, we will see if Steve thinks it is an issue.. if so
the HB scenario fixes the problem and eliminates a
"horse race" that is not a solution...

>the INIT process of legitimate assocations, not deny them.
It is still a much easier attack to launch and it can effect any
endpoint.. not just those that happen to be connecting to
you and wish to connect to some else that you predict :-0

>must send an INIT, so I can avoid the situation as I like.
Like I said, the minute you launch an INIT you can get the collision 
scenario..

ahh.. I see you are not attempting to get around your collision scenaro/
violation of the current MUST in RFC2960.. but instead just
this one attack..

That will work but you are doing a trade off .. if I am an evil attacker
"passive/aggressive" server I can delay sending the INIT-ACK until the
last possible retran (has you previously mentioned)... then I can do
the same thing with the cookie ack..

So in the case of a default parmeters case.. I can hold you up for
roughly 16 retransmissions.. blocking your stack from all outgoing
connections during that time... lets see..

(3 + 6 + 12 + 24 + 48 + 60 + 60) * 2 = 426 seconds..

So you can be held for over 7 minutes every time you contact
a "passive/aggressive" server.

Seems like another attack to me... I think the HB of the
collided addresses (suitably apart of course) would
be a better approach.. and solve the problem without
blocking your stack from sending INIT's to legit users...

>period of time it takes to HB.
Ahh, but one only needs to HB the collided addresses.. I don't need
to HB non-overlapping addresses.. once all the collided addresses
are HB'd the impostor will have been found...

>the user to provide a list of known and trusted addresses to

Nope.. I disagree.. assocaition initiation is no more un-reliable than
sending a INIT to a single address... no difference... and as far
as that goes if you want to discuss un-reliable association setup,
I think Ivan as illustrated to you this very case where you do
NOT setup the assocaition.. all it takes is the peer
to send its INIT from an alternate address (from which
you used to send the INIT) and you can't bring up the
association.. with default routing this is a far worse
case.. since your scenario requires something to be unreachable/broken
where Ivan's scenario has everything reachable and available and
you won't bring up an association..

This is far more unreliable in my opinion..

but thats another thread.. the other side of your argument.

R

>the attacker (the place to which the INIT-ACK will be sent).

The very place you sent your first INIT? again contacting an attacker?

>from A and X will have hijacked at least part of the

A man-in-the-middle attack, where the routing infrastructure has
been compromised breaks all security unless you have end2end
encryption aka IPSEC..

R