PF "keep state" for ICMP

Daniel Hartmeier daniel at benzedrine.cx
Thu Nov 17 00:21:05 PST 2005


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


More information about the freebsd-pf mailing list