[UNIX] IPv4 Forwarding Doesn't Consult Inbound SPD in KAME-derived IPSec

From: support@securiteam.com
Date: 03/11/02


From: support@securiteam.com
To: list@securiteam.com
Date: Mon, 11 Mar 2002 23:29:51 +0100 (CET)

The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

When was the last time you checked your server's security?
How about a monthly report?
http://www.AutomatedScanning.com - Know that you're safe.
- - - - - - - - -

  IPv4 Forwarding Doesn't Consult Inbound SPD in KAME-derived IPSec
------------------------------------------------------------------------

SUMMARY

NetBSD 1.5.2 and -current, FreeBSD 4.5 and -current, and the KAME versions
of NetBSD and FreeBSD fail to perform inbound policy checks on packets
which are forwarded, in violation of RFC2401 sections 4.4.1 and 5.2.1
(steps 3 and 4). NetBSD, FreeBSD, and KAME have already committed changes
to address this problem.

The typical case where one might care is at a Security Gateway where
packets from a peer gateway are required to be ESP in order to provide
confidentiality and integrity. If the SG peer fails to use ESP,
confidentiality is lost. If the local SG follows RFC2401 and performs
inbound SPD checking, the packet will be determined to require ESP and be
dropped. However, with the present code, no SPD check is performed, and
the packets - possibly forged - will be forwarded, presumably to hosts
relying on the SG.

DETAILS

The defect was observed in attempting to control network access from an
802.11 LAN by requiring tunnel-mode ESP of all traffic from the wireless
host, with tunnel endpoints of the host and an SG with a wired interface
and an 802.11 interface. We observed that non-ESP packets (emitted due to
configuration errors) were forwarded by the SG; this is a real failure
that caused a security policy to be violated, although in a situation with
no adverse consequences. The policy called for ESP for confidentiality
over 802.11 and access control to the wired network and resulting Internet
connection. With the defect, an attacker could have injected packets into
the Internet, but not received packets because the outbound SPD check on
the SG functioned correctly.

Examine src/sys/netinet/ip_input.c, and follow the code from the call to
ip_forward(). Note that inbound SPD check is done only for packets for
this host, and only for protocols with PR_LASTHDR; the check is deferred
to protocol implementation to enable per-socket policy.

Patches that fix (at least in the normal case) the problem for IPv4 are
enclosed for fairly recent points along NetBSD's netbsd-1-5 branch and
FreeBSD's RELENG_4 branch. The KAME versions of ip_input.c are very
similar. These patches are probably not sufficient; the check should
probably be in ip_forward (aligned with the IPv6 implementation). A more
careful analysis is needed to consider all the code paths; we have not
considered interaction of inbound SPD checks with tunneling (e.g. gif) and
other features. In particular, forwarding of packets via source routing
options seems to be handled incorrectly.

Other systems:
FreeBSD RELENG_4 and NetBSD netbsd-1-5 appear to perform this check for
IPv6 in ip6_forward; KAME has had the relevant code since 1999-09-01.

OpenBSD began to perform this check as of revision 1.58 of
src/sys/netinet/in_input.c on 2000-09-01; we have not tested OpenBSD.

Technical Details:
We give details for a simple setup with Alice and bob on two networks
connected by two SGs alice-gw and bob-gw, nominally intended to use
tunnel-mode ESP for all traffic between the networks. (We present results
from an actual experiment, but with the IP addresses obscured and
irrelevant traffic removed.)

10.1.1.48/28 is Alice's network, and 10.1.1.64/28 is Bob's (both red).
10.1.1.32/28 is the black network connecting Alice (.34) and Bob (.35).

alice-gw SPD

  # to/from bob
  spdadd 10.1.1.48/28[any] 10.1.1.64/28[any] any
  -P out ipsec esp/tunnel/10.1.1.34-10.1.1.35/require ;
  spdadd 10.1.1.64/28[any] 10.1.1.48/28[any] any
  -P in ipsec esp/tunnel/10.1.1.35-10.1.1.34/require ;

bob-gw SPD

  # to/from alice
  # intentional misconfiguration for testing - no ESP to alice
  spdadd 10.1.1.64/28[any] 10.1.1.48/28[any] any -P out none ;
  #spdadd 10.1.1.64/28[any] 10.1.1.48/28[any] any
  # -P out ipsec esp/tunnel/10.1.1.35-10.1.1.34/require ;
  spdadd 10.1.1.48/28[any] 10.1.1.64/28[any] any -P in ipsec
esp/tunnel/10.1.1.34-10.1.1.35/require ;

Example with the incorrect code:
With NetBSD along netbsd-1-5 as of 2001-11-26, examining the black network
at alice-gw, we see a clear text SYN, followed by alice-gw initiating IKE
due to the response from Alice, followed by a retransmitted SYN and the
reset in ESP:

09:44:45.258912 bob.65514 > alice.8001: S 406012389:406012389(0) win 16384
<mss 1460,nop,wscale 0,nop,nop,timestamp 2214891 0>
09:44:45.260843 alice-gw.isakmp > bob-gw.isakmp: isakmp: phase 1 I ident:
(sa: doi=ipsec situation=identity (p: #1 protoid=isakmp transform=1 (t: #1
id=ike (type=lifetype value=sec)(type=lifeduration value=0258)(type=enc
value=3des)(type=auth value=rsa sig)(type=hash value=sha1)(type=group desc
value=modp1024))))
09:44:45.262261 bob-gw.isakmp > alice-gw.isakmp: isakmp: phase 1 R ident:
(sa: doi=ipsec situation=identity (p: #1 protoid=isakmp transform=1 (t: #1
id=ike (type=lifetype value=sec)(type=lifeduration value=0258)(type=enc
value=3des)(type=auth value=rsa sig)(type=hash value=sha1)(type=group desc
value=modp1024)))) (vid: len=16)
09:44:45.345226 alice-gw.isakmp > bob-gw.isakmp: isakmp: phase 1 I ident:
(ke: key len=128) (nonce: n len=16) (vid: len=16)
09:44:45.426774 bob-gw.isakmp > alice-gw.isakmp: isakmp: phase 1 R ident:
(ke: key len=128) (nonce: n len=16) (vid: len=16) (cr: len=1
type=x509sign)
09:44:45.545348 alice-gw.isakmp > bob-gw.isakmp: isakmp: phase 1 I
ident[E]: [|id]
09:44:45.576906 bob-gw.isakmp > alice-gw.isakmp: isakmp: phase 1 R
ident[E]: [|id]
09:44:45.577171 bob-gw.isakmp > alice-gw.isakmp: isakmp: phase 2/others R
inf[E]: [|hash]
09:44:45.582749 alice-gw.isakmp > bob-gw.isakmp: isakmp: phase 2/others I
inf[E]: [|hash]
09:44:46.588822 alice-gw.isakmp > bob-gw.isakmp: isakmp: phase 2/others I
oakley-quick[E]: [|hash]
09:44:46.590693 bob-gw.isakmp > alice-gw.isakmp: isakmp: phase 2/others R
oakley-quick[E]: [|hash]
09:44:46.591449 alice-gw.isakmp > bob-gw.isakmp: isakmp: phase 2/others I
oakley-quick[E]: [|hash]
09:44:51.217057 bob.65514 > alice.8001: S 406012389:406012389(0) win 16384
<mss 1460,nop,wscale 0,nop,nop,timestamp 2214902 0>
09:44:51.217686 alice-gw > bob-gw: ESP(spi=29712172,seq=0x1)

On the Alice red network we see the SYNs and the response (a TCP reset):

09:44:45.258949 bob.65514 > alice.8001: S 406012389:406012389(0) win 16384
<mss 1460,nop,wscale 0,nop,nop,timestamp 2214891 0>
09:44:45.259415 alice.8001 > bob.65514: R 0:0(0) ack 406012390 win 0
09:44:51.217090 bob.65514 > alice.8001: S 406012389:406012389(0) win 16384
<mss 1460,nop,wscale 0,nop,nop,timestamp 2214902 0>
09:44:51.217540 alice.8001 > bob.65514: R 0:0(0) ack 1 win 0

Example with the modified code:
Here we see the black network observed at alice-gw. One NTP exchange has
been left in, since otherwise the red tcpdump would be empty. (The
security policy does not require the observed NTP traffic to be in ESP.)

09:58:25.886014 bob.65513 > alice.8001: S 2189637913:2189637913(0) win
16384 <mss 1460,nop,wscale 0,nop,nop,timestamp 2216532 0>
09:58:31.664971 bob.65513 > alice.8001: S 2189637913:2189637913(0) win
16384 <mss 1460,nop,wscale 0,nop,nop,timestamp 2216543 0>
09:58:43.664091 bob.65513 > alice.8001: S 2189637913:2189637913(0) win
16384 <mss 1460,nop,wscale 0,nop,nop,timestamp 2216567 0>
10:00:06.991381 alice.ntp > tai.ntp: v4 client strat 3 poll 6 prec -17
[tos 0x10]
10:00:06.991559 tai.ntp > alice.ntp: v4 server strat 3 poll 6 prec -18
[tos 0x10]
09:59:07.662368 bob.65513 > alice.8001: S 2189637913:2189637913(0) win
16384 <mss 1460,nop,wscale 0,nop,nop,timestamp 2216615 0>

Here we see the red network observed at alice-gw:
10:00:06.991356 alice.ntp > tai.ntp: v4 client strat 3 poll 6 prec -17
[tos 0x10]
10:00:06.991579 tai.ntp > alice.ntp: v4 server strat 3 poll 6 prec -18
[tos 0x10]

With the modified code, we captured output of "netstat -p ipsec -s" on
alice-gw immediately before and immediately after sending TCP SYNs.

  ipsec:
  0 inbound packets processed successfully
  0 inbound packets violated process security policy
  0 inbound packets with no SA available
  0 invalid inbound packets
  0 inbound packets failed due to insufficient memory
  0 inbound packets failed getting SPI
  0 inbound packets failed on AH replay check
  0 inbound packets failed on ESP replay check
  0 inbound packets considered authentic
  0 inbound packets failed on authentication
  0 outbound packets processed successfully
  0 outbound packets violated process security policy
  0 outbound packets with no SA available
  0 invalid outbound packets
  0 outbound packets failed due to insufficient memory
  0 outbound packets with no route

  ipsec:
  0 inbound packets processed successfully
  4 inbound packets violated process security policy
  0 inbound packets with no SA available
  0 invalid inbound packets
  0 inbound packets failed due to insufficient memory
  0 inbound packets failed getting SPI
  0 inbound packets failed on AH replay check
  0 inbound packets failed on ESP replay check
  0 inbound packets considered authentic
  0 inbound packets failed on authentication
  0 outbound packets processed successfully
  0 outbound packets violated process security policy
  0 outbound packets with no SA available
  0 invalid outbound packets
  0 outbound packets failed due to insufficient memory
  0 outbound packets with no route

Modifications
For NetBSD netbsd-1-5:
Index: src/sys/netinet/ip_input.c
===================================================================
RCS file: /NETBSD-CVS/netbsd/src/sys/netinet/ip_input.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ip_input.c
--- src/sys/netinet/ip_input.c 2001/07/05 14:42:54 1.1.1.1
+++ src/sys/netinet/ip_input.c 2002/02/25 01:07:02
@@ -611,6 +611,15 @@
  ipstat.ips_cantforward++;
  m_freem(m);
  } else {
+#ifdef IPSEC
+ /*
+ * Enforce inbound IPsec SPD.
+ */
+ if (ipsec4_in_reject(m, NULL)) {
+ ipsecstat.in_polvio++;
+ goto bad;
+ }
+#endif
  /*
  * If ip_dst matched any of my address on !IFF_UP interface,
  * and there's no IFF_UP interface that matches ip_dst,

For FreeBSD RELENG_4:
Index: src/sys/netinet/ip_input.c
===================================================================
RCS file: /FREEBSD-CVS/src/sys/netinet/ip_input.c,v
retrieving revision 1.130.2.31
diff -u -r1.130.2.31 ip_input.c
--- src/sys/netinet/ip_input.c 2001/12/15 01:06:27 1.130.2.31
+++ src/sys/netinet/ip_input.c 2002/02/24 16:10:26
@@ -625,8 +625,18 @@
  if (ipforwarding == 0) {
  ipstat.ips_cantforward++;
  m_freem(m);
- } else
+ } else {
+#ifdef IPSEC
+ /*
+ * Enforce inbound IPsec SPD.
+ */
+ if (ipsec4_in_reject(m, NULL)) {
+ ipsecstat.in_polvio++;
+ goto bad;
+ }
+#endif /* IPSEC */
  ip_forward(m, 0);
+ }
 #ifdef IPFIREWALL_FORWARD
  ip_fw_fwd_addr = NULL;
 #endif

Vendor status:
This advisory was provided to KAME, NetBSD and FreeBSD before public
posting. Our modifications above, or the equivalent, have already been
incorporated into sys/netinet/ip_input.c in KAME's CVS repository (for
NetBSD, 1.37 and for FreeBSD-4, 1.33), NetBSD -current (1.145) and
1.5-stable (1.114.4.8), and FreeBSD -current (1.192) and -stable
(1.130.2.35).

ADDITIONAL INFORMATION

The information has been provided by <mailto:gdt@ir.bbn.com> Greg Troxel.

========================================

This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

====================
====================

DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.



Relevant Pages

  • Re: configuring IPsec without IKE -problems
    ... Watch your manual keys. ... authkey 123456780123456789abcdeffedcba9876543210 ... # for outbound packets ...
    (comp.unix.solaris)
  • Reading outbound packets to datalink layer using C sockets API - how?
    ... I've recently written a packet dump program that logs all the inbound packets ... to my server using a socket created using the following call: ... This works fine but my problem is that this socket only receives packets ...
    (comp.os.linux.networking)
  • Re: IPsec - locking down Windows 2003
    ... Therefore, yes, I do not need to mirror the blocking ... of inbound packets. ...
    (microsoft.public.windows.server.security)
  • Re: Political Analysis of Security Products
    ... > bee collected nor has any evidence of such a backdoor ever really been ... send several packets to ports on the target system. ... be used for booth sides of the security game. ...
    (Pen-Test)
  • Re: Network hardware IPS
    ... Setting up a complete security with all the currently available tools ... snort_inline uses libipq to queue the packets to user space. ... >Captus Networks IPS 4000 ...
    (Focus-IDS)