Last Updated: 2009-10-19 09:21:54 UTC
by Daniel Wesemann (Version: 1)
ICMP, the Internet Control Message Protocol, was originally designed (RFC 792, 1981) to convey error conditions back to the sender of an IP packet. In today's Internet, ICMP is somewhat of an anachronism, since pretty much all programs and protocols contain their own error detection and recovery logic.
ICMP packets don't use port numbers like UDP and TCP do, but have a message type and message code field in the header instead.
ICMP/8 and ICMP/0
The ICMP packets that you probably are most familiar with are "ICMP Type 8 code 0" and "ICMP Type 0 Code 0", commonly known as "ping" and "ping reply". A "ping" is still the most commonly used command by system administrators to determine if a box is "up" and to check "round trip times" between two systems. While there are more reliable methods to accomplish either of these tasks, good old "ping" still prevails.
Ping packets can also have a data portion (payload). This triggered a big hunt for "covert channels" more than a decade ago, when an article on "Project LOKI: Arbitrary information tunneling" appeared in Phrack Magazine. Today, most firms and institutions keep "ping" blocked across their perimeter firewall, but primarily since the impact of blocking it is marginal, and not because of "covert channel" concerns. It has been a long time since mal-code authors last effectively used ping for communication. And why should they - http and https are working just fine across most corporate firewalls.
Another attack, the "smurf", relied on ICMP's ability to respond to a broadcast packet. Basically, a single "ping" sent to the broadcast address of a subnet was answered by all the active hosts on that subnet. Very neat to quickly map what's out there, but also a really good "amplifier" in a denial of service attack. This non-feature of ICMP has therefore long since been fixed: All current Operating Systems have broadcast ICMP either off by default, or support a configuration parameter to turn it off.
ICMP Type 3, "Destination Unreachable", is next to "ping" the most common of the ICMPs on today's Internet, primarily thanks to the increasing use of UDP in peer to peer networks. Unlike TCP, where the recipient of a packet can respond with a "Reset" (RST) if communication is undesired or not permitted, UDP contains no such mechanism and relies on ICMP to convey its displeasure. ICMP Type 3 Code 3, "port unreachable" is the usual answer returned on an UDP packet sent to a port that is not active (listening).
One of the cool features of ICMP Type 3 is that the error messages actually contain the first few bytes of the original packet that triggered the error. Firewalls unfortunately tend to ignore this information, and only display a useless information like "Denied ICMP type=3, code=3 from 220.127.116.11 on interface outside". A good old tcpdump or decent IDS will tell you more:
18:12:34.068212 IP 18.104.22.168 > 22.214.171.124: ICMP 126.96.36.199 udp port 53 unreachable, length 65
0x0000: 45c0 0055 95f5 0000 4001 4d0c 5801 0203 E..U....@.M.X.,.
0x0010: ad02 0304 0303 941a 0000 0000 4500 0039 ..dx........E..9
0x0020: 6749 0000 7211 4a84 ad02 0304 5801 0203 gI..r.J...dxX.,.
0x0030: c0df 0035 0025 3608 000a 0100 0001 0000 ...5.%6.........
0x0040: 0000 0000 0377 7777 0369 626d 0363 6f6d .....www.ibm.com
0x0050: 0000 1c00 01
At offset 0x001C (marked in blue), you can see the start of the original datagram. In this case, the system at 188.8.131.52 responded with an ICMP/3:3 "Port unreachable" because 184.108.40.206 apparently sent a DNS request for "www.ibm.com" to 220.127.116.11, and the latter does not seem to be running a DNS service. If you ever find your firewall under a deluge of ICMP/3 packets, sniffing them to determine the embedded original packets could help to tell you more.
ICMP/3 Type 4, "Fragmentation Needed but Don't Fragment Bit Set" is used to determine the maximum size per IP packet that a path between source and destination can support. This so-called "PMTU Discovery" helps to ensure that packets are sent at the maximum size that can squeeze through, which avoids fragmentation and reduces the bandwidth used for packet headers as compared to actual payload. In the frenzy to ban all ICMP through firewalls a decade ago, the rather useful ICMP 3/4 messages got blocked along with everything else. PMTU discovery is largely defunct today.
An ICMP/11 packet is triggered when a packet dies off because its internal "time to live" (TTL) counter expired. IP packets start their journey with a TTL of usually 255, and this counter is decremented at every network hop the packet traverses. When the counter reaches zero, the packet is discarded, and an ICMP/11 error generated. ICMP/11 are also used by the "traceroute" program, which sends packets with deliberately low TTLs and keeps track of the origins of any ICMP/11 error message it receives. By slowly counting up from the low initial TTL, a hop-by-hop mapping of the network nodes between source and destination can be performed.
The IETF started work on a paper that lists both the "threat" of ICMP and "impact" caused when an ICMP message is blocked at the perimeter. Today, a lot of firms block everything ICMP, and accept that doing so can lead to delays and time-outs in some UDP based applications. A less paranoid and equally well accepted practice is to permit ICMP/11:0 and ICMP/3:4 error replies from the outside, but to rate-limit these packets to prevent flooding.
But this is the Cyber Security Awareness Month. So ... time to improve your awareness: If you currently have all ICMP blocked on your perimeter, sniff the ICMP traffic on the outside of the firewall for a day to see what you are missing. If you currently permit ICMP through your perimeter, sniff the ICMP traffic for a day to see what it is that you are letting through.
There's no telling what you might find, in either case :)