Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

wiremax

A Wireshark/tshark dissector for Ubiquiti AirMAX (AC + M) and the companion Mikrotik / RouterBoard vendor Information Elements, written in Lua.

It is the over-the-wire counterpart to pyrmax: the decode logic mirrors that Python package field-for-field. The AC packet format was reverse-engineered from the AirMAX AC firmware binary; the M and RouterBoard layouts come from prior published notes on the older AirMAX-M vendor IE.

AirMAX rides inside 802.11 vendor-specific IEs (tag 221). Wireshark already parses the 802.11 frame and shows the vendor IE as an opaque blob; wiremax takes that blob, decrypts it (AES-128-ECB, key derived from the frame MACs) and renders a parsed, filterable subtree.

Tag: Vendor Specific: Ubiquiti Inc  (built-in 802.11 dissector)
AirMAX AC (Vendor Specific IE)       ← added by wiremax
    Flags: 0x02 ( .... ..1. = Encrypted: True )
    Message Type: Beacon (1)
    Encrypted Length: 48
    [Decrypted payload (AES-128-ECB)]
        [AES Key …: 1f162a13…  (dst=broadcast)]
        Version: 9
        Source MAC: 24:5a:4c:44:57:fd
        Radio MAC (mac_0c): 24:5a:4c:44:57:fd
        Capability Flags: 0x0000003e
        Mixed Mode: 0
        Radioname: LB1
        SSID: labalUBI2
        TLV: Radioname (1), len 3
        TLV: SSID (2), len 9
        TLV: Padding (0)

The decrypted layout depends on Message Type: beacons carry mac_0c / cap_flags / mixed_mode + name TLVs (above); assoc req/resp carry chainmasks, cap_flags and version-gated tail fields (field_9c, rssi, fwname, txpower); probe req is header-only; deauth carries a jiffies nonce and an opaque auth token (and its source MAC is XOR-masked, which wiremax un-masks).

Status

Variant Coverage
AirMAX AC outer header + decrypted shared head (version + src_mac) + per-message-type, version-gated body (beacon, assoc req/resp, probe req, deauth) + name TLVs
AirMAX M outer shell + decrypted 9 documented bytes (version, msg_type, src_mac, enable) + raw rest
RouterBoard (Mikrotik) OUI/type + sub-IEs + device name (cleartext)

Undocumented byte regions are shown raw (Unknown [n:len]), never invented — same discipline as pyrmax and the ac/ knowledge base.

How it works

A postdissector (it does not replace the built-in 802.11 dissector, it runs after it). For each frame it:

  1. reads every wlan.tag.oui plus wlan.sa / wlan.da via Field extractors;
  2. matches the AirMAX AC (00:27:22), M (00:15:6d) or RouterBoard (00:0c:42) OUI — for AC/M it also requires OUI-type FF FF FF, because 00:15:6d is shared with Mikrotik and with another Ubiquiti IE that appears in the same frame;
  3. locates the IE bytes in the frame and, for AC/M, decrypts the payload with AES-128-ECB, key = HMAC-SHA1(dst_mac, src_mac)[:16], trying the captured 802.11 destination first and falling back to broadcast (identity frames use the broadcast key even when unicast) — the winner is the one whose decrypted payload's embedded source MAC matches the 802.11 source;
  4. builds the subtree, exposing the decrypted bytes as their own data source so field selection highlights them.

The crypto (SHA-1, HMAC-SHA1, AES-128 decrypt) is self-contained pure Lua — Wireshark exposes no crypto API to Lua. Payloads are a few 16-byte blocks, so performance is irrelevant. The key is derived from public MACs, so this is obfuscation, not security.

Install / run

One-off (no install):

tshark   -X lua_script:airmax.lua -r capture.pcap -V
wireshark -X lua_script:airmax.lua capture.pcap

Persistent (Wireshark GUI + tshark): put the whole wiremax/ folder in a Personal Lua Plugins directory. The exact path is shown in Wireshark under Help ▸ About Wireshark ▸ Folders ▸ Personal Lua Plugins; the defaults are:

OS Default Personal Lua Plugins path
Linux ~/.local/lib/wireshark/plugins/
macOS ~/.local/lib/wireshark/plugins/ (or ~/.config/wireshark/plugins/)
Windows %APPDATA%\Wireshark\plugins\

A symlink is ideal while iterating — edits are picked up on reload (Ctrl+Shift+L) with no copy step:

ln -s "$PWD" ~/.local/lib/wireshark/plugins/wiremax

Wireshark recursively loads every .lua under the plugin folder; the submodules under wsairmax/ are plain modules (harmless if loaded standalone) and test/selftest.lua no-ops inside Wireshark.

Fields (display filters)

Filter Meaning
airmax.ac.msg_type message type: 1 Beacon, 2 Assoc Req, 3 Assoc Resp, 4 Probe Req, 0xC Deauth
airmax.ac.flags.encrypted encrypted bit (0x02)
airmax.ac.version decrypted format version (the gate; TX emits 9)
airmax.ac.src_mac source MAC from the decrypted head (deauth un-masks it)
airmax.ac.mac_0c beacon radio MAC (BSSID)
airmax.ac.cap_flags + airmax.ac.cap_flags.chanbw/.high_density/.auth_deauth/.compat_11ax capability bitfield (§11)
airmax.ac.radioname, airmax.ac.ssid, airmax.ac.fwname AC name / firmware strings
airmax.ac.jiffies_nonce, airmax.ac.enc_token deauth nonce + opaque auth token
airmax.ac.tlv.tag / .len / .data raw TLV walk
airmax.m.version, airmax.m.msg_type, airmax.m.src_mac, airmax.m.enable M documented fields
airmax.m.unknown_rest undocumented M tail
airmax.rb.device_name RouterBoard device name
airmax.ac.key / airmax.m.key derived AES key (generated, for verification)

Examples:

tshark -r cap.pcap -Y 'airmax.ac.ssid'                 -T fields -e wlan.sa -e airmax.ac.ssid
tshark -r cap.pcap -Y 'airmax.m.msg_type == 1'         -T fields -e airmax.m.src_mac
tshark -r cap.pcap -Y 'airmax.rb.device_name'          -T fields -e airmax.rb.device_name

Captures must be 802.11 monitor mode (radiotap); the management frames carrying the IEs (beacon / probe response / assoc) are unencrypted at the 802.11 layer — only the AirMAX payload inside the IE is AES-wrapped, and wiremax unwraps it.

Tests

test/selftest.lua runs the crypto and decoders under the standalone Lua 5.4 interpreter (no Wireshark), checking against ground-truth vectors plus standard SHA-1 / RFC-2202 HMAC vectors:

lua test/selftest.lua        # from this directory

End-to-end against a real capture (pyrmax ships sample pcaps under tests/samples/):

tshark -X lua_script:airmax.lua -r airmax_ac_beacon.pcap -V
tshark -X lua_script:airmax.lua -r airmax_m_probe_response.pcap -V

Layout

wiremax/
├── airmax.lua            # Wireshark entry: ProtoFields + postdissector + tree
├── wsairmax/             # pure-Lua modules (no Wireshark dependency)
│   ├── util.lua          # hex / MAC helpers
│   ├── sha1.lua          # SHA-1 + HMAC-SHA1
│   ├── aes.lua           # AES-128 ECB decrypt
│   ├── crypto.lua        # key derivation + decrypt (mirrors pyrmax/_crypto.py)
│   ├── ac.lua            # AirMAX AC decoder (outer ksy: airmax_ac; payload hand-written per 09b)
│   ├── m.lua             # AirMAX M decoder       (ksy: airmax_m[_payload])
│   └── routerboard.lua   # RouterBoard decoder    (ksy: routerboard)
├── test/selftest.lua     # standalone-Lua test harness
└── README.md

Caveats

  • M msg_type labels 1 = Beacon per the older AirMAX-M notes, but value 1 is also observed on probe responses — the M message-type space is not fully mapped, so trust the raw number.
  • The AC cleartext length is enc_len, a u16 big-endian (09b §3); the old 1-byte read was accidentally correct only for payloads < 256.
  • AC assoc-req / assoc-resp / deauth layouts are decoded straight from the spec, but the capture corpus has no real AC samples of them yet — only beacon and probe-req are wire-verified. The version < 9 decoders are likewise unverified (TX only emits 9). See the synthetic vectors in test/selftest.lua.
  • Decryption depends on the 802.11 source MAC being present in the capture. If a frame can't be decrypted, the cleartext outer header is still shown with an expert note.

Keeping it in sync with pyrmax

When a field is added/renamed in pyrmax (src/pyrmax/ac.py or its ksy/*.ksy schemas), mirror it in the matching wsairmax/*.lua decoder and, if user-visible, add a ProtoField in airmax.lua. The ground-truth vectors in test/selftest.lua come from the pyrmax sample pcaps, so a divergence will surface there.

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages