3. Probe Request/Response交互过程分析

Probe Request/Response交互过程分析 学习卡片

任务目标

捕获WiFi主动扫描过程中的Probe Request与Probe Response帧,解析其关键字段,理解设备如何通过主动扫描发现周围网络。本案例使用Python的Scapy库完成抓包与解析,不依赖额外硬件。

环境依赖

需要Linux系统(推荐Ubuntu 22.04+),无线网卡支持监听模式。安装依赖:

sudo apt update && sudo apt install -y aircrack-ng tshark
pip install scapy

核心实现

以下代码完成三件事:将无线网卡切换至监听模式、捕获Probe Request/Response帧、解析并打印关键字段。代码使用Scapy的Dot11ProbeReq和Dot11ProbeResp层识别帧类型,并提取MAC地址、SSID、支持速率及厂商信息。

#!/usr/bin/env python3
import sys
import time
from scapy.all import *
from scapy.layers.dot11 import Dot11, Dot11ProbeReq, Dot11ProbeResp
from scapy.layers.dhcp import BOOTP  # 确保802.11层完整加载

# 配置参数
IFACE = "wlan0"          # 无线网卡接口名
CHANNEL = 6              # 扫描信道(1/6/11常用)
CAPTURE_SECONDS = 30     # 抓包时长(秒)

def channel_hop():
    """在指定信道上监听(简化版,不跳频)"""
    os.system(f"iwconfig {IFACE} channel {CHANNEL}")

def parse_probe(pkt):
    """解析并打印Probe帧关键信息"""
    if pkt.haslayer(Dot11):
        # 提取MAC地址
        addr2 = pkt.addr2  # 发送方MAC(STA)
        addr3 = pkt.addr3  # 接收方MAC(AP或广播)
        
        # 判断帧类型
        if pkt.haslayer(Dot11ProbeReq):
            frame_type = "Probe Request"
            ssid = pkt.info.decode('utf-8', errors='ignore') if pkt.info else "(广播探测)"
            # 提取支持速率(如有)
            rates = []
            if pkt.haslayer(Rates):
                rates = list(pkt[Rate].rates)
            print(f"[{frame_type}] STA={addr2} → AP={addr3} | SSID: {ssid} | Rates: {rates}")
            
        elif pkt.haslayer(Dot11ProbeResp):
            frame_type = "Probe Response"
            ssid = pkt.info.decode('utf-8', errors='ignore') if pkt.info else "(未知)"
            # 提取厂商信息(Vendor Specific IE)
            vendor = ""
            if pkt.haslayer(VendorSpecific):
                vendor = pkt[VendorSpecific].info.hex()[:16]
            print(f"[{frame_type}] AP={addr2} → STA={addr3} | SSID: {ssid} | Vendor: {vendor}")

def main():
    # 检查root权限
    if os.geteuid() != 0:
        print("请使用sudo运行此脚本")
        sys.exit(1)
    
    # 设置监听模式
    os.system(f"sudo airmon-ng start {IFACE}")
    monitor_iface = f"{IFACE}mon"
    time.sleep(2)  # 等待接口就绪
    
    # 固定信道
    os.system(f"iwconfig {monitor_iface} channel {CHANNEL}")
    print(f"[*] 开始监听信道 {CHANNEL},持续 {CAPTURE_SECONDS} 秒...")
    
    # 抓包并实时解析
    try:
        sniff(iface=monitor_iface, prn=parse_probe, 
              store=False, timeout=CAPTURE_SECONDS)
    except KeyboardInterrupt:
        pass
    finally:
        # 恢复网卡模式
        os.system(f"sudo airmon-ng stop {monitor_iface}")
        print("\n[*] 监听结束,网卡已恢复")

if __name__ == "__main__":
    main()

运行与验证

运行步骤:

  1. 将代码保存为probe_parser.py,修改IFACE变量为你的无线网卡名(通过iwconfig查看)。
  2. 执行:sudo python3 probe_parser.py
  3. 用另一台设备(如手机)关闭WiFi再重新打开,或手动搜索WiFi网络,以触发主动扫描。

通过判定标准:

  • 终端输出包含Probe Request行,其中STA MAC为你的手机/电脑地址,SSID显示(广播探测)或具体网络名。
  • 若附近有AP响应,输出包含Probe Response行,其中AP MAC为路由器地址,SSID为你的WiFi名称。
  • 程序运行30秒后自动退出,网卡恢复管理模式。

常见问题

  • 抓不到任何帧:确认网卡支持监听模式(iw list查看Supported interface modes);尝试切换信道(修改CHANNEL为1或11);靠近AP或设备。
  • 报错Unknown layer:执行scapy进入交互模式,输入ls(Dot11ProbeReq)确认层已加载;若缺失,运行pip install --upgrade scapy。
  • 网卡名称带mon后缀:airmon-ng创建监听接口后,原接口变为wlan0mon格式,代码中已自动拼接,无需手动修改。
主动扫描过程:Probe Request/Response 交互 STA(手机) MAC: 3C:52:82:... AP1(路由器) SSID: HomeWiFi AP2(邻居) SSID: CafeNet ① Probe Request(广播) SSID: 空 / 特定网络名 ② Probe Response(单播) 含SSID、速率、厂商IE 解析要点: • Probe Request 的 addr2 = STA MAC,addr3 = 广播地址 (ff:ff:ff:ff:ff:ff) • Probe Response 的 addr2 = AP MAC,addr3 = STA MAC

解析说明:主动扫描时,STA发送Probe Request(目标MAC为广播地址),可携带特定SSID(定向扫描)或空SSID(广播扫描)。AP收到后回复Probe Response,包含自身支持的速率、信道、加密方式及厂商自定义IE。通过对比Request与Response中的SSID和MAC地址,可完整还原设备探测过程。