Re: Issue 60: Addresses in IKE_SA_INIT/AUTH (was: Comments of draft-ietf-mobike-protocol-04.txt)

Tero Kivinen <[email protected]> Thu, 20 Oct 2005 13:23:58 +0300
Newsgroups gmane.ietf.mobike
Message-ID <[email protected]>
[email protected] writes:
> Tero Kivinen wrote:
> 
> > 2)
> >
> > In section 4.2 we should always take the IP-addresses from the
> > IKE_AUTH request, as there might be multiple IKE_SA_INIT request,
> > and some of those might not create state at all (cookie,
> > invalid_ke_payload). I think it would be simplier to say that the
> > IP-addresses are always taken from the IP header of the IKE_AUTH
> > packet having SA payload (regardless of the NAT-T or no NAT-T).
> >
> > In normal IKEv2 this does not matter, as if no NAT-T is used then
> > the IP address must stay same, and if NAT-T is used then we take the
> > last packet seen and use the IP-addresses from there. In Mobike we
> > do need to define the exact time what IP-address is used, and I
> > think the packet having the ADDITIONAL_*_ADDRESSES would be the most
> > logical choise (i.e. the IKE_AUTH packet having the SA payload).
> 
> There's a reason why I wrote it that way: when not doing NAT-T, 
> the address should be taken from the same packet which contains
> NO_NATS_ALLOWED. And it seems that putting NO_NATS_ALLOWED in
> IKE_SA_INIT is simpler than IKE_AUTH; see below on this...

That reason is not explained anywhere, thus it is very hard to
understand why it is done that way (i.e. why do we have more
complicated processing here). 

> 
> > The section 4.8 says that NO_NATS_ALLOWED should be put to the
> > IKE_SA_INIT (among other things), but we do want to keep IKE_SA_INIT
> > as small as possible, so I think IKE_AUTH is much better place for
> > that notify. That would also be in sync with my proposed change to
> > the 4.2 where I proposed to say that use the IKE_AUTH packet having
> > SA payload to get the IP address tobe used. NO_NATS_ALLOWED is not
> > needed in the IKE_SA_INIT like NAT_DETECTION_*_IP notifies are, as
> > they do not cause changing of the port numbers for the IKE_AUTH.
> 
> NO_NATS_ALLOWED takes less space than NAT_DETECTION_*_IP payloads,
> so IMHO it's not unreasonable to put it in IKE_SA_INIT.

True, not unreasonable, but I still unnecessary to put them there.

> The real reason to put NO_NATS_ALLOWED in IKE_SA_INIT is that it's
> much simpler to retry the request if we get UNEXPECTED_NAT_DETECTED
> error back. In particular, this text from Section 4.8 would need major
> revision if we take the address from IKE_AUTH:

I do not think there is any difference in the complexity of the retry
even if the NO_NATS_ALLOWED is in the IKE_AUTH, you simply delete half
created IKE SA and start over (from the IKE_SA_INIT) when you get
error in both cases. There will be performance penalty, as we need to
do Diffie-Hellman again, but on the other hand we do not need to add
another test matrix case to test the checking that we take the IP
addresses in IKE_AUTH for NAT-T and from IKE_SA_INIT for non-NAT-T
case. 

The question simply is whether this is felt like being important
enough to have performance optimizations when trying to revert this
attack, and costing more in the code complexity and testing time.
Note, that the whole idea of retrying is something that does not
really make attack that much harder especially in the initial contact
step. If someone can modify one packet he can usually modify all the
packets. Also moving them to IKE_AUTH does make the attack a bit
harder, as now the attacker must be able to get the return packets and
forward them to the real destination.

If we know there was no NAT between us in the first place, then it is
quite safe to assume that such thing does not appear on the path
suddenly, thus retrying is ok for the existing IKE SA (i.e. for the
INFORMATIONAL exchanges).

If the initial contact seems to have NAT between, then it is must
likely going to be real NAT, thus retrying by protocol is not really
useful. We could simply say that the IKE SA initiation fails in that
case, and then when the next trigger packets comes in (or user retries
by pressing "connect" again) we retry the exchange from the beginning
again.

>    If the exchange initiator receives an UNEXPECTED_NAT_DETECTION
>    notification in response to its request, it SHOULD retry the
>    operation several times using new IKE_SA_INIT/INFORMATIONAL requests.
>    This ensures that an attacker who is able to modify only a single
>    packet does not unnecessarily cause a path to remain unused.

The change needed would be something like:

    If the exchange initiator receives an UNEXPECTED_NAT_DETECTION
    notification in response to its INFORMATIONAL request, it SHOULD
    retry the operation several times using new INFORMATIONAL
    requests. This ensures that an attacker who is able to modify only
    a single packet does not unnecessarily cause a path to remain
    unused. If initiator receives UNEXPECTED_NAT_DETECTION during IKE
    SA creation (i.e. in IKE_AUTH state), then it should abort the IKE
    SA creation, and retry it later when it gets next trigger for that
    connection.

>From the code point of view, that retry does not need any new code,
simply fail the IKE SA and other parts of the code will already take
care of the retry.

Actually sending UNEXPECTED_NAT_DETECTION during IKE SA creation is
quite useless, as it cannot be authenticated, and also if the
initiator wants to ignore those error notifications and continue
retrying regardless of them. So why do we send those notifies in the
first place? Only benefit they will give is to inform the initiator
that there was attacker between him and the responder. There is
really nothing initiator can do for that, except retry. If his policy
does not allow NATs between, then he will not enable NAT-T even when
there would be NAT between, thus he will be just out of connectivity.

> > Also moving that NOFITY to the encrypted IKE_AUTH packet will
> > prevent passive attackers of getting the information about the IP
> > addresses and ports used in case host behind NAT is configured to
> > try first with NO_NATS_ALLOWED before falling back and enabling
> > NAT-T. It will also make the attacker acting as a NAT between two
> > hosts bit harder, as if it is sent inside the IKE_SA_INIT, attacker
> > can simply flip a bit inside the NO_NATS_ALLOWED payload to cause
> > DoS, otherwise he need to flip bit in the IP-address or ports, which
> > requires it to catch the return packet and forward it to the
> > original requestor to cause attack. It is not much, but offers again
> > a bit more protection against attacks.
> 
> A host that is worried about an attack as obscure as this is IMHO
> unlikely to have a policy "first try without NAT-T; but if there's 
> a NAT, enable NAT-T".

I agree that the revealing of the IP addresses is not very serious
case, but there are people who consider that unacceptable (that is why
the NAT-T uses hashes, as people did consider leaking the IP-addresses
a problem). If we leak them again here, there needs to be at least
security considerations section explaining the issue, and also explain
why we require them to be sent in clear when they could also be sent
as encrypted (i.e. hidden from passive attackers).

> Furthermore, moving the payload doesn't actually prevent anything.
> If there's no NAT, the addresses are visible in the IP header.
> If there is a NAT, and the host behind NAT falls back to NAT-T, 
> the eavesdropper can get the addresses anyway with a quite trivial 
> amount of computation (as is already pointed out in the IKEv2 spec,
> hashing does not prevent NAT detection payloads from leaking the 
> internal addresses).

True, that is mentioned in the IKEv2 spec, and its implications are
explained there. We are now adding another case, so we need to explain
it in the security considerations section. There is nothing about
NO_NATS_ALLOWED in the security considerations now.

Hmm... I got completely new idea, dont know if it is good or bad, but
how about adding the flag in the IKE generic header flags field to tell
that include IP-addresses and ports to the MAC. Then we wouldn't need
to send those IP-addresses/ports at all, and the responder would
simply ignore all packets having wrong MAC (i.e. modified IP-addresses
or ports).

Either end could put that bit in case they want to make sure the
IP-addresses are protected (i.e when they would send NO_NATS_ALLOWED).
Hmm.. the problem with that is that it is not backward compatible,
i.e. if the other end does not support MOBIKE, then he do not know
about flag, thus will not be able to calculate the MAC correctly.

So ignore that suggestion (this would probably have been the way to do
it if we would still be modifying IKEv2 draft).
-- 
[email protected]