Beacon帧解析:从空中嗅探到网络身份

Beacon帧,说白了就是Wi-Fi网络的「广播名片」。AP每隔100ms左右就会在空中喊一嗓子:「我在这里,我叫这个名,我支持这些速率,加密方式是这样的...」

我刚开始做Wi-Fi抓包时,觉得Beacon帧无非就是看看SSID。后来有一次客户投诉说办公区有干扰源,我抓了上千个Beacon帧,才发现厂商信息、信道宽度、HT Capabilities这些字段才是定位问题的关键。嗯,从那以后我再也不敢小看这个「广播包」了。

核心认知:Beacon帧是802.11管理帧的一种,Type=00,Subtype=1000。它不携带用户数据,但携带了网络的全部「元信息」。

Beacon帧结构:逐层拆解

一个完整的Beacon帧,从物理层到MAC层,再到帧体,层层嵌套。我习惯把它分成三块来看:

  • MAC头部(24字节):Frame Control、Duration、DA(目的地址,通常是广播FF:FF:FF:FF:FF:FF)、SA(源地址,即AP的MAC)、BSSID(基本服务集标识,通常等于AP的MAC)、Sequence Control。
  • 帧体(可变长度):Timestamp、Beacon Interval、Capability Information,后面跟着一串Tagged Parameters(也叫IE,信息元素)。
  • FCS(4字节):帧校验序列,用于检测传输错误。

你想想看,一个Beacon帧最少也就50字节左右,但里面塞了十几甚至二十几个IE。每个IE都有Type、Length、Value三段结构,这就是TLV格式。

字段 长度(字节) 说明
Timestamp 8 AP的64位时间戳,用于同步
Beacon Interval 2 发送间隔,单位TU(1TU=1024μs),默认100
Capability Information 2 能力位图:ESS、IBSS、Privacy、Short Preamble等
SSID (IE 0) 2+可变 Type=0,Length=SSID长度,Value=SSID字符串
Supported Rates (IE 1) 2+可变 支持的速率集,每个速率用7位编码
DS Parameter Set (IE 3) 3 当前信道编号
Vendor Specific (IE 221) 3+可变 厂商自定义信息,OUI+数据

抓包小技巧:在Wireshark中,直接展开"Tagged Parameters"就能看到所有IE。我习惯用过滤表达式 wlan.fc.type_subtype == 8 只显示Beacon帧,然后按BSSID分组统计,一眼就能看出环境中有多少AP。

SSID与BSSID提取:从字节到字符串

SSID就是Wi-Fi的名字,BSSID是AP的MAC地址。提取它们,说白了就是解析IE的过程。

SSID提取:

  • 找到Tag Number = 0的IE。
  • 读取Length字段,得到SSID的字节长度(0~32)。
  • 读取Value字段,就是SSID的ASCII字符串。
  • 如果Length=0,说明是隐藏SSID(后面会讲)。

BSSID提取:

  • 直接取MAC头部的Address 3字段(因为Beacon帧中,Address 3就是BSSID)。
  • 注意:有些AP会使用不同的BSSID和SA(源MAC),但绝大多数情况下BSSID = SA。
// 伪代码示例:从Beacon帧中提取SSID和BSSID
function parseBeacon(packet):
    // 提取BSSID (Address 3, 偏移24字节处)
    bssid = packet[24:30].toMacString()
    
    // 遍历Tagged Parameters
    offset = 36  // MAC头(24) + 固定字段(12) = 36
    while offset < packet.length - 4:  // 减去FCS
        tagType = packet[offset]
        tagLen = packet[offset + 1]
        if tagType == 0:  // SSID
            ssid = packet[offset+2 : offset+2+tagLen].toString()
            if tagLen == 0:
                ssid = "[Hidden SSID]"
            break
        offset += 2 + tagLen
    return {bssid, ssid}

注意:SSID长度最大32字节,但有些厂商会发送超过32字节的SSID(非标行为)。我在一次兼容性测试中遇到过,某品牌AP发送了33字节的SSID,导致部分老旧网卡直接不显示这个网络。抓包一看,IE的Length字段写的是33,但标准规定最大32。这种「野路子」AP,遇到了就得留个心眼。

隐藏SSID探测:它真的「隐藏」了吗?

很多人觉得隐藏SSID就是「我把SSID广播关掉,别人就找不到我了」。其实这是个误解。隐藏SSID的AP仍然在发送Beacon帧,只是把SSID IE的Length设为0,或者填充一个空字符串。

我做过一个实验:在办公室把AP设为隐藏SSID,然后用抓包工具监听。结果呢?Beacon帧照样每秒10个左右在发,只是SSID字段是空的。但注意——

  • Probe Response帧会泄露SSID:当客户端主动发送Probe Request(探测请求)时,AP会回复Probe Response,里面就包含了完整的SSID。
  • 某些AP在Beacon帧的其他IE中也会泄露SSID:比如Vendor Specific IE、或者某些厂商自定义的IE里,可能藏着SSID字符串。

为什么会这样?因为AP需要让已经连接过的客户端知道「我还在」,所以它必须保留SSID信息,只是不在标准位置暴露而已。

隐藏方式 Beacon帧SSID IE Probe Response 能否被扫描到
标准隐藏 Length=0 包含完整SSID 能(但SSID为空)
非标隐藏 填充空字符或随机数据 包含完整SSID 能(但SSID乱码)
完全静默 不发送Beacon 不响应Probe Request 不能(但客户端也无法连接)

探测隐藏SSID的方法:在Wireshark中,用过滤表达式 wlan.tag.number == 0 && wlan.tag.length == 0 找到隐藏SSID的Beacon帧。然后监听后续的Probe Response,或者用主动扫描工具发送针对该BSSID的Probe Request,AP就会乖乖吐出SSID。

厂商信息识别:从OUI到设备指纹

每个网卡厂商都有自己分配的OUI(Organizationally Unique Identifier),即MAC地址的前3个字节。比如00:1A:2B是Cisco,00:0C:43是TP-Link。但Beacon帧里的厂商信息远不止OUI这么简单。

我习惯从三个维度识别厂商:

  • BSSID的OUI:最直接,查OUI数据库就能知道AP的制造商。
  • Vendor Specific IE (IE 221):很多厂商会在Beacon帧里塞自己的私有IE,比如Cisco的CCX、Aruba的VSIE、小米的MiWiFi等。这些IE的Type=221,前3个字节是厂商的OUI,后面是自定义数据。
  • HT/VHT Capabilities中的厂商特征:比如某些厂商对MCS(调制编码方案)的支持范围、对信道带宽的偏好,都有细微差异。
// 解析Vendor Specific IE的示例
function parseVendorIE(packet, offset):
    tagType = packet[offset]       // 应为221 (0xDD)
    tagLen = packet[offset + 1]
    oui = packet[offset+2 : offset+5].toHexString()
    vendorData = packet[offset+5 : offset+2+tagLen]
    
    switch(oui):
        case "00:00:0C":  // Cisco
            // 解析Cisco私有IE
            break
        case "00:0C:43":  // TP-Link
            // 解析TP-Link私有IE
            break
        case "00:1A:2B":  // 其他厂商
            break
    return {oui, vendorData}

实战经验:有一次客户说网络中有「不明AP」干扰,我抓了Beacon帧一看,BSSID的OUI显示是某知名品牌,但Vendor Specific IE里却出现了另一个厂商的OUI。后来确认是有人刷了第三方固件(比如OpenWrt),导致MAC地址没改,但私有IE暴露了真实身份。嗯,这种「伪装AP」在抓包分析中并不少见。

Beacon帧分析知识体系

下面这张图是我自己梳理的Beacon帧分析框架,从帧结构到实际应用,一条线串下来:

Beacon帧分析知识体系 Beacon帧分析知识体系 Beacon帧 MAC头部 (24字节) 帧体 (可变长度) FCS (4字节) Timestamp Beacon Interval Capability Info Tagged Parameters (IE) SSID (IE 0) Supported Rates DS Parameter Set HT Capabilities Vendor IE SSID提取 BSSID提取 隐藏SSID探测 厂商信息识别 应用场景:网络发现 · 干扰定位 · 设备指纹 · 安全审计 · 兼容性测试

这张图把Beacon帧从物理结构到分析目标再到实际应用串了起来。我个人习惯在抓包前先画这么一张图,脑子里有了框架,抓包时就不会迷失在几百个字段里。

实战:用Wireshark快速提取关键信息

说了这么多理论,来点实操。打开Wireshark,抓一个Beacon帧,你会看到类似这样的结构:

Frame 1: 242 bytes on wire (1936 bits)
Radiotap Header v0.0
802.11 Beacon frame, Flags: ....
    Type/Subtype: Beacon (8)
    Frame Control: 0x8008
    .000 0000 0000 0000 = Duration: 0
    DA: Broadcast (ff:ff:ff:ff:ff:ff)
    SA: 00:1a:2b:3c:4d:5e
    BSSID: 00:1a:2b:3c:4d:5e
    ...
Tagged Parameters (174 bytes)
    Tag: SSID (0)
        Tag Number: 0
        Tag Length: 8
        SSID: MyWiFi
    Tag: Supported Rates (1)
        Tag Number: 1
        Tag Length: 8
        Supported Rates: 1(B), 2(B), 5.5(B), 11(B), 6, 9, 12, 18
    Tag: Vendor Specific (221)
        Tag Number: 221
        Tag Length: 7
        OUI: 00-00-0C (Cisco)
        Vendor Specific Data: ...

快速过滤技巧:

  • 只看Beacon帧:wlan.fc.type_subtype == 8
  • 只看某个BSSID:wlan.bssid == 00:1a:2b:3c:4d:5e
  • 只看隐藏SSID:wlan.tag.number == 0 && wlan.tag.length == 0
  • 只看某厂商:wlan.tag.oui == 00:00:0c

嗯,Beacon帧解析这块,说白了就是「读TLV」。你只要掌握了TLV的套路,再复杂的IE也能拆开。下次抓包时,别只看SSID,多看看Vendor IE、HT Capabilities、甚至DS Parameter Set里的信道号,这些信息往往能帮你快速定位问题。