标题：ICMP
基本简介
ICMP协议是一种面向连接的协议，用于传输出错报告控制信息。它是一个非常重要的协议，它对于网络安全具有极其重要的意义。[1]
它是TCP/IP协议族的一个子协议,属于网络层协议,主要用于在主机与路由器之间传递控制信息,包括报告错误、交换受限控制和状态信息等。当遇到IP数据无法访问目标、IP路由器无法按当前的传输速率转发数据包等情况时，会自动发送ICMP消息。
  ICMP原理ICMP提供一致易懂的出错报告信息。发送的出错报文返回到发送原数据的设备，因为只有发送设备才是出错报文的逻辑接受者。发送设备随后可根据ICMP报文确定发生错误的类型，并确定如何才能更好地重发失败的数据包。但是ICMP唯一的功能是报告问题而不是纠正错误，纠正错误的任务由发送方完成。
我们在网络中经常会使用到ICMP协议，比如我们经常使用的用于检查网络通不通的Ping命令（Linux和Windows中均有），这个“Ping”的过程实际上就是ICMP协议工作的过程。还有其他的网络命令如跟踪路由的Tracert命令也是基于ICMP协议的。
协议内容
ICMP的全称是 Internet Control Message Protocol 。从技术角度来说，ICMP就是一个“错误侦测与回报机制”，其目的就是让我们能够检测网路的连线状况﹐也能确保连线的准确性﹐其功能主要有：
· 侦测远端主机是否存在。
· 建立及维护路由资料。
· 重导资料传送路径。
· 资料流量控制。  ICMP常用类型  ICMP常用类型ICMP在沟通之中，主要是透过不同的类别(Type)与代码(Code) 让机器来识别不同的连线状况。常用的类别如下表所列﹕
ICMP 是个非常有用的协议﹐尤其是当我们要对网路连接状况进行判断的时候。下面让我们看看常用的 ICMP 实例，以更好了解 ICMP 的功能与作用。
重要性
ICMP协议对于网络安全具有极其重要的意义。ICMP协议本身的特点决定了它非常容易被用于攻击网络上的路由器和主机。例如，在1999年8月海信集团“悬赏”50万元人民币测试防火墙的过程中，其防火墙遭受到的ICMP攻击达334050次之多，占整个攻击总数的90%以上！可见，ICMP的重要性绝不可以忽视！
比如，可以利用操作系统规定的ICMP数据包最大尺寸不超过64KB这一规定，向主机发起“Ping of Death”（死亡之Ping）攻击。“Ping of Death” 攻击的原理是：如果ICMP数据包的尺寸超过64KB上限时，主机就会出现内存分配错误，导致TCP/IP堆栈崩溃，致使主机死机。（操作系统已经取消了发送ICMP数据包的大小的限制，解决了这个漏洞）
此外，向目标主机长时间、连续、大量地发送ICMP数据包，也会最终使系统瘫痪。大量的ICMP数据包会形成“ICMP风暴”，使得目标主机耗费大量的CPU资源处理，疲于奔命。
校验算法
以下代码在Visual Studio 2008 + Windows 7下调试通过。
lpsz指定要计算的数据包首地址，_dwSize指定该数据包的长度。
int CalcCheckSum(char* lpsz,DWORD _dwSize)
{
int dwSize;
__asm // 嵌入汇编
{
mov ecx,_dwSize
shr ecx,1
xor ebx,ebx
mov esi,lpsz
read: //所有word相加，保存至EBX寄存器
lodsw
movzx eax,ax
add ebx,eax
loop read
test _dwSize,1 //校验数据是否是奇数位的
jz calc
lodsb
movzx eax,al
add ebx,eax
calc:
mov eax,ebx //高低位相加
and eax,0ffffh
shr ebx,16
add eax,ebx
not ax
mov dwSize,eax
}
return dwSize;
}
抵御攻击
虽然ICMP协议给黑客以可乘之机，但是ICMP攻击也并非无药可医。只要在日常网络管理中未雨绸缪，提前做好准备，就可以有效地避免ICMP攻击造成的损失。
对于“Ping of Death”攻击，可以采取两种方法进行防范：第一种方法是在路由器上对ICMP数据包进行带宽限制，将ICMP占用的带宽控制在一定的范围内，这样即使有ICMP攻击，它所占用的带宽也是非常有限的，对整个网络的影响非常少；第二种方法就是在主机上设置ICMP数据包的处理规则，最好是设定拒绝所有的ICMP数据包。
设置ICMP数据包处理规则的方法也有两种，一种是在操作系统上设置包过滤，另一种是在主机上安装防火墙。具体设置如下：
1．在Windows 2000 Server中设置ICMP过滤
Windows 2000 Server提供了“路由与远程访问”服务，但是默认情况下是没有启动的，因此首先要启动它：点击“管理工具”中的“路由与远程访问”，启动设置向导。在其中选择“手动配置服务器”项，点击[下一步]按钮。稍等片刻后，系统会提示“路由和远程访问服务现在已被安装。要开始服务吗？”，点击[是]按钮启动服务。
  图1服务启动后，在计算机名称的分支下会出现一个“IP路由选择”，点击它展开分支，再点击“常规”，会在右边出现服务器中的网络连接（即网卡）。用鼠标右键点击你要配置的网络连接，在弹出的菜单中点击“属性”，会弹出一个网络连接属性的窗口，如图1所示。
图1中有两个按钮，一个是“输入筛选器”（指对此服务器接受的数据包进行筛选），另一个是“输出筛选器”（指对此服务器发送的数据包进行筛选），这里应该点击[输入筛选器] 按钮，会弹出一个“添加筛选器”窗口，再点击[添加]按钮，表示要增加一个筛选条件。
在“协议”右边的下拉列表中选择“ICMP”，在随后出现的“ICMP类型”和“ICMP编码”中均输入“255”，代表所有  图2的ICMP类型及其编码。ICMP有许多不同的类型（Ping就是一种类型），每种类型也有许多不同的状态，用不同的“编码”来表示。因为其类型和编码很复杂，这里不再叙述。
点击[确定]按钮返回“输入筛选器”窗口，此时会发现“筛选器”列表中多了一项内容（如图2所示）。点击[确定]按钮返回“本地连接”窗口，再点击[确定]按钮，此时筛选器就生效了，从其他计算机上Ping这台主机就不会成功了  图3。
2． 用防火墙设置ICMP过滤
许多防火墙在默认情况下都启用了ICMP过滤的功能。如果没有启用，只要选中“防御ICMP攻击”、“防止别人用ping命令探测”就可以了，如图3所示。
防御方法
选择合适的防火墙
有效防止ICMP攻击，防火墙应该具有状态检测、细致的数据包完整性检查和很好的过滤规则控制功能。
状态检测防火墙通过跟踪它的连接状态，动态允许外出数据包的响应信息进入防火墙所保护的网络。例如，状态检测防火墙可以记录一个出去的 PING（ICMP Echo Request），在接下来的一个确定的时间段内，允许目标主机响应的ICMP Echo Reply直接发送给前面发出了PING命令的IP，除此之外的其他ICMP Echo Reply消息都会被防火墙阻止。与此形成对比的是，包过滤类型的防火墙允许所有的ICMP Echo Reply消息进入防火墙所保护的网络了。许多路由器和基于Linux内核2.2或以前版本的防火墙系统，都属于包过滤型，用户应该避免选择这些系统。
新的攻击不断出现，防火墙仅仅能够防止已知攻击是远远不够的。通过对所有数据包进行细致分析，删除非法的数据包，防火墙可以防止已知和未知的 DoS攻击。这就要求防火墙能够进行数据包一致性检查。安全策略需要针对ICMP进行细致的控制。因此防火墙应该允许对ICMP类型、代码和包大小进行过滤，并且能够控制连接时间和ICMP包的生成速率。
配置防火墙以预防攻击
一旦选择了合适的防火墙，用户应该配置一个合理的安全策略。以下是被普遍认可的防火墙安全配置惯例，可供管理员在系统安全性和易用性之间作出权衡。
防火墙应该强制执行一个缺省的拒绝策略。除了出站的ICMP Echo Request、出站的ICMP Source Quench、进站的TTL Exceeded和进站的ICMP Destination Unreachable之外，所有的ICMP消息类型都应该被阻止。
详细分析
下面是针对每个ICMP消息类型的过滤规则的详细分析。
Echo Request和Reply（类型8和0）：
允许Echo Request消息出站以便于内部用户能够PING一个远程主机。阻止入站Echo Request和出站Echo Reply可以防止外部网络的主机对内部网络进行扫描。如果您使用了位于外部网络的监视器来监视内部网络，就应该只允许来自于特定外部IP的Echo Request进入您的网络。限制ICMP Echo包的大小可以防止“Ping Floods”攻击，并且可以阻止那些利用Echo Request和Reply来“偷运”数据通过防火墙的木马程序。
Destination unreachable （类型3）：
允许其入站以便于内部网用户可以使用traceroute。需要注意的是，有些攻击者可以使用它来进行针对会话的DoS攻击，如果您曾经历过类似的攻击，也可以阻止它。阻止出站的ICMP Destination unreachable消息，因为它可能会泄漏内部网络的结构。不过有一个例外，对于那些允许外部网络通过TCP访问的内部主机（如位于DMZ区的Web 服务器）发出的Destination unreachable，则应该允许它通过。为了能够支持“Path MTU Discovery”，您应该允许出站的“Packet Too Big”消息（类型3，代码4）到达那些主机。
Source quench（类型4）：
阻止其入站，因为它可以作为一种DoS攻击，能够降低发送者的发送速度。允许其出站以便于内部主机能够控制发送端发送数据的速度。有些防火墙会忽略所有直接发送到防火墙端口的Source Quench消息，以防止针对于防火墙的DoS攻击。
Redirect（类型5，9，10）：
Redirect、Router announcement、 Router selection（类型5，9，10）：这些消息都存在潜在危险，因为它们可以用来把数据重定向到攻击者的机器。这些消息都应该被阻止。
TTL exceeded（类型11）：
允许其进站以便于内部用户可以使用traceroute。“firewalking”使用很低的TTL值来对网络进行扫描，甚至可以通过防火墙对内网进行扫描，所以应该禁止其出站。一些防火墙可以阻止TTL值小于设定值的数据包进入防火墙。
Parameter problem（类型12）：
禁止其入站和出站。通过使用一个能够进行数据包一致性检查的防火墙，错误和恶意的数据包都会被阻塞。