Abusing GTK
Layer: Wi-Fi encryption · Section: NDSS’26 §IV-B · CLI:
--check-gtk-shared
What it is
The GTK is shared with every client on a BSSID. Anyone holding the GTK can produce a broadcast/multicast frame that the AP and every other client will accept as legitimately group-encrypted traffic. AirSnitch turns that into a client-to-client unicast injection by wrapping a unicast IP datagram inside a GTK-encrypted broadcast Wi-Fi frame.
The injected frame, in Scapy notation:
Dot11(addr1=ff:ff:ff:ff:ff:ff, # broadcast receiver
addr2=<AP MAC>, # spoof AP as transmitter
addr3=ff:ff:ff:ff:ff:ff)
/ IP(src=<attacker>, dst=<victim>)
/ <payload>
…then encrypted with the GTK the AP gave to every client on this BSSID.
The victim’s stack receives a broadcast Wi-Fi frame, decrypts it with the GTK (because that’s what broadcasts use), unwraps the IP packet, and — because most OSes accept unicast IP inside an L2 broadcast — delivers it to the destination IP address. The victim accepts it. Client isolation at the AP never enters the picture: the frame went over the air, not through the AP’s bridge.
Why it works
Three reinforcing facts:
- GTK is shared by default. With one valid 4-way handshake on the BSSID, the attacker possesses the same key the AP uses to broadcast.
- Most OSes accept unicast IP in L2 broadcast frames. From NDSS’26 Table IV: macOS, iOS, Android 14, Windows 11 (firewall off) all accept; Ubuntu 22.04 accepts unless
drop_unicast_in_l2_multicast=1is set; Windows 11 with firewall on rejects only the IPv4 case but still accepts IPv6 ping and unicast ARP. - The AP can’t filter what goes over the air. Frames constructed and broadcast by the attacker do not traverse the AP’s bridge, so any AP-side ACL on client-to-client traffic is bypassed.
Persistence after revocation
Most APs do not rotate the GTK when a client leaves. They rotate it on a timer (an hour, a day, sometimes never). So a guest whose access has been revoked retains injection capability until the next rotation. (NDSS’26 §IV-B-1.)
What’s required
- One legitimate association to the victim’s BSSID to capture the GTK from the AP’s 4-way handshake (or from a later group-key handshake — both deliver it).
- A radio that can transmit on the victim’s channel.
- Knowledge of the AP’s MAC (
addr2), trivially observable. - Knowledge of the victim’s IP address.
What’s not required
- Knowing the victim’s PTK or PMK.
- Being on the same physical AP, as long as the attacker can hear the victim’s BSSID well enough to transmit on it.
- Defeating Wi-Fi encryption — the attack uses encryption as designed.
CLI
./airsnitch.py wlan2 --check-gtk-shared wlan3 --no-ssid-check [--other-bss | --same-bss]
Saves both NICs’ GTKs after association. If the two GTKs are the same, the network is vulnerable: the attacker (wlan3) can encrypt frames under the GTK the victim (wlan2) trusts. (README §4.1.)
A second AirSnitch test exists for the close cousin Broadcast Reflection (--c2c-broadcast), which reaches the same outcome via the AP rather than directly over the air, and does not require knowing the GTK at all.
What the test actually outputs
>>> The victim's GTK is (XXX).
>>> The attacker's GTK is (YYY).
If XXX == YYY: vulnerable.
For the OS-acceptance side of the picture, AirSnitch’s --c2c-gtk-inject test sends an actual GTK-wrapped ICMP echo and checks for a reply. README §7 notes this requires the test machine to have drop_unicast_in_l2_multicast=0 because the simulated victim and attacker are both Linux.
Combined with other attacks
- Port stealing: the attacker first steals the victim’s port to intercept downlink, then uses GTK abuse to return the intercepted traffic to the victim, completing a downlink MitM (NDSS’26 §VI-A).
- Passpoint flaws: when the AP correctly randomizes GTK in the 4-way handshake, an attacker forces the AP to deliver the real shared GTK during FT, FILS, group-key handshake, or via a forged WNM-Sleep Response. Then GTK abuse becomes possible again.
- = ARP over GTK: same envelope, ARP payload instead of IP. Bypasses the entire family of router-side ARP defences (DAI, DHCP-snooping ARP filtering, IP-MAC binding,
ebtablesonbr-lan) because the malicious frame never crosses the bridge.
What stops it
- Per-client randomized GTK in every handshake (Passpoint DGAF Disable extended to FT/FILS/group-key/WNM).
- OS-level filtering of unicast IP inside L2 broadcasts: Linux
drop_unicast_in_l2_multicast=1, but only for IPv4 — IPv6 and ARP still pass. (NDSS’26 §VII-C and Table IV.) - VLANs with
gtk-per-vlanat minimum, full per-client VLANs ideally. - MACsec between Wi-Fi clients and the gateway (NDSS’26 §VIII-C).
Test it on your network
sudo ./airsnitch.py wlan2 --check-gtk-shared wlan3 --no-ssid-check --same-bss
sudo ./airsnitch.py wlan2 --check-gtk-shared wlan3 --no-ssid-check --other-bss
sudo ./airsnitch.py wlan2 --c2c-gtk-inject wlan3 --no-ssid-check --same-bss
The first two tell you whether the GTK is shared. The third confirms the OS accepts a forged unicast-in-broadcast injection.
