在编写ARP命令之前,需要搞清楚 ARP 是什么?
地址解析协议(Address Resolution Protocol,缩写ARP)是一个通过解析IP地址来找寻数据链路层(MAC)地址的网络传输协议,它在IPv4中极其重要。
和ARP相关有两种协议:
- ARP(Address Resolution Protocol,地址解析协议)是用来将IP地址解析为MAC地址的协议。
- RARP(Reverse Address Resolution Protocol,反向地址解析协议)是用来将MAC地址解析为IP地址的协议。
ARP 工作过程,一句话:主机A要发送一个数据包给主机B之前,先要获取主机B的MAC地址。
今天我们用代码完成这个功能,发送ARP请求报文,携带的目标是IP地址在广播域中询问它MAC地址是什么,收到ARP应答包将其解析。
socket套接字系列的文章,有兴趣的同学可以看看呀~
简单说下实现思路
- 基于
SOCK_PACKET
套接字类型创建socket,实现二层网络接收或发送原始数据包; - 手动封装
Ethernet II
以太帧报文、ARP报文,将目标IP地址封装至ARP包中,组包完成后发送ARP请求数据包; - 最后根据绑定二层网络的socket描述符,接收ARP应答包,并进行解析最终拿到MAC地址。
根据实现思路,来认识下三个新朋友:SOCK_PACKET
套接字类型、Ethernet II
以太帧报文、ARP
报文。
SOCK_PACKET套接字类型
用于在设备驱动程序(OSI模型第2层)级别接收或发送原始数据包。允许用户在物理层之上的用户空间中实现协议模块。创建 SOCK_PACKET
套接字,进程必须在用户空间中具有CAP_NET_RAW
权限能力。
特性
- 底层数据访问:可以直接处理完整的以太网帧,包括 MAC 头部
- 混杂模式支持:可以接收所有经过网络接口的帧,而不仅是发给本机的
- 协议透明:可以处理任意类型的网络协议数据
Ethernet II 报文
Ethernet Ⅱ帧,也称为Ethernet V2帧,网络里最常见的以太帧,是以太网事实标准。如今大多数的TCP/IP应用(如HTTP、FTP、SMTP、POP3等)都是采用Ethernet II帧承载。
字段 | 长度 | 含义 |
---|---|---|
DMAC | 6字节 | 目的MAC地址,IPv4为6字节,该字段标识帧的接收者。 |
SMAC | 6字节 | 源MAC地址,IPv4为6字节,该字段标识帧的发送者。 |
Type | 2字节 | 协议类型。 |
Data | 46~1500字节 | 数据字段,标识帧的负载(可能包含填充位)。 数据字段的最小长度必须为46字节以保证帧长至少为64字节,这意味着传输1字节信息也必须使用46字节的数据字段。 如果填入该字段的信息少于46字节,该字段的其余部分也必须进行填充。数据字段的最大长度为1500字节。 以太帧的长度必须为整数字节,因此帧的负载长度不足整数字节,需插入填充字段以保证数据帧的长度为整数字节。 |
FCS | 4字节 | 帧校验序列FCS(Frame Check Sequence)是为接收者提供判断是否传输错误的一种方法,如果发现错误,丢弃此帧。 |
ARP报文
字段 | 长度(bit) | 含义 |
---|---|---|
Ethernet Address of Destination | 48比特 | 目的MAC地址。发送ARP请求时,为广播的MAC地址,0xFFFF-FFFF-FFFF。 |
Ethernet Address of Sender | 48比特 | 源MAC地址。 |
Hardware Type | 16比特 | 表示硬件地址的类型。对于以太网,该类型的值为“1”。 |
Protocol Type | 16比特 | 表示发送方要映射的协议地址类型。对于IP地址,该值为0x0800。 |
Hardware Length | 8比特 | 表示硬件地址的长度,单位是字节。对于ARP请求或应答来说,该值为6。 |
Protocol Length | 8比特 | 表示协议地址的长度,单位是字节。对于ARP请求或应答来说,该值为4。 |
OP | 16比特 | 操作类型: + 1 ARP请求 + 2 ARP应答 + 3 RARP请求 + 4 RARP应答 |
IP Address of Sender | 32比特 | 发送方的IP地址。 |
IP Address of Destination | 32比特 | 接收方的IP地址。 |
说了这么多理论,让我们进入代码的时间吧~
第一步,首先把Ethernet报文、ARP报文格式按照结构体定义好,Ethernet报文长度14字节、ARP报文长度28字节,总计42字节。
第二步,进行封装ARP数据包
第三步,构建链路层地址并绑定,发送ARP请求数据包
syscall.SockaddrLinkLayer
参数说明
Protocol
网络字节顺序的标准以太网协议类型Ifindex
网络接口的索引编号Hatype
ARP表中定义的类型Pkttype
packet类型Halen
大小为字节为单位
第四步,接收ARP应答包,完成。
完整代码,请查阅代码仓库:https://github.com/hltfaith/go-example/blob/main/arp/arp.go
下面看下效果,代码通过go编译后,执行arp命令参数是目标IP
发送完ARP请求包后,便立即收到对方返回的ARP应答包。
通过抓包的方式,让我们看下数据包的详细结构
此处Destination:
全是f,是我们代码在封装Ethernet报文头时定义的广播包;Opcode:
代表封装ARP报文是作为ARP请求的方式去封装的ARP报文。
在ARP报文中,Opcode:
字段回应了数字2 代表ARP应答包,Sener Mac address:
则是回应的Mac地址。
这里普及下ARP欺骗,它是什么呢?
ARP欺骗或ARP攻击,是针对以太网地址解析协议(ARP)的一种攻击技术,攻击者通过伪造虚假的 ARP 响应包,将自己的 MAC 地址伪装成目标设备的 MAC 地址,导致其他设备错误地更新其 ARP 缓存,从而将通信数据流重定向到攻击者或中断通信。
此种攻击可让攻击者获取局域网上的数据包甚至可篡改数据包,且可让网络上特定计算机或所有计算机无法正常通信。
欺骗过程
- 攻击者向局域网内的设备发送伪造的 ARP 响应包。
- 在这些 ARP 响应包中,攻击者将其 MAC 地址与目标设备(如网关或通信方)的 IP 地址绑定。
- 局域网内的设备接收到伪造的 ARP 响应后,更新其 ARP 缓存,将目标 IP 地址错误地映射到攻击者的 MAC 地址。
如何通过代码,实现ARP欺骗攻击呢?大家可以参考上述代码,自己试着玩一玩~
技术文章持续更新,请大家多多关注呀~~
搜索微信公众号,关注我【 帽儿山的枪手 】