ARP 欺骗

目标

尝试一次本地 ARP 欺骗攻击,掌握 ARP 协议及其利用。学会使用 ARP 攻击工具并进行分析。

本篇文章为实验记录,仅供交流学习使用,切勿违法应用,所有文中提到的工具不提供下载。

原理

ARP 协议

在网络中,每台主机会有一个 MAC 地址,而每个网络位置会有一个专属于它的 IP 地址。ARP 协议是将 IP 地址解析为 MAC(硬件地址)的协议。IP 地址和 MAC 地址不存在任何简单的映射关系,网络中的主机也在不停变化中,映射关系在不断改变,ARP 协议利用了主机的高速缓冲,维护了一个从 IP 地址到硬件地址的映射表,这个映射表在动态更新。

若主机 A 要与主机 B 通信,首先会从主机 A 的缓冲中寻找 B 的 IP 地址,如果有,就查出 B 对应的 MAC 地址。若无,就在局域网中广播 ARP 请求(其中有 B 的地址),所有主机都会收到该请求。B 主机收到以后,向 A 主机回复 IP 地址。B 主机也会记录下 A 的 IP 地址和 MAC 地址,以便之后双方高速通信。

ARP 欺骗攻击

ARP 高速缓存根据所接收到的 ARP 协议包随时进行动态更新,它是无状态的协议,不会检查自己是否发过请求包,只要收到目标 MAC 是自己的 ARP 响应数据包或 ARP 广播包,都会接受并缓存。
ARP 协议没有认证机制,只要接收到的协议包是有效的,主机就无条件地根据协议包的内容刷新本机 ARP 缓存,并不检查该协议包的合法性。 因此攻击者可以随时发送虚假 ARP 包更新被攻击主机上的 ARP 缓存,进行地址欺骗或拒绝服务攻击。

ARP 欺骗攻击的类型

  • 拒绝服务攻击:构造响应包,指定协议地址为关键服务的 IP 地址,而 MAC 地址为不存在的虚拟地址。这样,局域网转发给关键服务的数据包都会丢失(因为对应物理地址不存在)。
  • 广播攻击:构造响应包,其中协议地址为网关 IP,而 MAC 地址为广播地址。如此,所有发往网关的数据包都将被广播出来,可能会占用过大带宽,干扰服务,也会泄露局域网结构。
  • MAC 洪泛攻击:攻击者与目标机连接在同一个集线器时,可以将网卡设置为混杂模式,从而能够接收所有经过它的数据流,而不论其目的地址是否是它。当其在交换机不同的端口时,攻击者可向交换机发送大量不同源 MAC 地址的数据包,使得交换机内存不足以存放正确的 MAC 地址和物理端口号的映射关系。交换机降级为集线器模式,从而可以继续使用广播攻击嗅探网络结构。
  • 中间人攻击:攻击者向目标发送虚假应答包,告诉主机 A“主机 B 的 MAC 地址是 MacC(攻击者 MAC)”,告诉主机 B“主机 A 的 MAC 地址是 MacC(攻击者 MAC)”,此时 A 和 B 间通信的数据均被 C 嗅探,而 A 和 B 不能得知这一点(C 会将数据正确地重定向至正确位置)。

实验过程

使用 ARP 攻击工具攻击

本实验使用 WinArpAttacker3.7.0 版完成。监测机的两块网卡分别为:192.168.235.1 00-50-56-C0-00-08 192.168.17.1 00-50-56-C0-00-01

操作系统为 Windows 10 64Bit。

禁止上网

目标机 (A) 地址为 192.168.235.133 00-0C-29-E7-58-4D

操作系统 windows2000。

在 WinArpAttacker 中,扫描到目标主机后,选择攻击 -> 禁止上网,发现 Attack 处变为”BanGateway”,说明攻击过程已经开始。目标机的上网受到了一定的影响。

IP 冲突

目标机 (A) 地址为 192.168.235.133 00-0C-29-E7-58-4D

操作系统 windows2000。

扫描到需要攻击的主机后,选择攻击 -> 定时 IP 冲突(不断 IP 冲突貌似也可以,只是一次发包量的不同,定时 IP 冲突可以方便看到过程),Attack 处变为 IPConflict,证明攻击过程开始。

中间人攻击

目标机 (A) 地址为 192.168.235.133 00-0C-29-E7-58-4D,操作系统 windows2000。

另外一个被监测机 (B) 地址为 192.168.235.134 00-0C-29-9D-2D-F7,操作系统为 Red Hat Linux Enterprise 7.2 64Bit。

顾名思义,中间人攻击需要有两台主机在互相通信(实验中用的是 ping)。所以布置好另外一台主机,先行测试互 ping 成功后,开启 WinArpAttacker,选择两台要监听的主机,选择攻击 -> 监听主机通讯。Attack 处会变为 SniffHosts。

然后让两个虚拟机之间互相 ping。与此同时打开 wireshark 准备进行抓包分析。

编程进行 ARP 攻击

本机安装 winpcap 及其开发包环境,编程运行截图如下:

实验结果及分析

查看本机 (A) 的 ARP 缓存表

第一行的 IP 地址恰好是监测机的 IP 之一,MAC 地址也是监测机的硬件地址。类型为动态。此检测结果也表明其与监测机在同一网段下 (192.168.235.*)。

禁止上网

当执行禁止上网攻击后,靶机的 arp 记录中多了一条 0.0.0.0->01-01-01-01-01-01 的动态路由。经查阅资料可得知,在这里,0.0.0.0 表示 “本网络的本主机”,也表示默认的路由,即所有不满足路由表其他 IP 要求的路由均由该地址进行处理。本主机的 MAC 地址被指定了一个非法的值(01-01-01-01-01-01),理论上会导致发往本机的所有包均丢失。经观察抓包记录,发现监测机不断在向外部广播请求 192.168.235.2 的地址,然而一直得不到回复。

但是,本次测试的这个攻击的强度并没有想象中的大,在虚拟机中也不是所有的网都上不了,可以访问百度主页,只是访问不了贴吧子域名。可能是这部分的缓存完好无损,恰好不需要 0.0.0.0 来默认路由的原因。

IP 冲突

查看 arp 列表并没有异常的地方。检查 attacker 软件的日志,发现了在 IP 冲突攻击前,目的机的 MAC 地址被改成了 01-01-01-01-01-01。本地由于开了保护所以又将 MAC 地址改为了目的机的源 MAC 地址。

检查抓包记录,发现目标机发送了一次 GARP 请求,从 192.168.235.133 发到了 192.168.235.133,这个请求通常用于确认有没有其他主机的 IP 与它相同。

感觉不太对,为什么这个截图和禁止上网的那么像,有 GARP 请求但没有 IP Conflict 错误…… 是不是抓包时用错网卡了?

目的机在 IP 冲突开始的一瞬间报了一个错误。除此以外没有别的影响。

中间人攻击

在靶机开心的互 ping 时,看到 attacker 软件上的日志有了这样两个事件。其中一个是修改目的 IP,监测机 192.168.235.1 在两个主机 192.168.235.133 和 192.168.235.134 间担任了转发者的角色,两个主机并不知道它们通信时 192.168.235.1 在做它们的 “网关”。第二个是修改 MAC 映射,把两个主机的对方 IP 对应的 MAC 地址改成监测机自己的 MAC 网关,这样就实现了对两个机子通信的监听。

对两个机子的抓包结果看不到任何监听的痕迹。从两个目标机的角度来看,它们发现不了被监听的痕迹,也没有相关的第三方流量。

Winpcap 编程攻击

攻击效果如上图,可以看到,成功地实现了 MAC 和 IP 地址的碰撞,它们全部碰撞在同一网关地址 00-50-56-c0-00-08 上,造成了冲突。编程的关键在于 ARP 包的构建,由于 winpcap 提供了发包的 api int pcap_sendpacket(pcap_t *, const u_char *, int),我们剩下的工作就是构建正确的协议头。

  • 根据 ARP 协议包的构成,我们有

    arp_header.h
    1
    2
    3
    4
    5
    6
    pkt->eth_hdr.type = htons(0x0806);
    pkt->arp_hdr.hardware_type = htons(0x1);
    pkt->arp_hdr.protocol_type = htons(0x800);
    pkt->arp_hdr.hardware_len = 6;
    pkt->arp_hdr.protocol_len = 4;
    pkt->arp_hdr.option = htons(0x2);
    • 0x0806 代表该帧封装了 arp 包,硬件类型为以太网 0x1,协议类型为 IP0x0800,硬件地址为 MAC 地址,其长度为 6,协议地址为 IP 地址,其长度为 4,此包封装了 ARP 应答,值为 0x2
      然后,在这里,构造 packet 的目标 IP 和 MAC 地址。

      arp.c
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      if (flag == TO_VICTIM_HOST) {
      for (i = 0; i < MAC_LEN; i++)
      pkt->eth_hdr.dst_mac[i] = pkt->arp_hdr.dst_mac[i] = VICTIM_MAC[i];
      pkt->arp_hdr.src_ip = inet_addr(GATEWAY_IP);
      pkt->arp_hdr.dst_ip = inet_addr(VICTIM_IP);
      }
      else if (flag == TO_VICTIM_GATEWAY) {
      for (i = 0; i < MAC_LEN; i++)
      pkt->eth_hdr.dst_mac[i] = pkt->arp_hdr.dst_mac[i] = GATEWAY_MAC[i];
      pkt->arp_hdr.src_ip = inet_addr(VICTIM_IP);
      pkt->arp_hdr.dst_ip = inet_addr(GATEWAY_IP);
      }
    • 最后在一个循环中,不断发出 arp 请求包。

      arp.c
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      while (1) {
      printf("Press ctrl+C to stop attack...\n");
      if(attack_host){
      if (pcap_sendpacket(handle, (unsigned char *)&pkt_host, sizeof(ARP_PKT)) != 0)
      fprintf(stderr,"\nError sending the packet: \n", pcap_geterr(handle));
      else
      printf("attack %s...\n", VICTIM_IP);
      }
      if(attack_gateway){
      if (pcap_sendpacket(handle, (unsigned char *)&pkt_gateway, sizeof(ARP_PKT)) != 0)
      fprintf(stderr,"\nError sending the packet: \n", pcap_geterr(handle));
      else
      printf("attack %s...\n", GATEWAY_IP);
      }
      }

前述截图中输出了 attack xxx,说明 ARP 包被成功发送。

总结

软件使用方面

  1. WinArpAttacker 的兼容性在 win10 中略差,启动前需要先行调整为兼容模式,以防止闪退。
  2. WinArpAttacker 扫描主机时,要注意选择虚拟机所在的 VMware 网卡,否则扫描不到虚拟机,同时要注意仔细核对目标 ip 和 mac 地址,防止其对正常影响的监测机产生影响,误伤到自己或其他无辜的局域网用户。

ARP 知识方面

掌握了 ARP 网络包的组成和构建,并尝试在结构体的帮助下,使用 C 语言编程实现 ARP 请求包的发送。