Chapter: 8 (Week 10) Duration: 3 hr Substrate: Wireshark + PCAP files from Labs 3, 4, 6 + Python/tshark Points: 8
Overview
Apply Wireshark's multi-protocol RF dissection capabilities to captures from three protocol families: WiFi 802.11 (from Lab 3), BLE (from Lab 4), and ZigBee 802.15.4 (from Lab 6). Develop cross-protocol analysis skills and write a Lua dissector prototype.
Part 1: 802.11 Decrypted Traffic Analysis (60 min)
Load lab3-capture-01.cap in Wireshark. Add the lab AP's WPA2 PSK (instructor-provided) to Wireshark's decryption key database:
Edit → Preferences → Protocols → IEEE 802.11 → Decryption Keys → Add
Key type: wpa-pwd
Key: <passphrase>:<SSID>
Reload the capture (View → Reload).
Analysis tasks:
-
Apply filter
eapol— identify the 4-way handshake frames. How many handshakes are present? Each represents one client association. -
After adding the PSK, filter
wlan_mgt.fixed.capabilities.privacy == 1 && !eapol && data. These should now be decrypted data frames. Are they? (If not, verify the EAPOL handshake is complete in the capture — all 4 EAPOL messages must be present for Wireshark to derive session keys.) -
Filter
http— are any HTTP requests visible in the decrypted traffic? Document: URL, method, host header (without reproducing full payload content). -
Filter
dns— what hostnames are being resolved? This reveals which services the client was accessing. -
Filter
tls.handshake.type == 1— how many TLS ClientHello frames are present? Note: TLS payload remains encrypted above 802.11; the ClientHello reveals the SNI (server name indication) hostname.
import subprocess
# Extract TLS SNI hostnames from the capture
result = subprocess.run(
['tshark', '-r', 'lab3-capture-01.cap',
'-Y', 'tls.handshake.extensions_server_name',
'-T', 'fields',
'-e', 'tls.handshake.extensions_server_name'],
capture_output=True, text=True
)
sni_hosts = set(line.strip() for line in result.stdout.strip().split('\n') if line.strip())
print("TLS SNI hostnames visible in 802.11 capture:")
for h in sorted(sni_hosts): print(f" {h}")
Part 2: BLE Cross-Protocol Analysis (45 min)
Load lab4-ble-pairing.pcapng alongside a second capture from Part 1. Apply Wireshark's multi-file analysis.
Analysis tasks:
-
Filter
btle.advertising_header.pdu_type == 0(ADV_IND). For each advertising device, note: address type, address, RSSI (from the Nordic BLE metadata). -
Filter
btatt(ATT layer). For each ATT Read Request + ATT Read Response pair:- What is the handle?
- What is the value?
- Using the Bluetooth GATT specification assigned UUIDs (bluetooth.com/specifications/assigned-numbers), what characteristic does this handle correspond to?
-
Filter
btsmp(Security Manager Protocol). How many SMP PDUs are in the capture? List the PDU type codes and their meanings.
Python BLE analysis:
import subprocess
result = subprocess.run(
['tshark', '-r', 'lab4-ble-pairing.pcapng',
'-T', 'fields',
'-e', 'btle.advertising_header.pdu_type',
'-e', 'btle.advertising_address',
'-e', 'btatt.opcode',
'-e', 'btatt.handle',
'-e', 'btatt.value'],
capture_output=True, text=True
)
for line in result.stdout.strip().split('\n')[:40]:
fields = line.split('\t')
if any(f.strip() for f in fields):
print('\t'.join(f or '-' for f in fields))
Part 3: ZigBee ZCL Command Stream Analysis (45 min)
Load lab6-zigbee-mesh.pcapng with the ZigBee network key already added (from Lab 6). Apply the ZigBee ZCL dissector.
Analysis tasks:
-
Filter
zbee_zcl— list all ZCL cluster commands observed. For each: cluster ID, cluster name, command ID, direction (server-to-client or client-to-server), source short address, destination short address. -
Focus on any On/Off cluster (0x0006) commands. Create a timeline: which device sent On (0x01), which sent Off (0x00), and in what order?
-
Filter
zbee_nwk— look at the NWK Frame Counter field. Is it monotonically increasing for each source device? What happens if you observe two frames with the same Frame Counter from the same source? (This would indicate a replay attack.)
tshark ZCL extraction:
import subprocess
result = subprocess.run(
['tshark', '-r', 'lab6-zigbee-mesh.pcapng',
'-T', 'fields',
'-e', 'zbee_zcl.cluster_id',
'-e', 'zbee_zcl.cmd.id',
'-e', 'ieee802154.src16',
'-e', 'ieee802154.dst16'],
capture_output=True, text=True
)
for line in result.stdout.strip().split('\n'):
if line.strip():
print(line)
Part 4: Lua Dissector Prototype (30 min)
Write a minimal Wireshark Lua dissector for a fictional "OOK Remote" protocol (matching the frame structure you would find in Lab 9):
-- File: ~/.config/wireshark/plugins/ook_remote.lua
local myproto = Proto("ook_remote", "OOK Sub-GHz Remote Control")
local f_preamble = ProtoField.bytes ("ook_remote.preamble", "Preamble")
local f_sync = ProtoField.uint16("ook_remote.sync", "Sync Word", base.HEX)
local f_addr = ProtoField.uint8 ("ook_remote.address", "Device Address")
local f_channel = ProtoField.uint8 ("ook_remote.channel", "Channel")
local f_command = ProtoField.uint8 ("ook_remote.command", "Command", base.HEX,
{[0x01]="On", [0x00]="Off", [0x02]="Toggle"})
local f_crc = ProtoField.uint8 ("ook_remote.crc", "CRC-8")
myproto.fields = {f_preamble, f_sync, f_addr, f_channel, f_command, f_crc}
function myproto.dissector(buffer, pinfo, tree)
if buffer:len() < 6 then return end
pinfo.cols.protocol = "OOK_REMOTE"
local t = tree:add(myproto, buffer(), "OOK Remote Control Protocol")
t:add(f_preamble, buffer(0, 1))
t:add(f_sync, buffer(1, 2))
t:add(f_addr, buffer(3, 1))
t:add(f_channel, buffer(4, 1))
t:add(f_command, buffer(5, 1))
if buffer:len() >= 7 then
t:add(f_crc, buffer(6, 1))
end
end
-- Register on UDP port 5555 for testing
DissectorTable.get("udp.port"):add(5555, myproto)
Test the dissector: craft a 7-byte UDP payload matching the format above and send it to localhost:5555:
echo -ne '\xAA\xD3\x91\x42\x01\x01\xB3' | nc -u 127.0.0.1 5555
Open Wireshark on the loopback interface and observe the decoded OOK_REMOTE protocol tree.
Screenshot: Wireshark with the OOK_REMOTE dissector applied and the frame tree expanded.
Deliverables
- Part 1: TLS SNI hostname list (tshark output) + written answers to all analysis questions
- Part 2: tshark BLE output + list of ATT handles and their GATT characteristic names
- Part 3: ZCL command timeline + Frame Counter monotonicity observation
- Part 4: Lua dissector file + Wireshark screenshot with OOK_REMOTE frame tree expanded
Grading (8 points)
| Item | Points |
|---|---|
| Part 1: TLS SNI + 802.11 analysis questions answered | 2 |
| Part 2: BLE ATT handle/characteristic mapping | 2 |
| Part 3: ZCL command timeline + Frame Counter analysis | 2 |
| Part 4: Lua dissector working (screenshot) | 2 |