李成友 韩昧华
聊城大学网络信息中心 山东 252059
近几年来,无论是网络运营商,还是各高校校园网、各单位的局域网等等,都经受了ARP欺骗的攻击。这种攻击带有很大的普遍性,对用户和网管人员影响都非常大。其实,这类攻击大多是来自于蠕虫病毒,发起者电脑通常是在不知情的情况下感染了这类病毒,并在不知情的情况下对同一VLAN内的电脑发起了攻击。根据欺骗的对象可以将 ARP欺骗分为两种类型:欺骗网关型和欺骗主机型。其中,欺骗网关型是指攻击发生时网关内存中维护的IP-MAC对照表被污染,网关找不到真实的主机,致使主机收不到网关的回应包,从而造成上网不正常;而欺骗主机型是指攻击发生时主机缓存中维护的ARP表被污染,网关的真实MAC地址被篡改,致使主机找不到真实的网关,同样造成上网不正常。
(1)每台主机都会在自己的ARP缓冲区(ARP Cache)中建立一个 ARP列表,以存储IP地址和MAC地址(即链路层地址)的映射关系。
(2)当源主机需要将一个数据包发送到目的主机时,会首先检查自己 ARP列表中是否存在该 IP地址对应的MAC地址,如果有,就直接将数据包发送到这个MAC地址;如果没有,就向本地网段发起一个ARP请求的广播包,查询此目的主机对应的MAC地址。此ARP请求数据包里包括源主机的IP地址、MAC地址、以及目的主机的IP地址。
(3)网络中所有的主机收到这个ARP请求后,会检查数据包中的目的IP是否和自己的IP地址一致。如果不相同就忽略此数据包;如果相同,该主机首先将发送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP表中已经存在该IP的信息,则将其覆盖,然后给源主机发送一个 ARP响应数据包,告诉对方自己是它需要查找的MAC地址。
(4)源主机收到这个ARP响应数据包后,将得到的目的主机的IP地址和MAC地址添加到自己的ARP列表中,并利用此信息开始数据的传输。如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。
漏洞一:在工作原理第3条中,当网络节点接收到目的IP地址与自己的IP地址相同的ARP请求报文时,会先将源设备的IP地址和MAC地址添加到自己的ARP缓存表中,若ARP表中已经存在该IP的信息,则将其无条件的覆盖,然后再给源设备发送一个ARP响应报文。在这个过程中,没有任何机制来验证ARP请求报文中源设备的IP地址和MAC地址的真实性。从而给欺骗者留下了漏洞,使得他们可以伪造ARP请求报文,既可以欺骗主机,也可以欺骗网关。当前有些ARP欺骗病毒正是利用了这个漏洞,成批地伪造ARP请求报文。
漏洞二:ARP协议并没有规定必须在接收到ARP请求报文后,才能发送ARP响应报文,这就为别有用心者创造了机会:他们可以人为地制造ARP响应报文,在报文中指定源IP、源MAC、目的IP、目的MAC,通过制造的响应包去修改其它网络设备上的动态ARP缓存。当前的一部分ARP攻击就是利用了这个缺陷,伪造大量的ARP响应报文,去修改其它网络设备的APR缓存表,造成同一广播域中的大量网络设备维护的ARP缓存表错误,不能正常上网。
从上面的分析可以看出,造成欺骗的根本原因在于ARP协议本身存在致命的漏洞,而地址解析的过程又是基于链路层的广播机制,所以要想从根本上杜绝ARP欺骗的发生是不可能的。通过采取积极的防范措施,可以在很大程度上降低ARP欺骗对网络造成的严重影响,但这毕竟增加了许多管理的代价,同时也存在网络质量的降低。在基于Ipv6的下一代互联网中,关于地址解析是如何设计的?能否从根本上杜绝类似问题的出现呢?
在IPv6中,没有专门的地址解析协议,而是利用ICMPv6中的邻居发现协议(Neighbor Discovery Protocol,NDP)来完成的。NDP是Ipv6中的一个基础协议,它实现了Ipv4中的地址解析、重定向和路由器发现等所有功能。对于IPv4,我们无法检测邻居的可达性,而邻居发现协议则定义了一种邻居是否可达的检测机制,同时,还可进行重复IP地址检测。
邻居发现协议采用5种类型的ICMPv6报文来实现各种功能,分别是:
(1)路由器请求RS(Router Solicitation):当接口工作时,主机发送路由器请求消息,要求路由器立即产生路由器通告消息,而不必等待下一个预定时间。
(2)路由器通告RA(Router Advertisement):路由器周期性地通告它的存在以及配置的链路和网络参数,或者对路由器请求消息作出响应。路由器通告消息包含在连接(on-link)确定、地址配置的前缀和跳数限制值等。
(3)邻居请求NS(Neighbor Solicitation):节点发送邻居请求消息来请求邻居的链路层地址,或验证它先前所获得并保存在缓存中的邻居链路层地址的可达性,或者验证它自己的地址在本地链路上是否是惟一的。
(4)邻居通告NA(Neighbor Advertisement):邻居请求消息的响应。节点也可以发送非请求邻居通告来指示链路层地址的变化。
(5)重定向(Redirect):路由器通过重定向消息通知主机。对于特定的目的地址,如果不是最佳的路由,则通知主机到达目的地的最佳下一跳。
其中邻居请求和邻居通告报文共同完成地址解析功能。对于每一个IPv6主机,它为每一个网络接口都要维护下列缓存表:邻居缓存表、目的地缓存表、前缀缓存表和默认路由器缓存表。
在邻居缓存表项中,邻居可达性状态是最关键的信息,规定了5种状态:
(1)不完整(INCOMPLETE):正在进行地址解析,邻居的链路层地址还没确定。
(2)可达(REACHABLE):邻居在最近处于可达状态(在小于10s以前)。
(3)失效(STALE):在数据流发送给该邻居以前邻居是不可达的,并无法验证其可达性。
(4)延迟(DELAY):邻居不再是可达的,同时数据流在最近已经发送给邻居,但不立即对该邻居进行探测,而在一个短时延后发送探测信息,这样就可以为上层协议提供可达性确认。
(5)探测(PROBE):邻居不再是可达的,同时发送单播邻居请求探测以验证可达性。
当一个网络节点要给它的邻居发送数据,但不知道它的链路层地址,这时它就要启动一个地址解析过程。为了更好地理解地址解析过程,您可以参考RFC4861的4.3和4.4,搞清楚邻居请求报文和通告报文的格式。
(1)邻居请求报文的发送
对于支持多播的接口,它需要首先创建一个邻居缓存表项,且设置状态为不完整(INCOMPLETE),然后发送一个目标指向这个邻居的 NS。这个报文发给目标地址的请求节点多播地址,且报文要包括发送者的链路层地址作为源链路层地址选项。
(2)邻居请求报文的接收
当一个NS被接收到,首先要经过有效性(valid)检查:IP hop limit 阈值为255、ICMP校验和有效、ICMP code值为0、target address 不是一个多播地址、若IP Source address是一个未指定地址,那么IP destination address就一定是请求节点多播地址且NS没有包括源链路层地址选项。若有一项检查通不过,这个NS就会被静静的丢掉。
当上述有效性检查都通过了,就要进行第2步操作,根据IP source address是否为未指定地址而采取不同的处理动作:若不是未指定地址,且NS包括源链路层地址选项,那么接收者就应该(SHOULD)为这个源IP地址创建或更新自己的邻居缓存表项,若这个表项不存在,就应该创建一个,且设置其可达性状态为失效,若这个表项已经存在,且接收的源链路层地址不同于缓存表项中链路层地址,那么缓存表项中的链路层地址就应该被新接收的替换,且必须设置其可达性状态为失效;若是未指定地址,则接收者一定不要创建或更新邻居缓存表项。
(3)被请求邻居通告的发送
当接收者创建或更新了邻居缓存表项,作为对NS的回应它就要发送NA。NA中的target address字段值从请求报文的 target address字段中拷贝得来。若请求报文中的目的 IP地址是一个多播地址,那么通告报文必须包含目标链路层地址选项,且若该节点是路由器,必须设置路由器标志为1。如果请求报文的源IP地址是未指定地址,那么节点必须设置请求标志为 0,且发送通告报文给全节点多播地址;否则,必须设置请求标志为1,且给请求的源发送单播通告报文。
(4)邻居通告报文的接收
当一个NA被接收到,首先要经过有效性检查:IP hop limit 阈值为255、ICMP校验和有效、ICMP code值为0、target address 不是一个多播地址、若目的IP地址是一个多播地址那么请求标志就应该为 0。若有一项检查通不过,这个请求报文就应被静静的丢掉。
当上述有效性检查都通过了,这个报文就是有效的通告报文,就可以进行下面的操作。节点开始搜索邻居缓存表以定位包含有目标(target)的表项。如果未找到,那么这个被收到的NA就应该被静静的丢弃。若定位到,则会根据邻居缓存表项的可达性状态、邻居通告消息中的标志和准确的链路层地址等三方面的综合情况来决定采取何种措施。
若可达性状态为不完整,且NA中不包括目标链路层地址选项,节点就应该将这个NA静静地丢弃;若可达性状态为不完整,且NA中包含了目标链路层地址选项,则节点就要完成下面步骤:①将目标链路层地址记录在邻居缓存表项中;②若通告中的请求标志为1,则设置可达性状态为可达,否则设置为失效;③根据通告中的路由器标志设置缓存中IsRouter标志;④节点开始发送数据包。
通过追踪邻居发现协议的RFC和IPv6寻址体系结构的RFC,仔细研究最新的标准草案RFC4861得知,邻居发现协议在许多方面对ARP协议都有改进,这里只对与地址解析相关的方面作理论探讨:
(1)在IPv4中,实现从网络层到链路层地址的解析是靠链路层的广播机制,这在节点数目很大的网络中,会占用大量的带宽,有时还会引起“广播风暴”;而在Ipv6中,这一过程是基于网络层的多播机制实现的,这样就使得在地址解析的过程中,受到地址解析所发送包的影响的节点数大大减少,而且非IPv6节点不会受到影响。
(2)路由器通告包含有链路层地址,这样为了解析路由器的链路层地址就不再需要额外的报文交换。
(3)重定向包含有新的下一跳的链路层地址,那么当主机收到重定向报文时,单独的地址解析过程就不再需要了。
(4)邻居发现协议使用邻居不可达检测机制来检查半连接(half-link)失败情况,从而避免给双向连接缺失的邻居进一步发送流量。而ARP协议不提供这种检测。
(5)通过设置跳数限制(hop limit)为255,邻居发现协议对于偶然或有意地发送ND报文的非连接发送者具有了免疫力;在IPv4中,非连接发送者既可以发送icmp redirect消息,亦可以发送路由器通告消息。
(6)IPv4的ARP运行在数据链路层,这样不同的网络介质就需要不同的ARP协议,例如Ethernet ARP与FDDI ARP就不完全相同;而邻居发现协议运行在网络层,与介质无关,任何网络媒介都可以使用相同的邻居发现协议,同时使得采用更加适合的通用的网络层认证和安全机制成为可能。
(7)当一个有效的(valid)邻居通告消息被收到,邻居缓存表就会被搜索以定位包含有目标(target)的表项。如果未找到,那么这个被收到的邻居通告消息就应该被静静的丢弃。若定位到,则会根据邻居缓存表项的可达性状态、邻居通告消息中的标志和准确的链路层地址等三方面的综合情况来决定采取何种措施。这一点可以保证未经请求的邻居通告消息不能轻易的修改邻居缓存表。而IPv4中的ARP就做不到,它会无条件地增加一条。
(8)当一个节点的链路层地址发生了改变,它希望尽快地通知它的邻居,这时它就会发送一条无请求邻居通告消息(Unsolicited Neighbor Advertisements)。RFC4861规定最多只能发送3条,并且要求间隔时间不得小于RetransTimer。这样就使得伪造的邻居通告消息不能大批量的频繁的发送,从而减轻了这类欺骗给网络造成的影响。
邻居发现协议中的地址解析和IPv4中的ARP相比,它提供了许多改进,并且是非常明显的改进。但是邻居发现协议作为协议自身,它仍然无法完全避免地址解析的欺骗现象,欺骗者仍然可以伪造合法且有效的邻居请求或邻居通告消息,别有用心者仍然可以篡改真实的邻居请求和邻居通告报文,原因是协议本身无法验证IP地址和MAC地址的真实性,也无法确认发送者的真实身份。
但是,正像在前面讨论的那样,邻居发现协议在地址解析方面确确实实做了不少改进,使得欺骗消息不太容易修改邻居缓存表,并且欺骗造成的影响程度也不像IPv4中的ARP欺骗那么严重。并且非常值得称道的是它为我们提供了进一步采取安全措施的平台,也就是邻居发现协议运行在 IPv6之上,属于网络层协议,所以它的安全性可以由IPv6的安全机制来保证。而IPv6协议缺省情况下要求采用安全性相当高的IPSec协议来保证它的安全。IETF提出了增强NDP安全机制的算法 SEND(Secure Neighbor Discovery),并引入CGA(Cryptographically Generated Address)和公钥密码以保证NDP的安全。当前有一些学者在此基础上,又提出了改进的安全算法,比如LL-HBA,以解决计算开销过大的问题。所以下一代的互联网中,地址解析中的欺骗问题是有望彻底解决的。
[1] RFC4861 Neighbor Discovery for IP version 6(IPv6). September 2007.T.Narten AND E.Nordmark AND W.Simpson AND H.Soliman.
[2] 杨志刚,张长河,祝岳飞.Ipv6邻居发现协议安全机制研究[J].计算机应用.2006.