Subject: DoS using crafted ICMP "frag needed" packets
To: None <tech-net@netbsd.org>
From: Ed Ravin <eravin@panix.com>
List: tech-net
Date: 06/21/2005 14:02:11
One of my customers with NetBSD 2.0 was recently hit with an interesting
DoS attack.  The attacker opened up an HTTP connection to the customer's
NetBSD webserver, sent an HTTP GET, and then when the response came flowing
down the pipe, sent an ICMP unreachable, "fragmentation needed" message,
with the "MTU wanted" size set to 1500.  NetBSD would then start
retransmitting the data in the TCP window, only to get another ICMP
unreachable message with the "MTU wanted" set to 1500.  And another.
And so on.  Basically, for the price of a 70 byte ICMP packet, the
attacker could provoke a 3k response.

As DoS attacks go, it's not the world's greatest, but using only one IP
address the attacker was able to cause one NetBSD box to generate 28
megabits per second of response traffic.

I looked over netinet/ip_icmp.c, and though I don't grok the code fully,
I have a few suggestions that should be able to blunt this attack:

1) ignore the ICMP unreachable "need to fragment" message if the "MTU size
wanted" in the message is equal to or larger than the current MTU size for
this connection.  This will limit the attacker to sending "only" 1431
messages before reaching the minimum MTU, 68.  Not enough to stop the
attack, but at least it blunts it.

2) Add a sysctl that when enabled, causes NetBSD to ignore the "MTU size
wanted" field and just use the MTU size table in ip_icmp.c.  That limits
the attacker to just 5 messages before reaching 68, at least with the
table currently in ip_icmp.c.

3) Add a threshold or other rate-limiting to each TCP connection - after
NN "fragmentation needed" messages, either ignore the messages or ignore
the MTU size and use the internal table to drop down to the next MTU size.

Any thoughts?  I've opened up kern/30550 on this.

	-- Ed