diff --git a/modules/wifi.go b/modules/wifi.go index b1360e13..65dda502 100644 --- a/modules/wifi.go +++ b/modules/wifi.go @@ -73,7 +73,7 @@ func NewWiFiModule(s *session.Session) *WiFiModule { return err } else if ap, found := w.Session.WiFi.Get(bssid.String()); found { w.ap = ap - w.stickChan = network.Dot11Freq2Chan(ap.Frequency) + w.stickChan = ap.Channel() return nil } return fmt.Errorf("Could not find station with BSSID %s", args[0]) diff --git a/modules/wifi_deauth.go b/modules/wifi_deauth.go index c3ce4990..993657eb 100644 --- a/modules/wifi_deauth.go +++ b/modules/wifi_deauth.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "net" + "sort" "time" "github.com/bettercap/bettercap/log" @@ -53,25 +54,45 @@ func (w *WiFiModule) startDeauth(to net.HardwareAddr) error { w.writes.Add(1) defer w.writes.Done() + type flow struct { + Ap *network.AccessPoint + Client *network.Station + } + + toDeauth := make([]flow, 0) isBcast := network.IsBroadcastMac(to) - found := isBcast for _, ap := range w.Session.WiFi.List() { isAP := bytes.Equal(ap.HW, to) for _, client := range ap.Clients() { if isBcast || isAP || bytes.Equal(client.HW, to) { - found = true - if w.Running() { - log.Info("Deauthing client %s from AP %s ...", client.String(), ap.ESSID()) - w.onChannel(network.Dot11Freq2Chan(ap.Frequency), func() { - w.sendDeauthPacket(ap.HW, client.HW) - }) - } + toDeauth = append(toDeauth, flow{Ap: ap, Client: client}) } } } - if found { - return nil + if len(toDeauth) == 0 { + return fmt.Errorf("%s is an unknown BSSID.", to.String()) + } - return fmt.Errorf("%s is an unknown BSSID.", to.String()) + + // since we need to change the wifi adapter channel for each + // deauth packet, let's sort by channel so we do the minimum + // amount of hops possible + sort.Slice(toDeauth, func(i, j int) bool { + return toDeauth[i].Ap.Channel() < toDeauth[j].Ap.Channel() + }) + + // send the deauth frames + for _, deauth := range toDeauth { + client := deauth.Client + ap := deauth.Ap + if w.Running() { + log.Info("deauthing client %s from AP %s (channel %d)", client.String(), ap.ESSID(), ap.Channel()) + w.onChannel(ap.Channel(), func() { + w.sendDeauthPacket(ap.HW, client.HW) + }) + } + } + + return nil } diff --git a/modules/wifi_show.go b/modules/wifi_show.go index d977d2f8..e74f76aa 100644 --- a/modules/wifi_show.go +++ b/modules/wifi_show.go @@ -78,7 +78,7 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) { fmt.Sprintf("%d dBm", station.RSSI), bssid, /* station.Vendor, */ - strconv.Itoa(network.Dot11Freq2Chan(station.Frequency)), + strconv.Itoa(station.Channel()), sent, recvd, seen, @@ -100,7 +100,7 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) { ssid, /* station.Vendor, */ encryption, - strconv.Itoa(network.Dot11Freq2Chan(station.Frequency)), + strconv.Itoa(station.Channel()), clients, sent, recvd, diff --git a/network/wifi_station.go b/network/wifi_station.go index 48b0a768..df734538 100644 --- a/network/wifi_station.go +++ b/network/wifi_station.go @@ -43,3 +43,7 @@ func (s Station) BSSID() string { func (s *Station) ESSID() string { return s.Hostname } + +func (s *Station) Channel() int { + return Dot11Freq2Chan(s.Frequency) +}