1、ARP协议简介
在《IP协议》中我们讲解了IP地址相关内容,IP协议中包含了目的IP地址和源IP地址,但是当一台主机把以太网数据帧发送到位于同一局域网上的另一台主机时,是根据48bit的以太网地址来确定目的接口的。设备驱动程序从不检查IP数据报中的目的IP地址。
还记得数据链路层的以太网的协议中,每一个数据包都有一个MAC地址头么?我们知道每一块以太网卡都有一个MAC地址,这个地址是唯一的,那么IP包是如何知道这个MAC地址的?这就是ARP协议的工作。
在OSI模型中ARP协议属于链路层;而在TCP/IP模型中,ARP协议属于网络层。ARP协议数据哪一层,不同的资料有不同的说法,这里不作重点讨论。
ARP(地址解析)协议是一种解析协议,本来主机是完全不知道这个IP对应的是哪个主机的哪个接口,当主机要发送一个IP包的时候,会首先查一下自己的ARP高速缓存(就是一个IP-MAC地址对应表缓存),如果查询的IP-MAC值存不存在,那么主机就向网络发送一个ARP协议广播包,这个广播包里面就有待查询的IP地址,而直接收到这份广播的包的所有主机都会查询自己的IP地址,如果收到广播包的某一个主机发现自己符合条件,那么就准备好一个包含自己的MAC地址的ARP包传送给发送ARP广播的主机,而广播主机拿到ARP包后会更新自己的ARP缓存(就是存放IP-MAC对应表的地方)。发送广播的主机就会用新的ARP缓存数据准备好数据链路层的的数据包发送工作。
2、ARP协议结构
之前的文章《以太网数据包结构》可以看出图表示ARP协议的数据结构。
这里先看一下典型的ARP包的组成结构。
前面12个字节是MAC地址,在《以太网数据包结构》文章中讲解过,接下来是帧类型,其中0806表示是ARP协议帧。接下来,就是ARP数据包部分了,第一个硬件类型字段表示发送方想要知道的硬件接口类型硬件,对于以太网MAC地址,它的值应该为1。协议类型字段表示要映射的协议地址类型,它的值为0x0800时,即表示要映射为IP地址,可以看出,该值与以太网数据帧头中类型字段的值使用相同的一组值。
接下来的两个单字节长度的字段,称为硬件地址长度和协议地址长度,它们分别指出硬件地址和协议地址的长度,长度单位为字节。对于以太网上ARP请求或应答来说,它们的值分别为6和4,代表MAC地址的长度和IP地址的长度。在ARP协议包中留出硬件地址长度字段和协议地址长度字段可以使得ARP协议在任何网络中被使用,而不仅仅只在以太网中。
操作字段op指出ARP数据包的类型,它们可以是ARP请求(值为1)、ARP应答(值为2)、RARP请求(值为3)和RARP应答(值为4),这里我们只关心前两个类型。RARP为逆地址解析协议,这里简单说一下,RARP用于主机启动时获得自己的IP地址。这个过程很简单:主机启动时,广播发送一个RARP请求数据包,数据包中包含了自身的MAC地址,然后等待响应。网络中另一台主机必须设置为监听RARP请求状态,并在收到请求后为该主机分配一个IP地址并返回RARP应答给主机,一旦收到应答,主机就有了IP地址,就可以在后续中使用了。
接下来的四个字段是发送端的以太网MAC地址、发送端的IP地址、目的端的以太网MAC地址和目的端的IP地址。
关于PAD填充字节,请看《以太网数据包结构》有讲解。
注意:在以太网的数据帧头部中和ARP数据包中都有发送端的以太网MAC地址。对于一个ARP请求包来说,除接收方以太网地址外的所有字段都应该被填充相应的值。当接收方主机收到一份给自己的ARP请求报文后,它就把自己的硬件地址填进去,然后将该请求数据包的源主机信息和目的主机信息交换位置,并把操作字段op置为2,最后把该新构建的数据包发送回去,这就是ARP应答。
3、wireshark抓包分析
假设查询IP为192.168.0.103的MAC地址,使用如下命令
- arp -a 192.168.0.103
抓包分析
这里分享下wireshark的抓包文件
链接:https://pan.baidu.com/s/1AWPj85Jb4nmLY8h2yJucUA 提取码:bxjq
4、ARP协议分类
ARP数据包的种类有两种:
一是ARP请求包,它是通过以太网广播的方式发送的,用于向具有某个IP地址的主机发送请求,希望该主机返回其MAC地址;
二是ARP应答包,收到ARP请求的主机会比对该数据包中的IP地址与自己的IP地址是否符合,若是,则该主机向源主机返回一个ARP应答包,向源主机报告自己的MAC地址。源主机通过提取ARP应答包中的相关字段来更新ARP缓存表。
一个典型的arp缓存信息如下,在任意一个系统里面用“arp-a”命令:
都会得到这样的结果。这样的高速缓存是有时限的,一般是20分钟(伯克利系统的衍生系统)。
5、ARP协议应用
基础知识:路由下有两个设备,他们相互知道对方IP和MAC,但是他们不能直接通讯,需要路由做转发,如果两个设备直接用网线连起来,就是直接通讯。
举个栗子
路由下有两个设备,首先一点:每个设备(包括路由),都有自己的ARP缓存表。设备A向局域网下设备B通讯(A设备知道B设备的IP)
情况1:A知道B的MAC地址,也就是在自己的ARP缓存表有设备B,直接封包,交给路由就好。
情况2:A不知道B的MAC地址,也就是在自己的ARP缓存表没有设备B,此时比较不幸,发送数据需要延时发送,首先设备A会向网关(就是路由)ARP请求包(以太网目的地址是FF-FF-FF-FF-FF-FF),这时候分情况A和B。
情况A:路由知道设备B的MAC,也就是自己的ARP缓存表有设备B,把自己的知道的设备B的IP和MAC返给设备A,设备A更新一下,自己的ARP缓存表,按情况1处理。
情况B:路由不知道设备B的MAC,路由就在自己的局域网发送,ARP请求包,去问设备B的MAC。得到之后,再发送给A。A得到MAC地址后按照情况1处理。
上述情况说明,想要网络设备第一次就通讯流畅,必须要局域网内的设备都知道自己的MAC地址,在网络设备开发中我们一般在网络设备首次接入网络后,首先向局域网广播自己的地址信息,称为无回报(gratuitous)ARP请求,这样的一个ARP数据包将告诉其他主机关于自己的信息,其他主机根据各自收到的ARP包更新自己的ARP表项。上文中提到的伯克利系统的衍生系统,ARP的缓存表一般存储20分钟,如果不及时更新,主机会删除“离线”设备的ARP表,因为主机ARP缓存表内存有限,不可能存储无限的ARP表信息。针对这种情况,我们开发网络设备,需要每隔一段时间广播一下自己的地址信息,表示自己“还活着”。但是不能太过频繁发送,频繁发送会被部分型号的路由认为是病毒。
6、ARP攻击
ARP协议有一个很大的漏洞,如果网络中的所有用户都规规矩矩,按照上述流程使用ARP就不会存在任何问题。但如果有恶意的设备收到一个ARP请求包(ARP请求包是广播形式发送的,局域网所有主机都可以收到),它不管包中的IP地址是否和自己相同,都会产生一个ARP应答包,告诉请求的用户:我这台主机的MAC地址就是你请求的目的IP地址匹配的MAC地址。另一方面,由于发送ARP请求的源主机不具备任何容错、认证功能(ARP协议未提供任何机制实现这些功能),这样它便会轻易地相信这条ARP应答,并把它加入到了自己的ARP缓存表中。这样做的后果可想而知,源主机在以后都会将具有该目的P地址的数据包发送到那个恶意的主机上。这样,它能轻松地实现数据的窃听,这也就是我们常常听说的ARP攻击的基本原理。
当PC1发送ARP协议询问PC2的MAC地址时,由于是广播的,PC3也收到了这个ARP请求包,PC3把不属于自己的广播包接收,同时回应一个虚假的回应包,告诉PC1我就是PC2。这样PC1会收到两个回应包(一个正确的IP2-MAC2,一个虚假的IP2-MAC3),但是PC1并不知道到底哪个是真的,所以PC1会做出判断,并且判断后到达的为真,那么怎么让虚假的回应包后到达呢,PC3可以连续不断的发送这样的回应包,总会把哪个正确的回应包覆盖掉。
而后PC1会建立IP2-MAC3这样一条ARP缓存条目,以后当PC1给PC2发送信息的时候,PC1依据OSI模型从上至下在网络层给数据封装目的IP为IP2的包头,在链路层通过查询ARP缓存表封装目的MAC为MAC3的数据帧,送至交换机,根据查询CAM表,发现MAC3对应的接口为Port3,就这样把信息交付到了PC3,完成了一次ARP攻击。
如果ARP攻击严重的话,恶意的网络设备只要在网络内阅读送上门的所有广播的ARP请求数据包,就能偷听到网内所有地址信息,进而监听多台网络设备。
防止办法:
我们可以使用静态ARP缓存表防止ARP攻击,但是缺点是违背了ARP协议的动态地址解析原则。
本文转载自微信公众号「知晓编程」,可以通过以下二维码关注。转载本文请联系知晓编程公众号。