[LWN Logo]

Date:         Fri, 26 May 2000 00:04:56 -0400
From: emf <emf@PRETTYHATEMACHINE.OBFUSCATION.ORG>
Subject:      Security Vulnerability in IPFilter 3.3.15 and 3.4.3
To: BUGTRAQ@SECURITYFOCUS.COM

	Obfuscation Research Laboratories Security Advisory #ORL-2000-05-19-01

			IPFILTER FIREWALLS

SYNOPSIS
		A weakness exists in the IPFilter firewalling package in
	all versions up to and including 3.3.15 and 3.4.3 that allows an
	attacker to penetrate the firewall when a common, yet admittedly
	flawed, configuration is used.

DETAILS

		If IPFilter rulesets are constructed such that
	"return-rst" and "keep state" overlap, e.g.:

		block return-rst in proto tcp from A to V
		pass out proto tcp from V' to A' keep state

	where A, A', V and V' are hostmasks that can include "any", and
	the attacker matches against A and A' and the victim matches against
	V and V', the attacker may exploit a race condition in the state
	table generation code that results from fr_addstate()'s fault of
	creating a new state entry for the outgoing RST packet generated
	by the "return-rst" rule.  If a new SYN packet comes in before
	the state entry created by the RST expires, the state entry
	will allow the SYN packet to pass through the firewall, and the
	explicit permissiveness of a "pass out all keep state" or similar
	rules then allows the SYN-ACK and all successive ACK's to create
	new state entries.  The attacker merely needs to ignore the RST's
	that are being sent to him and continue to attack the victim.

		For the curious, traces of an exploitation are included
	in the "GORY DETAILS" section at the end of this message.

PATCHES/WORKAROUNDS

        A patch has been made available for all versions of IPFilter that
        prevents fr_addstate() from creating a state entry when triggered
        by a RST packet.  This patch has been incorporated into IPFilter
	releases 3.3.16 and 3.4.4.

        If you are unable to patch your systems, remove all "return-rst"
	keywords or replace the rule which adds state for all outbound TCP
	packets:

        pass out proto tcp ... keep state    # No TCP flags matched upon!

        with the following three rules:

        pass out quick proto tcp ... flags R/R
        pass out proto tcp ... flags AR/A keep state
        pass out proto tcp ... flags S keep state

        This will support the current behavior of allowing state to be
        created by connections which are already open as well as new
        connections, so long as at least the ACK bit is set in the TCP
        header.  The use of the other rule, which matches all TCP packets,
        regardless of flag settings, is strongly discouraged.

        If you use a single rule such as this:

        pass out proto tcp/udp ... keep state

        then you must replace it with these four rules:

        pass out quick proto tcp ... flags R/R
        pass out proto tcp ... flags AR/A keep state
        pass out proto tcp ... flags S keep state
        pass out proto udp ... keep state

*** ip_state.c.old      Fri May 19 11:54:43 2000
--- ip_state.c  Sun May 21 15:50:11 2000
***************
*** 558,567 ****
--- 558,569 ----
            }
        case IPPROTO_TCP :
            {
                tcp = (tcphdr_t *)fin->fin_dp;

+               if (tcp->th_flags & TH_RST) return NULL;
+
                /*
                 * The endian of the ports doesn't matter, but the ack and
                 * sequence numbers do as we do mathematics on them later.
                 */
                is->is_dport = tcp->th_dport;

VENDOR INFORMATION

	The latest source releases of IPFilter can be obtained at:
		<http://coombs.anu.edu.au/~avalon/ip-filter.html>

	In addition, FreeBSD, NetBSD, and OpenBSD contain IPFilter in
	their operating systems, and patches have been applied to the
	following:
		FreeBSD 3-stable, FreeBSD 4-stable, FreeBSD-current,
		NetBSD-current, and OpenBSD 2.7-current.

	Errata patches will be available shortly for the following:
		NetBSD-1.4, OpenBSD 2.6-base, and OpenBSD 2.7-base

	
GORY DETAILS

		For those curious, this is what an exploitation looks like,
	from the viewpoint of ipmon. The attacker is 10.0.0.1 and the victim
	is 192.168.0.1.

19/05/2000 15:01:02.949513 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1969 PR tcp
19/05/2000 15:01:03.002974 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1969 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:03.463298 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1969 PR tcp
19/05/2000 15:01:03.502998 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1969 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:03.964040 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1969 PR tcp
19/05/2000 15:01:04.003008 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1969 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:04.464829 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1969 PR tcp
19/05/2000 15:01:04.773523 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1970 PR tcp
19/05/2000 15:01:05.003045 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1970 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:05.265838 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1970 PR tcp
19/05/2000 15:01:05.503067 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1970 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:05.766479 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1970 PR tcp
19/05/2000 15:01:06.003076 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1970 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:06.267255 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1970 PR tcp
19/05/2000 15:01:06.492856 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1971 PR tcp
19/05/2000 15:01:06.498127 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1972 PR tcp
19/05/2000 15:01:06.502494 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1973 PR tcp
19/05/2000 15:01:06.503102 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1973 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:06.503108 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1972 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:06.503112 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1971 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:06.968127 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1972 PR tcp
19/05/2000 15:01:06.968579 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1971 PR tcp
19/05/2000 15:01:06.969636 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1973 PR tcp
19/05/2000 15:01:07.003107 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1973 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:07.003113 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1972 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:07.003118 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1971 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:07.468886 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1972 PR tcp
19/05/2000 15:01:07.469341 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1971 PR tcp
19/05/2000 15:01:07.470679 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1973 PR tcp
19/05/2000 15:01:07.503141 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1973 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:07.503149 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1972 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:07.503156 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1971 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:07.969565 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1972 PR tcp
19/05/2000 15:01:07.970137 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1971 PR tcp
19/05/2000 15:01:07.970437 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1973 PR tcp
19/05/2000 15:01:08.233429 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1974 PR tcp
19/05/2000 15:01:08.405331 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1975 PR tcp
19/05/2000 15:01:08.503178 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1975 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:08.503186 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1974 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:08.670605 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1974 PR tcp
19/05/2000 15:01:08.744352 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1976 PR tcp
19/05/2000 15:01:08.745703 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1977 PR tcp
19/05/2000 15:01:08.870808 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1975 PR tcp
19/05/2000 15:01:09.003258 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1977 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:09.003269 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1976 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:09.003275 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1975 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:09.003281 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1974 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:09.171217 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1977 PR tcp
19/05/2000 15:01:09.171675 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1974 PR tcp
19/05/2000 15:01:09.172719 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1976 PR tcp
19/05/2000 15:01:09.371601 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1975 PR tcp
19/05/2000 15:01:09.503212 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1977 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:09.503220 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1976 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:09.503224 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1975 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:09.503228 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1974 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:09.671908 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1977 PR tcp
19/05/2000 15:01:09.672369 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1974 PR tcp
19/05/2000 15:01:09.672673 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1976 PR tcp
19/05/2000 15:01:09.872266 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1975 PR tcp
19/05/2000 15:01:10.003272 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1977 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:10.003281 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1976 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:10.127434 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1978 PR tcp
19/05/2000 15:01:10.127893 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1979 PR tcp
19/05/2000 15:01:10.172616 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1977 PR tcp
19/05/2000 15:01:10.173086 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1976 PR tcp
19/05/2000 15:01:10.503253 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1979 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:10.503262 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1978 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:10.573248 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1979 PR tcp
19/05/2000 15:01:10.573711 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1978 PR tcp
19/05/2000 15:01:11.003251 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1979 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:11.003259 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1978 PR tcp Pkts 1 Bytes 40
19/05/2000 15:01:11.073864 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1979 PR tcp
19/05/2000 15:01:11.074332 STATE:NEW 192.168.0.1,8003 -> 10.0.0.1,1978 PR tcp
19/05/2000 15:01:11.503275 STATE:EXPIRE 192.168.0.1,8003 -> 10.0.0.1,1979 PR

--
.emf.