From owner-freebsd-pf@FreeBSD.ORG Thu Nov 17 08:21:05 2005 Return-Path: X-Original-To: freebsd-pf@freebsd.org Delivered-To: freebsd-pf@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 605EB16A420 for ; Thu, 17 Nov 2005 08:21:05 +0000 (GMT) (envelope-from dhartmei@insomnia.benzedrine.cx) Received: from insomnia.benzedrine.cx (insomnia.benzedrine.cx [62.65.145.30]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9A67943D53 for ; Thu, 17 Nov 2005 08:21:04 +0000 (GMT) (envelope-from dhartmei@insomnia.benzedrine.cx) Received: from insomnia.benzedrine.cx (dhartmei@localhost [127.0.0.1]) by insomnia.benzedrine.cx (8.13.4/8.12.11) with ESMTP id jAH8L0g7000885 (version=TLSv1/SSLv3 cipher=DHE-DSS-AES256-SHA bits=256 verify=NO); Thu, 17 Nov 2005 09:21:01 +0100 (MET) Received: (from dhartmei@localhost) by insomnia.benzedrine.cx (8.13.4/8.12.10/Submit) id jAH8L0ld000404; Thu, 17 Nov 2005 09:21:00 +0100 (MET) Date: Thu, 17 Nov 2005 09:21:00 +0100 From: Daniel Hartmeier To: "Travis H." Message-ID: <20051117082100.GW29615@insomnia.benzedrine.cx> References: <20051108074236.18256.qmail@web32602.mail.mud.yahoo.com> <20051108095903.GB6116@insomnia.benzedrine.cx> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.10i Cc: freebsd-pf@freebsd.org Subject: Re: PF "keep state" for ICMP X-BeenThere: freebsd-pf@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Technical discussion and general questions about packet filter \(pf\)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 17 Nov 2005 08:21:05 -0000 On Thu, Nov 17, 2005 at 12:44:41AM -0600, Travis H. wrote: > (Any ICMP traffic is allowed back in after an outbound ICMP that keeps state) No, not any ICMP traffc. Any ICMP error (not query/reply) that references the ICMP query that created state by including its header in the payload. Yes, that header consists of only source/destination address and ICMP id. I.e. even if you know (or guess) the appropriate source and destination addresses, you can still only deliver ICMP errors for that tuple. > > Assuming you're a malicious A, what do you gain, though? You're already > > getting pinged by C, so you know it's there. You could already deliver > > an arbitrary amount of reply packets. Fingerprinting sillyness? > > Oooh, a challenge in creative thinking! > > First, remember that src IPs are eminently spoofable. So no protection there. > > Next let's handle the issue of the IDs. They appear to be 16-bit > values, so if the number sent out during a state expiry period is P, > and the attacker sends Q responses, then we expect that a reply will > get back in if PQ is close to 65536, and this assumes perfectly random > IDs in both the outbound and inbound... i.e. a perfect world. So you're introducing a malicious third party, let's say M, which guesses that there is a state for an ICMP query from C to A. Right, if there is such a state, M can probably guess its address tuple and ICMP id with that many tries. (In the original post, C is the origin of the ICMP query, and A is replying, i.e. C is pinging A. I think you switched those. I'll use S for 'source of query, recpient of reply and spoofed error' and D for 'destination of query, real peer' now.) > Lemme see, anything that handled net/host unreach intelligently could > be fooled into thinking C doesn't exist causing DoS... M could deliver a spoofed ICMP unreach error to S, pretending one of S's query packets to D couldn't reach D, yes. If S is handling ICMP unreach errors _intelligently_, it will not honour that bit of information for other connections, because it's aware that the credentials of referencing an ICMP header are weak (compared to referencing a TCP header including sequence numbers). If S is handling that _stupidly_, it might stop sending _any_ connections to D (or redirect connections to D through M, or such). Yes, it would be nice if pf could protect stupid S against this. But it can't, because there is the legitimate case where D is sending the same ICMP error (where D is really unreachable), and pf can't distinguish the two cases, and can't filter ICMP unreach errors generally, because that would break the legitimate cases, too. E.g. for ping(8) on FreeBSD, an incoming ICMP error referencing one of the outgoing ICMP echo requests is not an unexpected (assumed illegitimate) occurance, it even prints them nicely when they occur. > The attacker could force the source host to fragment packets for C, > which may do something interesting. At least it would reduce the > bandwidth from A to C, but it may be a DoS since something in between > may be dropping fragments. It could induce such short UDP/TCP > fragments such that they don't contain src/dst port information, and > thus are dropped by a firewall causing DoS... or possibly allocate > reassembly buffers, which could cause DoS in pathological cases.... This is the same thing again. You can't very well filter ICMP ttl-exceeded errors referencing ICMP queries, because then you'd immediately break legitimate cases, too. S might be sending ICMP queries with dont-fragment set to do PMTU discovery, for instance. So, you can't drop ICMP errors in general, because they are needed for proper operation of legitimate connections. Only if the sender of an ICMP query is stupid will he allow ICMP errors referencing ICMP queries allow to affect other protocols in his stack. I guess if you want to protect S in this case, you shouldn't allow it to ping untrusted D's, by not creating state. Daniel