Point it at an SSID and it disconnects the devices on that network, including ones that reconnect. You give it the network name; it finds the access point, finds the clients, and picks a disconnection method that fits the network's security.
The old versions only really worked against open-management WPA/WPA2. This one also has vectors for PMF (802.11w) and WPA3, no password needed, though those are broadcast-only and best-effort (see below).
Authorized use only. Run this against networks you own or have written permission to test. Unauthorized deauthentication is illegal in most places.
By default KTO stays whitelist-safe: it sends unicast deauthentication and disassociation, both directions, to each non-whitelisted client it has seen transmit. Whitelisted MACs are never targeted. This drops any client that hasn't negotiated PMF, which covers all of WPA/WPA2 and any non-PMF client on a mixed network.
PMF (802.11w) is the catch. It protects deauth, disassoc, and unicast action frames, so a PMF or WPA3 client ignores every forged per-client frame, including a unicast Channel Switch Announcement. There is no whitelist-safe way around that; it's exactly what PMF is designed to prevent. The only frames that still reach a PMF client are ones that can't be aimed at a single device:
- CSA beacon: a spoofed AP beacon carrying a Channel Switch Announcement that counts clients onto a dead channel. Beacons are never protected, so this gets through, but every client that hears it switches.
- Anonymous reassociation: a reassociation request to the AP with a broadcast source, which makes many APs deauthenticate the broadcast address themselves. The AP does the kick, so PMF never enters into it, but it drops every client.
Both hit the whole BSS and can't honor a whitelist, so they are opt-in via
--broadcast (which also adds a broadcast deauth). Use it when you need to
disconnect PMF/WPA3 clients and can accept that whitelisted devices go down too.
--all-vectors is a synonym for turning the broadcast vectors on.
Bottom line: on WPA2 the whitelist works and per-client deauth is enough. On
WPA3/PMF nothing lands by default, the per-client frames (deauth, and a targeted
CSA too) are protected and ignored, so you have to pass --broadcast to
disconnect those clients, and that takes down the whole BSS, so the whitelist no
longer applies.
One honest caveat: WPA3 with PMF is built to resist forged management frames. No unauthenticated attacker can guarantee a kick against it. These vectors are best-effort and land on many real deployments, but "works on every network" is not a promise anyone can make about WPA3.
Needs a Rust toolchain and iw (from iproute2 / the wireless tools) on the
target machine.
cargo build --release
The binary lands at target/release/kto. Run it as root.
sudo ./target/release/kto -i wlan0 -t "CorpNet" --auto-monitor
Without --auto-monitor the interface has to already be in monitor mode. With
it, KTO switches the interface to monitor on start and back to managed on exit.
If you don't pass -c, it sweeps the common 2.4 and 5 GHz channels to find the
target, then locks onto its channel.
Many home routers advertise one SSID from two radios (2.4 GHz WPA2 and 5 GHz
WPA3, different BSSIDs) for band steering. KTO surveys every BSSID that carries
the SSID and, when more than one shows up, lists them with band and security and
asks which to attack. Pick the one your target device is actually on, or name it
up front with -b/--bssid. This matters: a client on the 5 GHz WPA3 BSSID
won't drop if you attack the 2.4 GHz WPA2 clone.
KTO only deauths clients it has seen transmit, so an idle device may never show
up on its own. If a specific device won't drop while others do, name it with
--client <MAC>; KTO will then hit it every round regardless. Check three
things: it's on the BSSID/band you're attacking, its MAC is the one you expect,
and, for the rare NIC that ignores deauth, try --all-vectors (which adds the
channel-switch and reassociation vectors even on plain WPA2).
More examples:
# already in monitor mode, lock to a known channel
sudo ./target/release/kto -i wlan0mon -t "CorpNet" -c 6
# band-steered SSID: target the exact AP the device is on
sudo ./target/release/kto -i wlan0mon -t "CorpNet" -b 62:a6:dd:6d:0a:24
# WPA3 / PMF: per-client is blocked, so broadcast to kick (whole BSS, no whitelist)
sudo ./target/release/kto -i wlan0mon -t "CorpNet" -b 62:a6:dd:6d:0a:24 --broadcast
# spare your own devices
sudo ./target/release/kto -i wlan0 -t "CorpNet" --auto-monitor -w AA:BB:CC:DD:EE:FF
# passive: list clients, send nothing
sudo ./target/release/kto -i wlan0mon -t "CorpNet" --scan-only
# throw every vector at it regardless of security
sudo ./target/release/kto -i wlan0mon -t "CorpNet" --all-vectors
| Flag | Default | Description |
|---|---|---|
-i, --interface |
required | Wireless interface |
-t, --target |
required | Target SSID |
-b, --bssid |
auto | Target one AP by BSSID (band-steered / multi-AP SSIDs) |
-f, --first |
off | Attack the first matching AP found (skip the picker) |
-c, --channel |
auto | Lock to a channel, skip the discovery sweep |
--client |
none | Always target these MACs, even if idle/unseen |
-w, --whitelist |
none | Comma-separated MACs to spare |
--whitelist-file |
none | File of MACs to spare, one per line (# comments) |
-n, --count |
8 | Frames per burst, per vector |
-s, --sleep |
0.05 | Seconds between attack rounds (small = continuous; raise to throttle) |
--reason |
7 | Deauth reason code (1 unspecified, 4 inactivity, 7 class-3) |
--broadcast |
off | Also use broadcast / AP-wide vectors (ignores the whitelist) |
--scan-only |
off | Discover clients, send nothing |
--auto-monitor |
off | Enable monitor mode on start, restore on exit |
--csa-channel |
14 | Channel the CSA vectors herd clients onto |
--all-vectors |
off | Synonym for --broadcast (turn the broadcast vectors on) |
--no-deauth |
off | Disable deauth/disassoc |
--no-csa |
off | Disable the channel-switch vectors |
--no-anon |
off | Disable anonymous reassociation |
--no-tui |
off | Plain scrolling output instead of the live dashboard |
--no-color |
off | Plain output |
The interface MAC is whitelisted automatically so KTO never targets itself.
On a real terminal KTO runs a full-screen dashboard: target details, a live
client table, an event log, and a TX-rate sparkline, after a short boot
animation. The STATE column is the useful part: UP means the device is still
transmitting (shrugging off the attack), quiet means it has gone silent, and
DOWN means it has been quiet long enough to count as disconnected. Clients
stay listed once seen, and KTO picks them up from association and auth frames as
well as data, so the table keeps working during a broadcast attack, you can
watch each device flip to DOWN as it drops. When several APs share the SSID you
get a list to pick from with the arrow keys.
Press q (or Esc, or Ctrl-C) to quit. Pipe the output somewhere, or pass
--no-tui, and it falls back to plain scrolling logs, which is what you want
for scripts or logging to a file.
Quitting stops cleanly, prints a per-client burst summary, and restores the interface to managed mode if KTO put it into monitor mode.
MIT, see LICENSE.