[LWN Logo]

Date:         Mon, 27 Mar 2000 23:31:41 -0600
From: H D Moore <hdm@SECUREAUSTIN.COM>
Subject:      Security Problems with Linux 2.2.x IP Masquerading
To: BUGTRAQ@SECURITYFOCUS.COM

[ Security Problems with Linux 2.2.x IP Masquerading ]



Summary:

Due to lax checking in the masquerading kernel code, an attacker is able
to rewrite a linux masq gateway's UDP masquerading entries so that the
remote host and port are whatever they choose. This creates a tunnel
between whatever host and port they want and a UDP port on an inside
machine.  The attacker is unable to tell what local inside ports and
addresses are being used, but they can determine the number of currently
masqueraded connections and the number of different hosts using those
connections behind the firewall.  Any network where UDP traffic is
masqueraded to the outside is vulnerable to this, including DNS, TFTP,
NetBIOS, and a multitude of other applications which rely on UDP
transport.  Since UDP is a connectionless protocol, the only way to
determine that a masqueraded connection is no longer being used is by
timing it out due to lack of activity or receiving ICMP messages
indication the port is closed. The result is that there is a 5 minute
time-out by default for all masqueraded UDP sessions, allowing an
attacker enough time to find and exploit the connection with some of the
methods outlined in the Examples section below.

Details:

For those familiar with the linux masquerading system, please jump to
the next paragraph.  IP masquerading is an implementation of NAT
(Network Address Translation) for the linux OS.  It allows you to
connect an internal network using private addresses to an external
network (internet) in a fairly secure manner. All packets coming from
the internal network and destined for the external network are rewritten
so the source of those packets is the masquerading gateway's external
address and the source port is the gateway's source port.  This only
requires one external IP address to enable internet access for
hundreds/thousands of internal machines and is therefore a popular
method for many businesses and home users with broadband connections.
The TCP and UDP protocols require both source and destination ports as
well as source and destination addresses to work.  The source port for
outgoing UDP/TCP connections is usually picked from the first available
port between 1024 and 65535 on the originating host, so how does the
masq gateway relay these connections AND be able to use these protocols
for its own networking?  The kernel sets aside the ports 61000 to 65096
by default for handling the masqueaded connection entries, allowing for
a theoretical maximum of 4096 of both UDP and TCP connections at a
time.  These values can be changed in the code or through the /proc file
system.  Now when connection request from internal host A comes in from
local port 1035 and its destination is the external DNS server Host Z on
port 53, the masquerading machine adds a new entry to the masquerading
table that looks like this:

Host A:1035 (651001) -> Host Z:53

The port in paranthesis is the local port the gateway uses to send the
forwarded UDP datagrams from and the port it uses to receive responses
back from Host Z.  The next paragraph describes how the vulnerability
found allows an attacker to modify the right side of the above
connection to allow traffic to come from thier host back into the
internal network to the local port on the inside host.


The UDP masquerading code only checks the DESTINATION PORT to determine
if a packet coming from the external network is to be forwarded inside.
It then sets the remote HOST and PORT to the source address and source
port of the incoming packet.  An attacker only needs to determine the
local port on the masq gateway to be able to rewrite the masq table with
thier own address and port, which is trivial considering the relatively
small port range set by default for use by masqueraded conenctions
(65100 - 65096).  Now how do you determine which one of these ports is
the local port on the gateway for the masq connection?  Easy, we send a
probe packet to each of these hosts and watch the IP ID field in the
responses.  The IP ID field is sequentially incremented on each host's
TCP/IP stack for each packet they send out, so the masq'd port ICMP
response will have the IP ID of the INTERNAL host, which is almost
always at least 1000 away from the current IP ID of the gateway
machine.  See the Examples section below for packet traces of a complete
scan/attack.


Examples:

We know that example.com has a linux masquerading gateway and that thier
DNS server is outside of this firewall. We can come to the conclusion
that internal machines must be able to contact the external DNS server
to be able to access the internet.  We start sending our probe packets:

Host A is our internal workstation (192.168.1.100)
Host B is our masq gateway (192.168.1.1 / 10.0.0.1)
Host C is the DNS server (10.0.0.25)
Host X is the attacker (10.10.187.13)

ipchains -L -M -n on the masq gateway BEFORE the probes
> UDP 03:39.21 192.168.1.100  10.0.0.25   1035 (63767) -> 53


[ tcpdump from attacker's machine ]

( we picked source port 12345 for our packets just so the trace would be
easier to follow)

[ snip -- this starts at port 61000 ]

10.0.0.1 > 10.10.187.13: icmp: 10.0.0.1 udp port 63762 unreachable [tos
0xd8] (ttl 245, id 13135)
10.10.187.13.12345 > 10.0.0.1.63763: udp 0 (DF) [tos 0x18] (ttl 254, id
23069)
10.0.0.1 > 10.10.187.13: icmp: 10.0.0.1 udp port 63763 unreachable [tos
0xd8] (ttl 245, id 13136)
10.10.187.13.12345 > 10.0.0.1.63764: udp 0 (DF) [tos 0x18] (ttl 254, id
23070)
10.0.0.1 > 10.10.187.13: icmp: 10.0.0.1 udp port 63764 unreachable [tos
0xd8] (ttl 245, id 13137)
10.10.187.13.12345 > 10.0.0.1.63765: udp 0 (DF) [tos 0x18] (ttl 254, id
23071)
10.0.0.1 > 10.10.187.13: icmp: 10.0.0.1 udp port 63765 unreachable [tos
0xd8] (ttl 245, id 13138)
10.10.187.13.12345 > 10.0.0.1.63766: udp 0 (DF) [tos 0x18] (ttl 254, id
23074)
10.0.0.1 > 10.10.187.13: icmp: 10.0.0.1 udp port 63766 unreachable [tos
0xd8] (ttl 245, id 13139)
10.10.187.13.12345 > 10.0.0.1.63767: udp 0 (DF) [tos 0x18] (ttl 254, id
23083)

10.0.0.1 > 10.10.187.13: icmp: 10.0.0.1 udp port 63767 unreachable [tos
0xd8] (ttl 244, id 17205)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The above packet's ID is substantially different, we may have found a
masq'd connection !!!

10.10.187.13.12345 > 10.0.0.1.63768: udp 0 (DF) [tos 0x18] (ttl 254, id
23084)
10.0.0.1 > 10.10.187.13: icmp: 10.0.0.1 udp port 63768 unreachable [tos
0xd8] (ttl 245, id 13140)
10.10.187.13.12345 > 10.0.0.1.63769: udp 0 (DF) [tos 0x18] (ttl 254, id
23088)
10.0.0.1 > 10.10.187.13: icmp: 10.0.0.1 udp port 63769 unreachable [tos
0xd8] (ttl 245, id 13141)
10.10.187.13.12345 > 10.0.0.1.63770: udp 0 (DF) [tos 0x18] (ttl 254, id
23090)
10.0.0.1 > 10.10.187.13: icmp: 10.0.0.1 udp port 63770 unreachable [tos
0xd8] (ttl 245, id 13142)
10.10.187.13.12345 > 10.0.0.1.63771: udp 0 (DF) [tos 0x18] (ttl 254, id
23091)
10.0.0.1 > 10.10.187.13: icmp: 10.0.0.1 udp port 63771 unreachable [tos
0xd8] (ttl 245, id 13143)
10.10.187.13.12345 > 10.0.0.1.63771: udp 0 (DF) [tos 0x18] (ttl 254, id
23092)
10.0.0.1 > 10.10.187.13: icmp: 10.0.0.1 udp port 63772 unreachable [tos
0xd8] (ttl 245, id 13144)

[ snip -- all the way to the upper end of our masq ports ]

ipchains -L -M -n on the masq gateway AFTER the probes
> UDP 04:35.12 192.168.1.100  10.10.187.13   1035 (63767) -> 12345
^-------[ expiration of the udp tunnel has been updated ;)

w00t! We now have a working tunnel from our host to port 1035 on the
inside machine!

Exploitation:

We have demonstrated that it is possible for us to 'hijack' the enternal
side of a masqueraded connection, so now what?  There is not a whole lot
we can do to the closed local udp port on the inside machine, so its
time to examine other applications/protocols that use UDP for transport
and what security risks there are in allowing unrestricted external
access to thier source ports.  I leave this as an excercise to the
reader...

-HD