Subject: Re: DoS using crafted ICMP "frag needed" packets
To: Ed Ravin <eravin@panix.com>
From: Steven M. Bellovin <smb@cs.columbia.edu>
List: tech-net
Date: 06/21/2005 20:43:04
In message <20050621180211.GA360@panix.com>, Ed Ravin writes:
>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.
>

Wearing my security researcher hat, that's cool -- the attack is 
described in RFC 1191, but I haven't heard of it in the wild before 
this...  (Well, not this attack, but several variants of Path MTU 
attack are mentioned.)

Option 1 is clearly correct -- there's no reason to send anything 
larger than the link's MTU.  But the attacker's response would be to 
oscillate between different MTU sizes.  I suspect that any Path MTU 
message that specifies a higher MTU than what is currently being used 
should be ignored, since it can't legitimately be generated.  In other 
words, Path MTU messages should only be able to lower the MTU, not 
raise it.  Raising it should be done as described in the RFC.  (Aside: 
I haven't looked at our code, so I don't know if that's being done.

Option 2, or a variant thereof, strikes me as best.  The table came 
more or less straight from the RFC, but that table is mostly an 
artifact -- it was designed to deal with the then-existing base of 
routers that knew what to do with a packet with DF set, but didn't know 
how to set the desired MTU field.  That's ancient history; I suspect 
that any router made in the last decade does it right or not at all.

Option 2 is probably best, but we may want to rethink the table.  The 
current values are based on more-or-less obsolete hardware.

		--Steven M. Bellovin, http://www.cs.columbia.edu/~smb