"Wireshark is not a Wi-Fi tool with RF extensions bolted on. It is a protocol dissector engine. The 802.11 dissector, the BLE dissector, the 802.15.4 dissector, and the DOCSIS dissector are all first-class citizens. The RF capture path is just the input."
Lecture (90 min)
10.1 Wireshark RF at Intermediate Depth
WIR-101 used Wireshark primarily for 802.11 dissection. RF-201 covers the full Wireshark RF pipeline: multi-protocol capture, decryption, custom dissectors, and the cross-protocol analysis workflow that Protocol RE requires.
The pcap/pcapng input chain for RF:
Wireshark receives RF captures through several paths:
| Source | Format | Protocol |
|---|---|---|
| Alfa NIC in monitor mode (tcpdump / dumpcap) | PCAP/PCAPNG with 802.11 radiotap | 802.11 all frame types |
| nRF52840 BLE sniffer (extcap plugin) | PCAPNG with Nordic BLE | Bluetooth LE |
| CC2531 / nRF52840 802.15.4 sniffer | PCAPNG with 802.15.4 | ZigBee / Thread / 802.15.4 |
| btmon (HCI logging) | PCAP with DLT_BLUETOOTH_HCI_H4 | Bluetooth Classic HCI |
| ANTSDR E200 → GNU Radio → PCAP sink | PCAPNG with custom DLT | Any (via custom dissector or Lua plugin) |
Radiotap header: 802.11 monitor-mode captures prepend a radiotap header to each frame. Radiotap encodes: receive frequency, signal strength (RSSI), noise, data rate, channel flags (CCK/OFDM/HT/VHT/HE), and hardware-level metadata. Wireshark's 802.11 dissector reads radiotap automatically.
10.2 802.11 Dissection at RF-201 Depth
You know the basics from WIR-101. RF-201 depth adds:
Decryption in Wireshark: Wireshark can decrypt WPA/WPA2-encrypted data frames if you provide the pre-shared key (for PSK) or the raw session keys (for enterprise/EAP). Pre-condition: you must have the 4-way handshake in the capture.
Edit → Preferences → Protocols → IEEE 802.11 → Decryption Keys → Add
Key type: wpa-pwd
Key: passphrase:SSID
# or:
Key type: wpa-psk
Key: <64-hex-character PSK>
After adding the key, View → Reload the capture. Encrypted data frames become visible.
What you can see after decryption:
- Full IP/TCP/UDP payload from the captured clients
- DNS queries, HTTP traffic, TLS ClientHello (but not TLS payload — TLS is end-to-end encrypted above the 802.11 layer)
- DHCP exchanges revealing device hostnames and vendor class identifiers
EAPOL (802.1X / WPA handshake) dissection:
The 4-way handshake runs over EAPOL (Extensible Authentication Protocol over LAN). Wireshark displays each EAPOL message with the key nonces (ANonce, SNonce), the MIC (Message Integrity Code), and the GTK (Group Temporal Key) in Message 3. The display filter eapol isolates the handshake.
Display filters for RF analysis:
# Show all management frames
wlan.fc.type == 0
# Show only beacon frames
wlan.fc.type_subtype == 0x0008
# Show deauth/disassoc
wlan.fc.type_subtype == 0x000c || wlan.fc.type_subtype == 0x000a
# Show frames from specific BSSID
wlan.bssid == aa:bb:cc:dd:ee:ff
# Show EAPOL handshake
eapol
# 802.11 with bad FCS (may indicate injection or interference)
wlan.fcs.status == "Bad"
10.3 Bluetooth Dissection in Wireshark
BLE with nRF52840 extcap: When the nRF52840 sniffer is connected and flashed with the Wireshark extcap firmware, Wireshark shows it as a capture interface. Select it. Wireshark will open a BLE advertising and data channel capture.
Bluetooth dissector layers visible:
Frame N: BLE Advertising PDU
Bluetooth Low Energy
Access Address: 0x8e89bed6 (advertising access address)
PDU Header: ADV_IND (0x00)
Advertising Address: aa:bb:cc:dd:ee:ff (random)
Advertising Data:
Flags: 0x06 (BR/EDR Not Supported, LE General Discoverable)
Complete Local Name: "MyDevice"
Manufacturer Specific: [vendor data]
BLE decryption: Wireshark can decrypt BLE data channel traffic if you provide the Long Term Key (LTK) from the pairing exchange. The LTK is derived from the ECDH shared secret during pairing; it is visible in btmon HCI logs if the pairing is observed on a host with HCI sniffing enabled.
Edit → Preferences → Protocols → Bluetooth → Longterm Keys → Add
Key: <32-hex LTK>
BT Classic HCI dissection (btmon):
# Capture HCI on Linux
sudo btmon -w /tmp/hci-capture.btsnoop
# Open in Wireshark — auto-detects btsnoop format
Wireshark's btsnoop dissector shows LMP, L2CAP, RFCOMM, SDP, HCI command/event.
10.4 ZigBee/802.15.4 Dissection and Decryption
As covered in Week 7, Wireshark can decrypt ZigBee NWK frames with the network key.
ZigBee display filters:
# All 802.15.4 frames
ieee802154
# ZigBee NWK frames
zbee_nwk
# ZigBee APS (application support sublayer)
zbee_aps
# ZigBee ZCL cluster commands
zbee_zcl
# Coordinator beacons
ieee802154.frame_type == 0x00 && ieee802154.src_addr_mode == 0x02
# Door Lock cluster (0x0101) commands
zbee_zcl.cluster_id == 0x0101
Wireshark ZigBee cluster identification: After adding the network key and decrypting, ZCL commands become visible. A door-lock unlock command appears as a ZCL Unlock Door command with the cluster-specific command byte. This is what a ZigBee security audit looks for: which commands are accessible without authentication, and what is the minimum security level required for each cluster.
10.5 Lua Dissectors for Custom Protocols
Wireshark supports custom dissectors in Lua. For protocol RE work, you will often have a protocol that Wireshark does not know. A Lua dissector turns raw bytes into named fields.
-- Simple OOK remote control dissector
local myproto = Proto("ook_remote", "OOK Remote Control")
local preamble_field = ProtoField.bytes("ook_remote.preamble", "Preamble")
local addr_field = ProtoField.uint8("ook_remote.address", "Address")
local cmd_field = ProtoField.uint8("ook_remote.command", "Command")
myproto.fields = {preamble_field, addr_field, cmd_field}
function myproto.dissector(buffer, pinfo, tree)
if buffer:len() < 3 then return end
pinfo.cols.protocol = "OOK_REMOTE"
local subtree = tree:add(myproto, buffer(), "OOK Remote Control")
subtree:add(preamble_field, buffer(0, 1))
subtree:add(addr_field, buffer(1, 1))
subtree:add(cmd_field, buffer(2, 1))
end
-- Register for a custom DLT or via UDP port decode
DissectorTable.get("udp.port"):add(5000, myproto)
Place the .lua file in ~/.config/wireshark/plugins/. Reload Wireshark. Use decode as → myproto to apply the dissector to a capture.
Homework
Reading (1.5 hr):
- Wireshark documentation: "Working with Captured Packets" chapters 6-7 (free at wireshark.org)
- Wireshark developer guide: "Lua Support in Wireshark" — free online
- 802.11 Wireshark wiki: wiki.wireshark.org/IEEE_802.11 (display filter reference)
Hands-on (1.5 hr): Open one capture from each of Labs 3, 4, and 6 in Wireshark. For each:
- Apply the appropriate display filter to show only application-layer frames
- Find one frame of interest and write a 2-3 line analysis (what does this frame say? what security implications does it carry?)
- For Lab 3 (802.11): add your lab network's WPA2 PSK and verify you can decrypt data frames
Key Terms
- Radiotap: per-frame metadata prepended to 802.11 monitor-mode captures; encodes frequency, RSSI, data rate, channel flags
- EAPOL: EAP over LAN; carries the WPA 4-way handshake; required in capture for Wireshark decryption
- extcap: Wireshark's external capture protocol; allows third-party tools (nRF52840 sniffer, USB SDR captures) to appear as capture interfaces
- btsnoop: HCI capture format used by btmon; natively parsed by Wireshark
- Lua dissector: custom Wireshark protocol decoder in Lua; turns raw bytes into named fields in the packet tree
- ZCL (ZigBee Cluster Library): application-layer command/attribute model; visible in Wireshark after ZigBee NWK decryption
- LTK (Long Term Key): BLE link-layer encryption key derived during pairing; needed by Wireshark for BLE traffic decryption