Visit our newest sister site!
Hundreds of free aircraft flight manuals
Civilian • Historical • Military • Declassified • FREE!


TUCoPS :: Linux :: Apps A-M :: lnx692.htm

IP Masquerading spoofing



19th May 2000 [SBWID-692]
COMMAND

	    Kernel IP Masquerading spoofing

	

	

SYSTEMS AFFECTED

	    Linux 2.2.x

	

	

PROBLEM

	 Updated a few typos, thanks to Dr. Peter Bieringer remarks. (04 April 2002).

	

	    H  D  Moore  found  following.    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  65095 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 (61001) -> 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.   This is

	    due to a number of  hosts/services returning UDP from an  IP other

	    than that which the original UDP  packet went to - for example  it

	    is frequently the case that NFS servers just use the interface  ip

	    address \"closest\" to that which the NFS op came from.

	

	    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 connections

	    (65100 -  65095).   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 ;)

	

	    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.   We leave  this as  an excercise  to  the

	    reader...

	

	    Following the \"NetBIOS Info\"  thread on Incidents mailing  list at

	    SF, Robert Graham  mentioned a utility  he wrote to  automatically

	    respond  to  netbios  port  137  name  probes  with a netbios name

	    lookup back to the originating  host.  He mentioned that  it seems

	    to  cut  right  through  state-based  firewalls  and  NAT  systems

	    because the response probe looks  like a response to the  outgoing

	    probe.  Assuming that a host  on an inside network is sending  out

	    these netbios name  queries, an attacker  could exploit the  linux

	    2.2.x vulnerability and be   able to query the  netbios  names  of

	    internal machines.  More info:

	
	        http://www.robertgraham.com/pubs/firewall-seen.html#netbios

	

	

SOLUTION

	    In  general  it  is  not  advisable  the  use  of  UDP  masq for a

	    firewalling  gateway  -  since  the  only  thing  that  people are

	    normally putting through the UDP side is DNS, you are much  better

	    advised to  put a  decent caching  name server  on the gateway box

	    and block UDP through completely.

	

	    The core problem  is precisely not  being able to  actually _know_

	    when internal box has closed the  port.  You can easily revert  to

	    good\"old\" way (1 tunnel/pair) by commenting out

	
	        #define CONFIG_IP_MASQ_LOOSE_DEFAULT 1

	

	    at  ip_masq.c:418  (stupid  patch  attached).   This  should  drop

	    hijack\'ing...  Of  course, if we  change the default,  some way to

	    enable  it  back  perhaps  on  a  per-application  basis  (ip_masq

	    module) MUST be done.

	
	    --- net/ipv4/ip_masq.c.dloose	Thu Mar 30 14:51:06 2000

	    +++ net/ipv4/ip_masq.c	Thu Mar 30 14:57:24 2000

	    @@ -415,7 +415,7 @@

	     /*

	      *	By default enable dest loose semantics

	      */

	    -#define CONFIG_IP_MASQ_LOOSE_DEFAULT 1

	    +/* #define CONFIG_IP_MASQ_LOOSE_DEFAULT 1 */

	

	

	     /*

	

	    The issues causing  this DoS are  apparently more complex  than it

	    may appear according to the discussion in the Linux kernel mailing

	    list.  There is a patch for the exploit in 2.2.15pre-16 and it  is

	    a noteworthy amount of code.

	

	    If you downloaded pre-patch-2.2.15pre-16 you\'ll see following:

	
	    diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla

	    /net/unix/af_unix.c linux.15pre16/net/unix/af_unix.c

	    --- linux.vanilla/net/unix/af_unix.c   Sat Aug 14 02:27:46 1999

	    +++ linux.15pre16/net/unix/af_unix.c   Tue Mar 28 17:27:52 2000

	    @@ -969,6 +969,10 @@

	             return -ENOTCONN;

	       }

	

	    +  err = -EMSGSIZE;

	    +  if (len > sk->sndbuf)

	    +     goto out;

	    +

	       if (sock->passcred && !sk->protinfo.af_unix.addr)

	          unix_autobind(sock);

	

	    This isn\'t so different from  above (except the fact that  the one

	    above checks  len >  sk->sndbuff -  16, thus  limiting the sending

	    buffer).

	

	    Solution for SuSE Linux (they  provide a patched 2.2.14 kernel  to

	    ensure stability and not the 2.2.15 kernel):

	
	        ftp://ftp.suse.com/pub/suse/i386/update/6.4/kernel/k_deflt.rpm

	        ftp://ftp.suse.com/pub/suse/i386/update/6.4/kernel/k_eide.rpm

	        ftp://ftp.suse.com/pub/suse/i386/update/6.4/kernel/k_i386.rpm

	        ftp://ftp.suse.com/pub/suse/i386/update/6.4/d1/lx_suse-2.2.14.SuSE-24.i386.rpm

	

	


TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2014 AOH