30_ARP_协议实践,实施_ARP ## 网络协议那些事儿

132 阅读16分钟

30_ARP_协议实践,实施_ARP

网络协议那些事儿

内容简介


  1. 前言

上一课我们学习了 ARP 协议,这一课我们就来实践一下,以加深对知识点的理解。

你应该会对这一课的内容很感兴趣,因为我们将尝试进行网络攻击,以监听与我们连接在同一网络上的另一台机器的流量。

一起来体验一把 hacker(“骇客,黑客”)的滋味吧。

  1. 付诸实践:监听你的邻居

原理

此网络攻击利用了 ARP 协议的运作方式,这也是为什么它被称为 ARP 缓存中毒(ARP Cache Poisoning。poison 表示 “下毒”)的原因。

事实上,我们将使别的机器的 ARP 表被篡改。

理论

在正常情况下,就如我们之前分析过的,一台机器进行 ARP 广播(或称 ARP 请求),​​目标机器通过提供自己的 MAC 地址进行响应。

如果我这台机器不是目标机器,但我也决定使用自己的 MAC 地址进行回复,那会发生什么呢?

例如,我可以静静地等待一个 ARP 请求的发出,此 ARP 请求的目标机器不是我。然后,我等待两秒钟(两秒钟对于机器来说已经是很久了)再响应这个 ARP 请求,我基本可以确定我的响应是在目标机器的响应之后的。

如果我在响应中放入自己的 MAC 地址,那么在发送 ARP 请求的机器的 ARP 表中,与目标机器的 IP 地址相关联的 MAC 地址,将从目标机器的 MAC 地址变为我的 MAC 地址。

我们以下图为例:

我们有三个机器,IP 地址分别是 192.168.0.1、192.168.0.2 和 192.168.0.3。

假设我就是机器 192.168.0.2,我想监听 192.168.0.1 和 192.168.0.3 之间发送的流量。

机器 192.168.0.1 想要向机器 192.168.0.3 发送消息。因此,它首先发送 ARP 请求,以获取 192.168.0.3 的 MAC 地址。

机器 192.168.0.3 立即响应 ARP 请求(它直接发送响应给机器 192.168.0.1,并不需要将响应以广播的形式发送给所有人)。

而我决定在收到 ARP 请求后,过两秒之后再发送响应给机器 192.168.0.1。

收到 192.168.0.3 的第一个响应后,机器 192.168.0.1 将更新自己的 ARP 表。

192.168.0.1 的 ARP 表:

IP 地址MAC 地址
192.168.0.3192.168.0.3 的 MAC 地址

这是正常的情况。

但是,机器 192.168.0.1 将收到一个新的响应,也就是我(机器 192.168.0.2)发送的响应,此响应也会被考虑在内!这将导致 192.168.0.3 这个 IP 地址不再与机器 192.168.0.3 的 MAC 地址相关联,而是与我(机器 192.168.0.2)的 MAC 地址相关联。

192.168.0.1 的 ARP 表:

IP 地址MAC 地址
192.168.0.3192.168.0.2 的 MAC 地址

因此,从现在开始,只要 ARP 表没有被更新或机器 192.168.0.3 没有再发送消息给机器 192.168.0.1,那么机器 192.168.0.1 每次要发送消息给机器 192.168.0.3 时,实际上都会发给我(机器 192.168.0.2),却并不知道自己被欺骗了。

我只需要对机器 192.168.0.3 进行相同的攻击,导致其 ARP 表被篡改,就能够截获这两个机器之间通信的所有流量了!

我就成功地扮演了 “中间人” 的角色,机器 192.168.0.1 和机器 192.168.0.3 以为它们在和彼此对话,但其实它们都把消息发给了我这台机器(192.168.0.2)。因此这种 ARP 攻击属于中间人攻击(Man-in-the-Middle Attack)的一种。

攻击的改进

不过,目前我们的攻击存在两个问题:

  • 如果有一台机器在我之后成功发送了 ARP 响应,则 ARP 表将正确地被更新,攻击将失效;

  • 一段时间后,ARP 表会删除陈旧的记录,攻击将失效。

但是有解决方案,而且正是 ARP 协议的运作方式使这种方案行之有效。实际上,当一台机器收到 ARP 响应时,即使它没有发送 ARP 请求,它也会认为此响应中包含的信息是有效的,并且比其已经拥有的信息更新。

因此,我们不必等待 ARP 请求的发出,就可以做出所谓的响应。

我们可以持续不断地用 ARP 响应去 “轰炸” 要攻击的机器,以确保它的 ARP 表从未正确被更新。只要我们持续进行攻击,我们将确保能截获到所有流量。

听起来都很不错,但是我们怎么做呢?

付诸实践

我们可以使用之前进行路由的实践时创建的那三个虚拟机(Ubuntu01,Ubuntu02 和 Ubuntu03)来实践此 ARP 攻击。

经过之前的课程,你应该对于在 Linux 上修改机器的网络配置比较熟练了。我们用 ifconfig 命令来配置这三台虚拟机的 IP 地址为 192.168.0.1(Ubuntu01)、192.168.0.2(Ubuntu02) 和 192.168.0.3(Ubuntu03)。

在 Ubuntu01 这个虚拟机上,先用 sudo su 命令切换为 root 用户身份,然后运行如下命令:


ifconfig enp0s3 192.168.0.1 netmask 255.255.255.0

  
  


在 Ubuntu02 这个虚拟机上,先用 sudo su 命令切换为 root 用户身份,然后运行如下命令:


ifconfig enp0s3 192.168.0.2 netmask 255.255.255.0

  
  


在 Ubuntu03 这个虚拟机上,先用 sudo su 命令切换为 root 用户身份,然后运行如下命令:


ifconfig enp0s3 192.168.0.3 netmask 255.255.255.0

  
  


好的,配置完三台虚拟机的 IP 地址后,我们可以在机器 192.168.0.1 上运行 ping 192.168.0.3 命令,可以看到 ping 命令成功了。然后,我们用 arp -an 命令来查看这三台机器的 ARP 表。

Ubuntu01 的 ARP 表:

Ubuntu02 的 ARP 表:

Ubuntu03 的 ARP 表:

可以看到,当我们在 Ubuntu01 上运行 ping 192.168.0.3 命令之前,三台虚拟机的 ARP 表都是空的。

当我们在 Ubuntu01 上运行 ping 192.168.0.3 命令之后,Ubuntu01 的 ARP 表增加了一条记录,是 Ubuntu03 的 IP 地址和 Ubuntu03 的 MAC 地址的关联。Ubuntu03 的 MAC 地址是 08:00:27:ed:d8:2c。Ubuntu03 的 ARP 表也增加了一条记录,是 Ubuntu01 的 IP 地址和 Ubuntu01 的 MAC 地址的关联。Ubuntu01 的 MAC 地址是 08:00:27:95:df:47。

现在,让我们转到 IP 地址为 192.168.0.2 的 Ubuntu02 这个虚拟机,为攻击做准备。为此,我们需要能够生成篡改的数据包的软件。这样的软件有不少,我们将使用 Scapy 这个软件。

我们这个实践只会使用 Scapy 的一小部分功能。如果你有兴趣,你可以探索 Scapy 的更多可能用法。

Scapy 的安装

我们目前是在 Ubuntu 这个 Linux 发行版中,如果你在其他操作系统中也没有关系。Scapy 是跨平台的,它是基于跨平台的 Python 语言。

要安装 Scapy,可以参看 Scapy 官方的 安装文档

在我们的 Ubuntu 系统里,安装 Scapy 是比较方便的。首先我们需要确保系统里安装了 Python3(不用 Python2 是因为 Python2 基本已经退出历史舞台,从 2020 年 1 月 1 日开始官方不再更新 Python2),毕竟 Scapy 是基于 Python 的。用以下命令:

可以看到我们的 Ubuntu 服务版里面已经默认安装了 Python3,可以在命令行运行 python3 命令来启动 Python3 的命令解释器来验证一下 Python3 已经安装。要离开 Python 命令解释器,只需要用 Ctrl + D 组合键即可。

确认 Python3 已经安装之后,我们可以用 apt 或 apt-get 这两个 Debian 一族的 Linux 发行版专用的包管理器来安装适合 Python3 的 Scapy,运行以下命令:


sudo apt install python3-scapy

  
  


看到 “Do you want to continue? [Y/n]”(表示 “你要继续吗?”,输入 y 表示继续,n 表示不继续)字样,我们在后面输入 y(y 是 yes 的首字母,表示 “是的”,就是同意安装),再按回车键开始下载安装,等待安装完成。

安装完 Scapy 后,我们运行以下命令来测试 Scapy 的安装情况:

可以看到,Scapy 已经安装成功。要退出 Scapy 的 Python 命令解释器,可以用 Ctrl + D 组合键,就和退出 Python 命令解释器一样。

当然了,你也可以用其他方法来安装 Scapy,我们只是演示了 Ubuntu 中比较方便的一种安装方法。你也可以用 pip 这个 Python 包管理工具来安装。

使用小型自动化脚本

我们将用一个小型的自动化 Python 脚本来完成我们的 ARP “攻击”。我们暂时不会详细研究 Scapy,只是简单使用它的功能。

我们可以用 Vim 这种强大的文本编辑器来创建此脚本文件(当然了,在 Ubuntu 里面,你也可以用 Nano 这样的文本编辑器来创建此脚本),可以命名为 arp_attack.py(attack 表示 “攻击”),运行以下命令:

进入 Vim 之后,按下键盘上的 i 键,就进入了插入模式(可以看到右下角出现 Insert 字样,insert 表示 “插入”):

进入插入模式后,就可以在里面输入字符了。我们输入以下的脚本内容(请注意 Python 中必不可少的行缩进!):


#!/usr/bin/python3

  


# Python script for ARP Cache Poisoning

  


from scapy.all import *

import sys

  


def get_mac_address():

my_macs = [get_if_hwaddr(i) for i in get_if_list()]

for mac in my_macs:

if(mac != "00:00:00:00:00:00"):

return mac

  


Timeout = 2

  


if len(sys.argv) != 3:

print("Usage: arp_attack.py HOST_TO_ATTACK HOST_TO_IMPERSONATE")

sys.exit(1)

  


my_mac = get_mac_address()

if not my_mac:

print("Can not get local MAC address, quitting")

sys.exit(1)

  


packet = Ether()/ARP(op="who-has", hwsrc=my_mac, psrc=sys.argv[2], pdst=sys.argv[1])

  


sendp(packet, loop=1, inter=0.2)

  
  


输入完毕之后,按下键盘左上角的 Esc 键,回到 Vim 的交互模式,然后输入 :x,可以看到左下角会显示 :x,然后按下回车,就保存了刚输入的内容,退出了 Vim。关于 Vim 的用法,你可以选择学习我在慕课网的两门 Linux 课程:

我没有对此 Python 脚本添加注释,因为我们的目标是使用这个 Python 脚本,而不是教大家 Python 编程。如果你想学习 Python 这门很流行的语言,你可以去网上找相关的教程,Python 语言是相对容易上手的。

实施攻击

这个脚本其实很简单。我们需要设置此脚本的权限,使其可被执行,运行以下命令:

现在让我们来测试此脚本。用以下命令运行脚本:

我们不理会第一行的警告(warning 表示 “警告”),这只是一条提示消息,不会阻碍我们。

第二行给出了脚本的使用格式(usage 表示 “用法”)。必须给脚本赋予两个参数,第一个参数(HOST_TO_ATTACK)得用我们要攻击的机器的 IP 地址来替换,第二个参数(HOST_TO_IMPERSONATE)得用我们要冒充的机器的 IP 地址来替换(impersonate 表示 “伪装,模仿,冒充”)。host 表示 “主机”。

让我们尝试攻击一下,我们是 Ubuntu02,我们想要修改 Ubuntu01 的 ARP 表,以便让 Ubuntu01 以为我们是 Ubuntu03。

首先,我们在 Ubuntu01 这台虚拟机上测试一下到 Ubuntu03 这台虚拟机的网络连接,用 ping 192.168.0.3 命令,以便让 Ubuntu01 的 ARP 表中有正确的信息:

然后让我们用 arp -an 命令看一下 Ubuntu01 的 ARP 表:

可以看到 Ubuntu01 的 ARP 表中已经有了一个 IP 地址和 MAC 地址的关联,是 Ubuntu03 的 IP 地址和 Ubuntu03 的 MAC 地址的关联。Ubuntu03 的 MAC 地址是 08:00:27:ed:d8:2c。

现在,让我们在 Ubuntu02 上开始发起对 Ubuntu01 的攻击,以冒充 Ubuntu03。运行以下命令:


./arp_attack.py 192.168.0.1 192.168.0.3

  
  


运行脚本后,输出的每个点代表一个发送的数据包(packet),可以用 Ctrl + C 组合键来结束脚本的运行。可以看到,结束运行时,已经发送了 16 个数据包(Sent 16 packets 表示 “发送了 16 个数据包”)。

现在,让我们用 arp -an 命令来看一下 Ubuntu01 机器的 ARP 表:

可以看到,ARP 表中与 Ubuntu03 的 IP 地址相关联的 MAC 地址已经从 Ubuntu03 的 MAC 地址被修改为了 Ubuntu02 的 MAC 地址!Ubuntu02 的 MAC 地址是 08:00:27:3e:9d:38。

如果在 ARP 表中看到额外的不相关的记录,可以用 arp -d xxx 命令来删除,其中 xxx 要用 IP 地址来替换,就会删掉对应 IP 地址的那个关联记录。

现在,我们在 Ubuntu01 上测试一下到 Ubuntu03 的网络连接,用 ping 192.168.0.3 命令:

可以看到 ping 没有成功(100 % packet loss 表示 “百分之百的丢包”,表示没有 ping 通),为什么呢?

事实上,因为 ARP 表中与 Ubuntu03 的 IP 地址相关联的 MAC 地址已经被篡改为 Ubuntu02 的 MAC 地址,因此 Ubuntu01 将 ping 发送到了 Ubuntu02,而不是 Ubuntu03。

但是,ping 命令的目标 IP 地址是 Ubuntu03 的 IP 地址(192.168.0.3)。我们的 Ubuntu02 不接受不是发给它的 IP 地址的数据包,因为它还不是路由器。所以 ping 请求被 Ubuntu02 丢弃了,所以 ping 会失败。

我们的攻击成功了,但是这样的攻击却不是很隐秘,因为 Ubuntu01 的使用者将会察觉到网络问题,并查找其根源!

如果我们不希望 Ubuntu01 上的使用者察觉到网络问题,那么 Ubuntu01 就须要收到对其 ping 命令的响应。

为了做到这一点,我们只需要让 Ubuntu02 像路由器一样工作即可。我们之前的课程已经设置过了,就是在 Ubuntu02 上运行以下命令来激活路由功能:


echo 1 > /proc/sys/net/ipv4/ip_forward

  
  


现在,我们在 Ubuntu01 上测试一下到 Ubuntu03 的网络连接,用 ping 192.168.0.3 命令:

可以看到,这次 ping 命令成功了。现在 Ubuntu02 成功截获了 Ubuntu01 发给 Ubuntu03 的数据包,但是 Ubuntu01 却丝毫没有察觉到什么异样,Ubuntu02 就能悄悄地监视一切了,哈哈。

攻击的改善

我们已经看到,为了使攻击有效,必须用 ARP 响应对受害者进行 “轰炸”,也就是不间断地发送消息。

现在,我们的脚本每秒发送 5 个数据包(发送频率是由 sendp 方法中的 inter 参数决定的。inter 是 interval 的缩写,表示 “间隔”。我们上面写的脚本里 inter 参数被赋值为 0.2,就表示每隔 0.2 秒发送一个包。1 / 0.2 = 5,每秒发送 5 个数据包)。

如果你想提高发送的频率,可以更改 inter 变量。例如,将其值修改为 0.02(1 / 0.02 = 50,每秒发送 50 个数据包),我们来测试一下:


./arp_attack.py 192.168.0.1 192.168.0.3

  
  


可以看到,这下发送消息的速度明显变快了!

当然了,不一定需要非常快速地 “轰炸”,但在某些情况下快速的攻击还是很有用的。发送数据包的速度越快,Ubuntu01 机器正确更新其 ARP 表的机会就越少。

但是,要注意不要使发送数据包太频繁从而导致网络饱和,并被网络管理员逮住!

但是这样的攻击有什么意义呢?

攻击的后果和目标

我们观察到的第一个结果是,如果我们不激活攻击机器上的路由,则数据包将被丢弃,因此可以切断通信的可能性。这被称为阻断服务,因为它阻止机器访问或提供网络服务。

一旦攻击机器上的路由功能被激活后,我们就可以观察到 192.168.0.1 和 192.168.0.3 之间的通信。让我们尝试看看。

为了可以在一个终端上进行攻击,又可以在另一个终端上监听网络,你可以使用 6 个虚拟终端(tty1 - tty6)中的 2 个,我们之前的课程已经演示过如何进入其他虚拟终端了。使用 Ctrl + Alt + Fx 组合键,其中 x 是虚拟终端的号码。

  • 从 Ubuntu02 的 tty1(也就是登录时所在的终端)上开始发动攻击;

  • 在 Ubuntu01 上运行 ping 命令,ping 192.168.0.3

  • 在 Ubuntu02 的 tty2(用 Ctrl + Alt + F2 进入,然后使用用户名和密码登录,再用 sudo su 命令切换到 root 用户 )上监听,以查看是否能观察到 ping 通。

和路由的实践时一样,我们也将用 tcpdump 命令。在 Ubuntu02 的 tty2 中运行 tcpdump icmp 命令:

我们注意到两件事:

  • 我们可以清楚地看到 ping 请求(request);

  • 但是我们看不到 192.168.0.3 返回的响应(reply)。

为什么我们没有看到 192.168.0.3 的响应呢?

因为我们只向一个方向发动了 ARP 攻击!

我们尚未修改机器 192.168.0.3(也就是 Ubuntu03)的 ARP 表。因此,它不通过 Ubuntu02 而将响应直接返回给 192.168.0.1。

尝试在两个方向上进行攻击,并观察是否能看到对 ping 命令的响应(可以在 Ubuntu02 的两个不同的终端中并行发起两次攻击)。

我会让你自己去实践上述所说的操作,就不演示了,你必须学会靠自己!

如果你在 Ubuntu02 上也能看到对于 ping 命令的响应(reply),就知道两个方向的攻击起作用了。

攻击的进一步改善

我们可以使用这种 ARP 攻击来监听本地网络上两台机器之间的通信。

但是,这种 ARP 攻击只能在本地网络上进行。你没办法监视互联网上的任何人…

但是,网络上是否会有我们想要监听的机器呢?

当然有,例如我们的网关,因为网关可以看到从本地网络上的机器到互联网的所有流量!

如果我发起了对本地网络的一台机器与网关之间通信的攻击,那我就可以看到此机器在互联网上的流量了。

但是我们还可以将攻击进一步改善!

攻击的终极改进

我们可以监听网络中的一台机器和网关之间的流量,但要是能监听网络上所有机器和网关之间的流量,岂不更棒?

为此,我们可以利用目标 IP 地址所在的网络的广播地址来发送攻击,这样就触达网络中的所有机器(当然了,另一方向的攻击将需要对每台机器单独做),就可以监听来自网络上任何机器的流量。

好的,我们已经掌握了 ARP 协议,下一课我们将学习同样很有用的 ICMP 协议。

一起加油吧~

}如果您想了解更多技术资源,欢迎加入点击这里钉钉群交流IT技术资源查看“IT技术交流群一”群的钉钉群号: 129605002953