Security Problems with Linux 2.2.x IP Masquerading

Type securityvulns
Reporter Securityvulns
Modified 2000-04-08T00:00:00


[ Security Problems with Linux 2.2.x IP Masquerading ]


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.


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.


We know that 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 ( Host B is our masq gateway ( / Host C is the DNS server ( Host X is the attacker (

ipchains -L -M -n on the masq gateway BEFORE the probes > UDP 03:39.21 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 ] > icmp: udp port 63762 unreachable [tos 0xd8] (ttl 245, id 13135) > udp 0 (DF) [tos 0x18] (ttl 254, id 23069) > icmp: udp port 63763 unreachable [tos 0xd8] (ttl 245, id 13136) > udp 0 (DF) [tos 0x18] (ttl 254, id 23070) > icmp: udp port 63764 unreachable [tos 0xd8] (ttl 245, id 13137) > udp 0 (DF) [tos 0x18] (ttl 254, id 23071) > icmp: udp port 63765 unreachable [tos 0xd8] (ttl 245, id 13138) > udp 0 (DF) [tos 0x18] (ttl 254, id 23074) > icmp: udp port 63766 unreachable [tos 0xd8] (ttl 245, id 13139) > udp 0 (DF) [tos 0x18] (ttl 254, id 23083) > icmp: 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 !!! > udp 0 (DF) [tos 0x18] (ttl 254, id 23084) > icmp: udp port 63768 unreachable [tos 0xd8] (ttl 245, id 13140) > udp 0 (DF) [tos 0x18] (ttl 254, id 23088) > icmp: udp port 63769 unreachable [tos 0xd8] (ttl 245, id 13141) > udp 0 (DF) [tos 0x18] (ttl 254, id 23090) > icmp: udp port 63770 unreachable [tos 0xd8] (ttl 245, id 13142) > udp 0 (DF) [tos 0x18] (ttl 254, id 23091) > icmp: udp port 63771 unreachable [tos 0xd8] (ttl 245, id 13143) > udp 0 (DF) [tos 0x18] (ttl 254, id 23092) > icmp: 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 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!


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...