COMMAND
ipchains
SYSTEMS AFFECTED
Linux
PROBLEM
Following is based on data protect GmbH - Advisory #2 by Thomas
Lopatic and John McDonald. They had discovered a potential
vulnerability in the Linux ipchains firewall implementation. In
certain situations, it is possible for an attacker to bypass the
packet filter when communicating with machines that allow incoming
packets to specific ports. This attack is a variation of
previously discussed fragmentation attacks, where the attacker
uses fragments to rewrite parts of the TCP or UDP protocol header.
In this case port information is rewritten in order to gain access
to ports that should be blocked by the firewall. Included in this
advisory is a patch to the 2.2.10 Linux kernel that corrects this
vulnerability, and a pointer to example code that demonstrates
the problem.
The Linux ipchains firewall code has special provisions for IP
fragments that do not contain enough information for transport
protocol header analysis. Fragments that start at offset 0, and
are not long enough to provide complete transport header
information are treated like fragments with an offset > 0 (> 1 in
the TCP case). This is the relevant code from ip_fw.c:
if (offset == 0) {
unsigned int size_req;
switch (ip->protocol) {
case IPPROTO_TCP:
/* Don't care about things past flags word */
size_req = 16;
break;
case IPPROTO_UDP:
case IPPROTO_ICMP:
size_req = 8;
break;
default:
size_req = 0;
}
offset = (ntohs(ip->tot_len) < (ip->ihl<<2)+size_req);
}
As mentioned above, fragments with an offset of 0, that are too
short to provide a full transport protocol header, are treated
like non-first fragments. This allows an attacker to perform the
following port rewriting attack:
1. Attacker sends a fragment, with offset 0, a set IP_MF bit,
and a full transport protocol header which meets the packet
filter and is passed to the victim machine.
2. Attacker sends a fragment, with offset 0, a set IP_MF bit,
and a length of 4 bytes. This contains the (blocked) ports
that the attacker wishes to access on the victim machine.
This fragment will be accepted by the firewall and overlap
- in the victim machine's reassembly chain - the port
information contained in the fragment sent in step 1.
3. Attacker sends a fragment with a cleared IP_MF bit,
starting where the first fragment left off, that completes
the set of fragments.
Depending on the defragmentation strategy of the victim machine's
operating system, it might be necessary to swap steps 1 and 2. It
is important to note that there are two conditions that must be
met for a particular ipchains packet filter to be vulnerable:
1. The packet filter must not be configured with the Linux
kernel option CONFIG_IP_ALWAYS_DEFRAG. If the packet filter
reassembles the fragments before doing the firewall checks,
then this attack will fail.
2. The packet filter must have a rule to allow non-first
fragments to pass. The Linux ipchains how-to suggests that
either an administrator selects CONFIG_IP_ALWAYS_DEFRAG, or
implements such a rule. This rule was considered to be
safe because fragments with an offset of 1 are blocked by
the packet filter, which prevents attacks based on
rewriting the TCP flags.
fragrouter, a component of Nidsbench, has been updated to perform
this attack transparently. This is an excellent open source tool
for testing intrusion detection systems and packet filters
provided by Anzen Computing. The version of fragrouter that
performs this attack should be available shortly, at
http://www.anzen.com/research/nidsbench/
SOLUTION
The following Linux kernel patch (against version 2.2.10) will
close this vulnerability by blocking packets that could be used to
rewrite header information in this fashion. It is also possible
to reconfigure the ipchains machine to always defragment packets,
or to remove any rule which passes non-first IP fragments through
the firewall ("-f" option of the "ipchains" command). The latter,
however, might introduce incompatibilities, e.g. with applications
that transmit large UDP datagrams across the firewall and hence
cause IP fragmentation.
*** linux.old/net/ipv4/ip_fw.c Wed Jun 9 05:33:07 1999
--- linux/net/ipv4/ip_fw.c Fri Jul 23 19:20:45 1999
***************
*** 37,42 ****
--- 37,45 ----
* 19-May-1999: Star Wars: The Phantom Menace opened. Rule num
* printed in log (modified from Michael Hasenstein's patch).
* Added SYN in log message. --RR
+ * 23-Jul-1999: Fixed small fragment security exposure opened on 15-May-1998.
+ * John McDonald <jm@dataprotect.com>
+ * Thomas Lopatic <tl@dataprotect.com>
*/
/*
***************
*** 644,650 ****
default:
size_req = 0;
}
! offset = (ntohs(ip->tot_len) < (ip->ihl<<2)+size_req);
}
src = ip->saddr;
--- 647,666 ----
default:
size_req = 0;
}
!
! /* If it is a truncated first fragment then it can be
! * used to rewrite port information, and thus should
! * be blocked.
! */
!
! if (ntohs(ip->tot_len) < (ip->ihl<<2)+size_req)
! {
! if (!testing && net_ratelimit()) {
! printk("Suspect short first fragment.\n");
! dump_packet(ip,rif,NULL,NULL,0,0,0,0);
! }
! return FW_BLOCK;
! }
}
src = ip->saddr;