Subject: RE: Matching addresses in INIT and INIT ACK

From: <[email-masked]>
Date: Fri, 7 Mar 2003 16:51:12 +0200

Brian,

	... snip...

> > > Here the TCB can be found by the destination address and 
> port pair in
> > > the INIT: it is not necessary to look in the source 
> address list of
> > > the INIT when searching for the TCB.
> > 
> > 	??
> > 
> > 	I don't follow you... :-/
> > 
> > 	Port are of course the same, but all what you know 
> about the peer at
> > 	Host A/B is the address C. However, the INIT from Host 
> C/D comes from
> > 	address D... The INIT from Host C/D effectively goes to the same
> > 	endpoint, but seems to come from a different one (if 
> you don't take a
> > 	look inside the address parameters, of course).
> > 
> > 	Take into account that in this example address B 
> belongs now to the
> > 	"left" endpoint...
> 
> The INIT is sent to address B:1000.   There exists a TCB with 
> sport=1000,
> dport=1000 and saddr=B.  It can be found with the port pair 
> and _destination_
> address of the INIT.  You don't need to look at source 
> address at all (far
> less what's in the address list).
> 
> --brian

	I still don't follow you at all... What you can know is that the INIT is sent to the same endpoint, not that it comes from the same endpoint...

	You know it goes there, so what? You don't know where it comes from... D might or might not be part of the same endpoint that also uses C (you don't know unless you take a look to the address parameter)... What if another completely different peer sends an INIT E:1000->B:1000? will you populate the Tie Tags as well? Will you "recognize" it as being part of the association you are about the create?

	I simply don't understand what you are saying... It seems that the sender address doesn't count at all... :-/

	BR Iván Arias Rodríguez

---

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

Ivan,

On Fri, 07 Mar 2003, [email-masked] wrote:

> 
> 	I still don't follow you at all... What you can know is that the INIT
> 	is sent to the same endpoint, not that it comes from the same
> 	endpoint...
> 
> 	You know it goes there, so what? You don't know where it comes from...
> 	D might or might not be part of the same endpoint that also uses C
> 	(you don't know unless you take a look to the address parameter)...
> 	What if another completely different peer sends an INIT
> 	E:1000->B:1000? will you populate the Tie Tags as well? Will you
> 	"recognize" it as being part of the association you are about the
> 	create?

Consider that if a completely different peer sends E:1000->B:1000 and
places C or D in the address list that you will offer the potential
attacker the unprotected vtag of the existing TCB in the cookie.

Also, the INIT from D:1000->B:1000 with (C) in its list is not
necessarily the peer at C:1000.

This is the very reason why I do not check the source address list, just
the source address in the packet: because none of the addresses in the
list are reliable.  Any attacker can put any source address in the list.

This is similar to the hijack situation that 2.6 attempted to solve.
2.6 only addresses the situation where the attacker tries to add its own
address to an existing address list when an established association
exists.  However, the same principle applies to hijacking hosts sending
INITs that foolishly follow 2.18.  Following your HOST A/B and HOST C/D
example, I will add a malicious Host E.

The sequence is as follows (note that Host E TCB's are from HOST A/B's
view as the attacker can mimic whatever they like):

>Host A/B                                                            Host E
>                                                                    
>TCB     \   INIT VT:0 IT:W                      INIT VT:0 IT:X   /  TCB
>A,B:1000 \  A:1000->C:1000                      E:1000->B:1000  /   E,C:1000
>C:1000    \                                     (C in list)    /    B:1000
>VTloc:W    \                                                  /     VTloc:X
>VTpeer:0    \                                                /      VTpeer:0
>C-WAIT       \                                              /       C-WAIT
>              \--------------------\  /--------------------/
>                                    \/
>                                    /\
>                                   /  \                             Host C/D
>   (1)  <-------------------------/    \------------------------->
>
>        \   INIT ACK VT:X IT:Y                                    
>         \  B:1000->E:1000                                      
>          \ VTloc:Y VTpeer:X                                   
>           \TTloc:W TTpeer:0                                  
>            \                                                 
>             \                                               
>              \--------------------\                        
>                                    \ 
>                                     \
>                                      \
>                                       \------------------------->  Host E
>                                              COOKIE ECHO VT:Y   /  TCB
>                                                D:1000->B:1000  /   C,D:1000
>                                              VTloc:Y VTpeer:X /    A,B:1000
>                                              TTloc:W TTpeer:0/     VTloc:X
>                                                             /      VTpeer:Y
>                                                            /       C-ECHOED
>                                      /--------------------/
>                                     /
>                                    / 
>                                   /   
>   (2)  <-------------------------/                                

>TCB                                                                    
>A,B:1000                                                                    
>E,C:1000                                                                    
>VTloc:W                                                                     
>VTpeer:X                                                                    
>ESTABLISHED

At (1) by checking the source address list, Host A/B gives up the VT of
the TCB to the attacker.

At (2), if attacking Host E can return a COOKIE-ECHO before valid Host
C/D returns an INIT-ACK, E will be installed in the TCB and will have
hijacked the association by spoofing C in the address list.

Certainly after (1), the attacker has the VT of the existing TCB and can
easily wreak havoc with that (ABORT, HEARTBEAT-ACK, SHUTDOWN, etc.).

If the attacker can turn around the COOKIE-ECHO fast enough (because it
is "closer" than C/D or just because C/D is already heavily loaded,
perhaps with bogus INITs from Host E or another attacking host), then it
can easily hijack the association.

After hijacking the association, either Host A/B does not support ADD-IP
on the association, in which case the hijacker could have up to 30
seconds before C gets a HEARTBEAT, or, if Host A/B supports ADD-IP and
the first action from E is to delete IP C.  Another technique would be
to get a new cookie and keep restarting the association before C gets a
HEARTBEAT.  At any rate, Host E has from 60 seconds to forever to
pretend to be Host A/B.  30 seconds is a long time.

For some period, the ULP at Host A/B believes that it is communicating
with Host C/D but is in fact communicating with Host E.  This is very
bad.

So how does Host A/B distinguish between this:

>Host A/B                                                            Host E
>                                                                    
>TCB     \   INIT VT:0 IT:W                      INIT VT:0 IT:X   /  TCB
>A,B:1000 \  A:1000->C:1000                      E:1000->B:1000  /   E,C:1000
>C:1000    \                                     (C in list)    /    B:1000
>VTloc:W    \                                                  /     VTloc:X
>VTpeer:0    \                                                /      VTpeer:0
>C-WAIT       \                                              /       C-WAIT
>              \--------------------\  /--------------------/
>                                    \/
>                                    /\
>                                   /  \                             Host C/D
>   (1)  <-------------------------/    \------------------------->

And this:

>Host A/B                                                            Host C/D
>                                                                    
>TCB     \   INIT VT:0 IT:W                      INIT VT:0 IT:X   /  TCB
>A,B:1000 \  A:1000->C:1000                      D:1000->B:1000  /   C,D:1000
>C:1000    \                                     (C in list)    /    B:1000
>VTloc:W    \                                                  /     VTloc:X
>VTpeer:0    \                                                /      VTpeer:0
>C-WAIT       \                                              /       C-WAIT
>              \--------------------\  /--------------------/
>                                    \/
>                                    /\
>                                   /  \
>   (1)  <-------------------------/    \------------------------->

Without prior knowledge of address D it cannot distinguish between the
two.

Note that although forming a proper association here requires static
port assignment on both sides, that is not true for the attack.  Knowing
the well-known server port on one side an the normal client dynamic port
assignment range on the other, it is quite easy to attack a large number
of clients simultaneously.  The IP address I would spoof in my source
address list would be the IP address and port of your on-line banking
server, and I would send INITs repeatedly to the low end of your dynamic
port range, and wait for you to give me your cookie in the INIT-ACK with
tie-tags populated.  Then, presto!, for 30 seconds I'm your bank.

The current STREAMS OpenSS7 implementation does not consider the source
address list and only uses packet header information (direct opposite of
2.18) and will not surrender the VT of the current association to D or
E, but will populate tie tags with zero as you originally showed, if the
connect() at Host A/B was only provided with C.

If the connect() at Host A/B was provided with (C,D), the valid
association will form and the attacker E cannot form an association (the
INIT-ACK to E will have zero tie-tags).

Note that in your previous example, populating tie tags just because B
is in the address list opens the same vulnerability.  The OpenSS7
implementation sends an INIT-ACK with zero tie tags and the association
still forms.

Also, in the 2.6 scenario, the OpenSS7 implementation populates the tie
tag with zero because the attacker's IP address does not match the TCB,
and again the attacker is thwarted while in more circumstances than
2.6's prescription the legitimate restarting node can add IP addresses
(as long as it is not the primary which is added, or the restarting node
tries INITs to other addresses as well).

Caitlin's examples involved the INIT-ACK, which can always be looked up
on VT if the sender of the INIT constrains its VT assignment to be
unique.

I don't see that I'm doing the wrong thing here in refusing to form
associations with INITs sent from an unknown source address claiming to
have the correct source address list.

Am I not justified in the conclusion here is that one should not
consider the source address list when searching for a matching TCB for
received INIT messages?  Not considering them closes these two
vulnerabilities and yet even your last example can form an association
if the ULP provides the addresses of the peer (C/D) to the connect() or
t_connect() or the simple arrangement is made to INIT to the primary.
IMO the right thing to do is to close the vulnerability for all
associations at very minor expense of this one unnecessary corner case.
(I say unnecessary because it is simple to configure Host A/B to INIT to
A->C and Host C/D to INIT to C->A, or provide C/D to connect().)

Following 2.18 opens up the vulnerability above and the vulnerability
yet to be properly addressed by 2.6.  Not following 2.18 closes both
vulnerabilities.

As this is the last example to be addressed, could you tell me again why
I should consider the source address list when searching for a matching
TCB on INIT and INIT-ACK?

--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: "Randall Stewart (cisco)" <[email-masked]>
Date: Sat, 08 Mar 2003 09:32:00 -0600

>attacker the unprotected vtag of the existing TCB in the cookie.
You are not addressing Ivan's point.. He was pointing out to you
that you must be able to distinguish the collision case from the
non-collision.. You also make the assumption that the attacker
knows that you are attempting at that very moment to setup
an association with C /D. This it does not know.. and would
not even realize is the V-Tag for your forming association.. what
the attacker would be more likely to be attempting is to camp
on addresses (as I just noted to you in my other email)...

>list are reliable.  Any attacker can put any source address in the list.
But in the end you must go through this same list in the COOKIE-ECHO..
and here if some attacker is placing some other peers addresses  in the
list you end up at the same point.. an association that is camping on
another's addresses... same result...

>example, I will add a malicious Host E.

I think the right fix for 2.6 is to remove the error cause.. and now you
just get an abort.. this does not share information and you can get
such an abort for a non-listening port...

As to your statement above.. it is far far easier for the attacker to 
just camp
on addresses.. in fact in the collision scenario you paint assuming that the
hijacker magically knows you have sent an INIT out and in the small
1-50ms window can get an INIT back that happens to have the very
addresses you put in the outing INIT's .. very very far-fetched ..

But lets consider your sequence below...

>>C:1000    \                                     (C in list)    /    B:1000
And now what is different in this case with the scenario that is painted
if you subtract out your sending the INIT? Nothing.. you think
you have an association to C/D and X.. and you don't..

And more so, since the INIT-ACK/COOKIE-ECHO happens faster
with the attacker.. even your solution brings up the association
with the attacker.. until the first HB to C/D goes out..

In fact this is just one possibility you also have:

Host A/B                                                            Host E
                                                                   
TCB     \   INIT VT:0 IT:W                      INIT VT:0 IT:X   /  TCB
A,B:1000 \  A:1000->C:1000                      E:1000->B:1000  /   E,C:1000
C:1000    \                                     (C in list)    /    B:1000
VTloc:W    \                                                  /     VTloc:X
VTpeer:0    \                                                /      VTpeer:0
C-WAIT       \                                              /       C-WAIT
             \--------------------\  /--------------------/
                                   \/
                                   /\
                                  /  \                             Host C/D
       <-------------------------/    \------------------------->
                                                                / 
       \   INIT ACK VT:X IT:Y                                  /  
        \  B:1000->E:1000                                     /   
         \ VTloc:Y VTpeer:X                  INIT-ACK        /          
          \TTloc:W TTpeer:0                  VT:W IT:Q      /          
           \                                               /   
            \                                             /  
             \--------------------\                      /   
       (1)  <-------------------------------------------/
                                    \
                                     \
                                      \------------------------->  Host E
                                             COOKIE ECHO VT:Y   /  TCB
                                               D:1000->B:1000  /   C,D:1000
                                             VTloc:Y VTpeer:X /    A,B:1000
                                             TTloc:W TTpeer:0/     VTloc:X
                                                            /      VTpeer:Y
                                                           /       C-ECHOED
                                     /--------------------/
                                    /
                                   / 
                                  /   
   X   <-------------------------/                                

A far more likely scenario, since the attacker must make 1.5 RTT to
the 1 RTT (minus the time between sending the INIT and the evil
attackers INIT arrives).

In the above scenario, by checking the address list, finding the TCB
has been updated a second time, but now with less addresses, the
sender of the INIT can then pick a new IT, reseting it because it
realizes  something is up i.e. the address list changed between one INIT-ACK
and the INIT that came in.. and then send a NEW INIT with this new tag, get
a second response from the real peer and of course the Cookie-Echo
from the attacker will be thrown away..

Now of course if you don't check the addresses, you blindly start
a new association and  so when the evil attackers COOKIE-ECHO
arrives after sending the second cookie (not shown) you accept
the association with the evil attacker.. where if you had
checked the address list you would not have.. instead
you would send a new INIT with new vtag...

I think the above scenario I have illustrated is far
more likely (due to RTT times)... but in your illustrated
scenario.. it matters not if you check the address list
or not.. if the attacker can get a INIT/COOKIE-ECHO
to you before the INIT-ACK from the real peer comes
back you will establish an association with the bad
guy....

>At (1) by checking the source address list, Host A/B gives up the VT of
No by checking the address list the peer can make the connection that
I have shown above and send a new INIT to the valid peer so the
attacker is foiled.. in your illustrated scenario it makes no difference
if you check the address list or not.. you still bring up the
association...

>hijacked the association by spoofing C in the address list.
As I said above.. it does not really matter, if the COOKIE-ECHO beats
your peers INIT-ACK back then your implementation would bring up the
evil association the same as if you checked the address list.. Only thing
checking the address list can do is help you in the far more likely
scenario that I have painted above...

>easily wreak havoc with that (ABORT, HEARTBEAT-ACK, SHUTDOWN, etc.).
What existing TCB.. this is a forming association.. if it was a
existing TCB it would get an ABORT() (aka 2.6 of the IG which
as I said will loose the error cause)...

If you have not yet formed an association your not checking the
INIT/INIT-ACK is not going to change the outcome of the
above scenario.. you end up in the same place... an association to
E that includes addresses to C/D..

>can easily hijack the association.
Look at your scenario.. if the attacker, with this ability to hit this 
limited
window, is that close.. it will not matter if you check the addresses
up front or not.. before the real INIT-ACK comes back you have
formed an association with E.. in your case or in what everyone
else does... this is not a hijack by the way.. a hijack is when you
have an existing association.. there is none here.. if there were
a ABORT would have been sent...

>pretend to be Host A/B.  30 seconds is a long time.
And how is the scenario different with your implementation.. its not..
if the attacker can get the message exchange done ahead of the
real peer.. you end up in the same place..

And has to the Add-IP there will be some changes coming that Michael
and I are working on.. probably a seperate draft.. but something that
can be done...

>port assignment on both sides, that is not true for the attack.  Knowing
No, static port assignments are NOT required.. there are other methods
that dynamic ports can be used.. RSERPOOL is an example of this...

>tie-tags populated.  Then, presto!, for 30 seconds I'm your bank.
If I am talking to my bank I don't think I would be using clear-text 
type conversations
and I fail to see how you have illustrated anything that won't fall onto 
your
implementation as well.. I , the attacker turn the COOKIE-ECHO around
as you have painted fast enough.. guess what.. you think I am your
bank as well.. sorry your method of waiting until you see the COOKIE-ECHO
is not going to help you at all..

>connect() at Host A/B was only provided with C.

And as you illustrate when E turns the INIT-ACK and COOKIE-ACK around
faster than C, your implementation will have you speaking to the
attacker as well..  

And whats this about a current assocation? There IS NOT a current
assocaition... If there was you give E an ABORT if of course you
check the address list..

>INIT-ACK to E will have zero tie-tags).
Ahh, your argument then is for full pre-knowledge of all addresses...
This is a different argument and as I said it is non-general purpose...

>implementation sends an INIT-ACK with zero tie tags and the association
The point is you will NOT form an association to valid users.. this is
what we have demonstrated to you ...

The weaknesses you lay out are there in your implementation when
a full peer address list is not present... I see no difference

>yet to be properly addressed by 2.6.  Not following 2.18 closes both
The vulnerability you illustrate is in both cases.. and has
nothing to do with checking addresses..

>TCB on INIT and INIT-ACK?
So, what can we learn from all of this discussion:

1) Checking the addresses does not change the outcome if the
    evil attacker can turn things around fast as in your illustration

2) Checking addresses WILL allow you to catch the more likely
    case that the valid peers INIT-ACK arrives after the hackers
    INIT..  

 2a) One should check if the INIT-ACK comes back with different
        addresses and then restart the INIT process with a new
         Tag...

3) Not checking addresses will lead to bringing up the association
    with the hacker.

4) Not checking the addresses will reduce the protection in the V-Tag (as
    we discussed previously)

5) If one is worried about the "fast" hacker (your illustration above), 
then
    the only way to avoid it is to either:
     a) Have a pre-listing of all valid address for the peer.
     <or>
     b) Require a HB to each of the peers listed addresses before
         allowing data to flow..
   
   Note: I think either a or b is a bit restrictive, but thats ok if one
   is worried about this scenario one can put these requirements in.

6) NOT checking addresses will lead to a scenario (as illustrated by 
Ivan) where
    a valid association cannot be started.

7) NOT checking addresses will lead as Caitlin as shown to an excess 
message.

You have pretty much convinced me we really need to require that addresses
be confirmed... Vtag hash lookups are ok, but addresses will need to be
validated as well since without it they weaken security in at least 2 
different
ways (the vtag is weaker and the more common scenario I illustrated can
 not be prevented).  We may even want to add a note in the IG stating that
a endpoint MAY wish to heartbeat every listed address if it feels it
cannot trust the peer.. wordsmitthing required a lot of course...

R

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