Table of Contents

About

The following is a classificiation of various types of ICMP Denial of Service (DoS) attacks. Even though most of these have been patched by various vendors, they still are historically significant and the methodologies more than often pertain even to TCP or UDP that are used more prevalently in modern day DoS attacks.

Taxonomy

Even though not categories per se, there are three cases of ICMP DoS that have been known to be the most effective, namely:

In practice, these attacks are sometimes combined together where, for instance, a flood will take place but by sending Ping-of-Death (PoD) packages. Nevertheless, the three attack types have various differences that should be highlighted in order to be able to understand the various methodologies used.

                                 +------------+
                                 |  ICMP DoS  |
                                 +-----+------+
                                       |
        +-------------------+----------+--------+-----------------+-------------------+
        |                   |                   |                 |                   |
    +---+---+       +-------+-------+      +----+-----+      +----+-----+      +------+-----+
    | Flood |       | Ping-of-Death |      |  TWINGE  |      |  Smurf   |      | BlackNurse |
    +-------+       +---------------+      +----------+      +----------+      +------------+

Flood

The standard ping or rather ICMP echo protocol can be summarized by the following sketch:

+---+                 +---+
| A |                 | B |
+-+-+                 +-+-+
  |                     |
  |      ICMP-Echo      |
  +-------------------->|
  |       Request       |
  |                     |
  |      ICMP-Echo      |
  |<--------------------+
  |        Reply        |
  |                     |

where:

A very basic ICMP flood attack can be perfromed by issuing the following command on Linux:

ping -f DESTINATION

where:

Or, on machines that do not have a ping utility that can also flood (ie: flag -f), for example Windows, the nmap / nping utility can be used instead:

nping --icmp --delay 1ms -c COUNT DESTINATION

where:

Compared to issuing ping without the -f parmeter, the command will deliver an ICMP packet to the destination but the command will not wait for a reply. In effect, this means that the machine executing ping -f will generate packets as fast as it can, at best, up to the total amount of bandwidth available to the machine.

Given the following scenario with three identical clients attached to a switch that is capable of processing more than 30MiB of data, in case "Client A" starts a flood towards "Client B", then given ideal circumstances with minimal lossses, the connection between "Client A" and "Client B" will be saturated with packets taking up the entire bandwidth between "Client A" and "Client B".

                         | Internet
                         |
          10MiB     +----+---+    10MiB
      +-------------+ Switch +-------------+
      |             +----+---+             |
+-----+----+     >30MiB  |            +----+-----+
| Client A |             | 10MiB      | Client B |
+----------+             |            +----------+
                    +----+-----+
                    | Client C |
                    +----------+

Conversely, if "Client C" and "Client B" decide to both flood "Client A" with packets, then the connection between "Client A" and the switch will be oversaturated. The result is that "Client A" will be stuck processing the ICMP packets from "Client B" and "Client C" without being able to respond to any other packets, for instance, packets from the Internet that are supposed to arrive at "Client A".

Having said that, a straight-flood, whether ICMP or not, is only really effective or useful whenever an attacker has the capability to overwhelm or oversaturate the connection of the victim. In practice, DDoS is used, such that an attacker already has a number of compromised machines that then can be used to oversaturate the connection of a victim.

Mitigations

A very rudimentary way of preventing an ICMP flood would be to drop all ICMP packets:

iptables -A INPUT -p icmp -j DROP

however, ICMP is widely used on networks for various other functionality such that dropping ICMP packets entirely is not an ideal solution.

Perhaps a better solution would be to rate-limit the amount of ICMP packets:

# Set the default policy to drop all incoming backets.
iptables -P INPUT DROP
 
# Only allow a single ICMP packet per second.
iptables -A INPUT -p icmp -m limit --limit 1/sec -k ACCEPT

Ping-of-Death (PoD)

The Ping-of-Death attack is a more technical attack that does not directly reply on the attacker's capabiltiies to overwhelm the victim's network. Specifically, the ICMP PoD attack relies on the fact that an ICMP packet is also capable of carrying data up to the total size of an IP packet which is $2^{16} - 1 = 65535B$ and then by placing large amounts of data inside an ICMP packet payload, when the ICMP packet gets reassembled on the machine receiving it, the reassembled packet ends up much larger than $65535B$ and up to $65548=65528 offset + 20B header$ which can end up creating a buffer overflow at the destination.

It is interesting to observe that in general PoD is a DoS since, if successful, the target machine would end up crashing or worse, but that the attack itself is more of a remote exploit. Typically, PoD has been known to be very effective against Windows machines, but it stands to reason that any TCP/IP stack that does not check the size of the reassembled packet before reading the data into a buffer will end up just as vulnerable. This can be particularly severe for closed-hardware and closed-firmware devices that do not receive any updates such that the entire device might have to be replaced.

Using nping a large ICMP-Echo packet can be created by issuing:

nping --icmp DESTINATION --data-length 65400 --mtu 8 --count 1

where:

In practice, modern machines have been patched such that PoD will not crash the machine but rather the packet will not even be reassembled in the first place when the TCP/IP stack realizes that an assembled packet would end up much larger than IP allows.

Nevertheless, it is important to realize that PoD pertains less to ICMP than it does to IP because the attack hinges on the fragmentation and the reassembly of packets at the destination given sufficiently large payloads. That being said, PoD relates less to a flood and even less to ICMP but PoD is a good example of a packet-level exploit that can trigger a buffer overflow inside the TCP/IP stack.

TWINGE

The TWINGE ICMP attack is made up of two different sub-attacks that have the main goal to overwhelm the TCP/IP stack of a target machine. In some ways, TWINGE relates more to the Ping-of-Death (PoD) and less so to an ICMP flood because the methodology used by TWINGE does not directly seek to oversaturate the network of an adversary but rather to hopefully trigger bugs within the TCP/IP stack of the destination.

The folllowing is a represention of an ICMP packet sent over the network with the various parameters and flags that can be set. As it stands, ICMP is encased inside IP such that the first part of the IP packet is a characterstic of IP and only the latter parameters are typical of ICMP itself.

+---------+---------------+-----+-------------------------+   -+
| VERSION | HEADER LENGTH | ToS |       TOTAL LENGTH      |    |
+---------+---------------+-----+-------+-----------------+    |
|             ID                | FLAGS | FRAGMENT OFFSET |    |
+--------------+----------------+-------+-----------------+    |
|      TTL     |     PROTOCOL   |     HEADER CHECKSUM     |    | IP
+--------------+----------------+-------------------------+    |
|                         SOURCE                          |    |
+---------------------------------------------------------+    |
|                       DESTINATION                       |    |
+------+------------------------+-------------------------+   -+
| TYPE |           CODE         |       ICMP CHECKSUM     |    |
+------+------------------------+-------------------------+    | ICMP
|                           DATA                          |    |
+---------------------------------------------------------+   -+

The TWINGE ICMP-Echo attack, performs two operations:

First, by randomizing the TYPE and CODE of the ICMP packet, the attacker sends a bunch of nonsensical packets to a victim, hoping that the victim machine will have a TCP/IP stack that would not know how to handle the packets. For instance, there are $30$ different ICMP types with quite a few sub-codes for each ICMP type. It is unlikely that a IP stack would know what to do with randomly generated packets based on the entire set of available types.

Second, and similar to Ping-of-Death (PoD), the TWINGE attack, in its original form contains the following code:

ip->saddr = random() + ty + getpid();

The code sets the source address of the ICMP packet by constructing a nonce composed of:

The iphdr struct defined in /include/linux/ip.h defines saddr as an unsigned int with 32-bit length such that it is valid, at least from the point of view of the code, to fill up the saddr structure member with any garbage that fits the type definition. For this second commonent of the TWINGE attack, the source IP addresses of all the packets are randomized making the target machine, in ideal circumstances, having to additionally respond and send packets itself to random IP addresses.

Similar to Ping-of-Death, the second part of the TWINGE ICMP attack, also relies on the nature of IP itself rather than the nature of ICMP since setting the source address for an IP packet is done within the IP header and not within the various sub-type of packets such as TCP, UDP or ICMP.

In order to demonstrate spoofing the source address, nping can be used to craft an ICMP-Echo packet such that the packet will be sent by one machine, bounce off a remote machine and then be received by a different machine.

                +---------+
        ICMP    |  Google |   ICMP
  +------------>+         +----------+
  |    Request  | 8.8.8.8 |   Reply  |
  |             +---------+          v
+-+-+                              +-+-+
| A | 1.1.1.1                      | B | 2.2.2.2
+---+                              +---+

In this scenario, machine A sends an ICMP packet with the source address set to the IP address of machine B to the Google nameserver at 8.8.8.8:

nping --icmp --source-ip 2.2.2.2 --count 1 8.8.8.8

Once the packet is received by Google, the packet source is found to have the IP address of the machine B, namely in this example 2.2.2.2, such that the Google nameserver will send an ICMP-Echo reply to machine B instead of machine A. Quite so, running tcpdump on machine B once the nping command is executed on machine A, the packet can be confirmed.

Running tcpdump on machine A, the ICMP echo request can be observed:

1.1.1.1 > 8.8.8.8 ICMP echo request, id 18713, seq 1, length 8

and running tcpdump on machine B, the ICMP reply is received:

8.8.8.8 > 2.2.2.2: ICMP echo reply, id 24748, seq 1, length 8 

Smurf

Similar to the TWINGE attack, the Smurf attack relies on spoofing both the source and destination of the ICMP/IP packet. The following sketch provides an overview of a classic Smurf attack.

       
+---------------------+
|       VICTIM        |
+---------------------+ 
  ^     ^     ^     ^
  |     |     |     |
+---+ +---+ +---+ +---+     +----------+
| 1 | | 2 | | 3 | | 4 | ... | ATTACKER |
+---+ +---+ +---+ +---+     +-----+----+
  ^     ^     ^     ^             |
  |     |     |     |             | ICMP/IP
  +-----+--+--+-----+<------------+ SRC: VICTIM
           |                        DST: BROADCAST
       +---+----+
       | SWITCH |
       +---+----+
           |
           |
      

Given a local network consisting of machines $M_{1}..M_{n}$, the attacker is to be found on the same network as the other machines. The attacker then forges an IP/ICMP packet and sets the source address to the address of the victim and the destination address to the broadcast address of the entire network. Since the ICMP/IP packet has as destination the broadcast address, the ICMP/IP packet is received by all machines $M_{1}..M_{n}$ on the network. Now, for all machines $M_{1}..M_{n}$, the packet is processed by each machine individually, and the reply is sent to the source set in the IP header of the packet which happens to be the IP address of the victim. The result is that all machines $M_{1}..M_{n}$ will then send an ICMP packet to the victim and hopefully oversaturate the bandwidth of the victim.

As a simple example, all machines on a network with the netmask 255.255.255.0 having the broadcast address 192.168.1.255 can be pinged by sending an ICMP packet to the broadcast address 192.168.1.255:

ping 192.168.1.255

to which all machine slistening, will reply:

PING 192.168.1.255 (192.168.1.255): 56 data bytes
64 bytes from 192.168.1.12: icmp_seq=0 ttl=64 time=1.009 ms
64 bytes from 192.168.1.24: icmp_seq=0 ttl=255 time=14.759 ms
64 bytes from 192.168.1.150: icmp_seq=0 ttl=255 time=14.843 ms
64 bytes from 192.168.1.98: icmp_seq=0 ttl=255 time=14.870 ms
64 bytes from 192.168.1.11: icmp_seq=0 ttl=255 time=14.895 ms
64 bytes from 192.168.1.4: icmp_seq=0 ttl=255 time=14.921 ms
...
--- 192.168.1.255 ping statistics ---
1 packets transmitted, 1 packets received, +5 duplicates, 0.0% packet loss
round-trip min/avg/max/stddev = 1.009/12.550/14.921/5.161 ms

Assuming the following topology:

                                                                        192.168.1.2 
                                                          +---+         +--------+
                                                     +----| 1 +-------->| VICTIM |
192.168.1.2                                          |    +---+         |--------+
+----------+    ICMP-Echo Request     +--------+     |    +---+         |        |
| ATTACKER +------------------------->| SWITCH +-----+--->| 2 +-------->|        |
+----------+    SRC: 192.168.1.2      +--------+     |    +---+         |        |
                DST: 192.168.1.255                   |    +---+         |        |
                                                     +--->| 3 +-------->|        |
                                                     |    +---+         |        |
                                                     |                  |        |
                                                     .                  .        .
                                                     .                  .        .
                                                     .                  .        .

and using nping, a Smurf attack can be carried out on the local network:

nping --icmp 192.168.1.255 --source-ip 192.168.1.3 --count 1

such that the traffic on the victim machine can be observed using tcpdump:

tcpdump -vvv -i en1 dst 192.168.1.2

resulting in more or less the output:

192.168.1.12 > 192.168.1.2: ICMP echo reply, id 26122, seq 1, length 8
192.168.1.24 > 192.168.1.2: ICMP echo reply, id 26122, seq 1, length 8
192.168.1.150 > 192.168.1.2: ICMP echo reply, id 26122, seq 1, length 8
192.168.1.98 > 192.168.1.2: ICMP echo reply, id 26122, seq 1, length 8
192.168.1.11 > 192.168.1.2: ICMP echo reply, id 26122, seq 1, length 8
192.168.1.4 > 192.168.1.2: ICMP echo reply, id 26122, seq 1, length 8

As can be observed, all the machines listening to the broadcast address (192.168.1.12, 192.168.1.24, 192.168.1.150, etc.) on the local network respond to victim machine with IP 192.168.1.2.

Amplification Factor

Dr. Sanjeev Kumar (The University of Texas) conined the phrase "amplification factor" and used the term to describe the bandwidth amplification that an original attack undergoes.

For instance, when exchaning a single ICMP packet accross the network, the amplification factor is said to be $1$ since there is just one single degree of amplification. For a Smurf attack, where the number of machines on the network is $n$, then the amplification factor is $n$. Depending on whether $n$ is small or large enough, a victim machine might or might not be overwhelmed.

If one were to set the destination and the source address of the packet being set to the broadcast address, then each host receiving the packet will have to retransmit the packet back to all the hosts resulting in an amlification factor of $n^{2}$.

Mitigation

There are two resolutions that can be applied:

On Linux, perhaps the more elegant solution is to use sysctl and then make the OS ignore ICMP echo requests to the broadcast address:

sysctl net.ipv4.icmp_echo_ignore_broadcasts = 1

The line could also be added on modern Linux distributions to the /etc/sysctl.d/ directory in order to make the setting persistent.

Using iptables a firewall rule an be established such that packets originating on the local interface that do not have the source address set to any machine on the local network will be dropped.

iptables -A OUTPUT -p tcp -i eth0 ! -s 192.168.1.0/24 -j DROP

which reads as:

BlackNurse

The BlackNurse attack was discovered by Lenny Hansson and Kenneth Bjerregard Jørgensen and it is similar to Ping-of-Death in that BlackNurse is not designed to oversaturate the bandwidth of the victim. Instead, BlackNurse relies on the observation that some equipment has issues dealing with ICMP packets with type 3 and code 3 namely "Destination Unreachable", "Destination port unreachable", requiring an abmormal amount of CPU power to process.

The attacker just crafts an ICMP packet with type 3 and code 3 in the ICMP part of the ICMP/IP header and delivers the packet to the victim. It just so happens that older equipment has trouble handling such a packet and then ends up taking up a more than usual CPU time slice.

Using nping as the packet crafting tool:

nping --icmp --icmp-type 3 --icmp-code 3 DESTINATION --count 1

where:

In order to overwhelm the CPU on the victim machine and to increase the chances of success, the attack is commonly spammed over and over again, using flooding:

nping --icmp --icmp-type 3 --icmp-code 3 DESTINATION --count N --delay 1ms

where:

The research into BlackNurse discovered that just a single packet could make the CPU spike as high as 15\% for some vulnerable equipment. In that sense, BlackNurse has less bandwidth requirements and even though there is no DoS amplification factor, the ratio of required bandwith to CPU usage induced is very low.

Similarly, it is good practice to usually allow ICMP type 3 ("Destination unreachable") on the network because the packets are used for routing and for upstream network configurations such that BlackNurse stands to have a good chance of succeeding in the absense of restrictions.

One can note that BlackNurse is in some ways a particular instance of the TWINGE attack given that TWINGE randomizes ICMP packet types and codes. On its own, TWINGE will invariably send an ICMP packet with type 3 and code 3 just that compared to BlackNurse, TWINGE does not have the specific goal in mind to overload the CPU of the victim machine.