From 573cb17735ff2e58e92867a163773321f28c270e Mon Sep 17 00:00:00 2001 From: evilsocket Date: Thu, 24 Jan 2019 11:17:27 +0100 Subject: [PATCH] new: wifi.show.filter, wifi.show.limit, wifi.show.sort and wifi.show.sort_by parameters to control wifi.show --- modules/{net_recon_show.go => net_show.go} | 0 .../{net_recon_sort.go => net_show_sort.go} | 0 modules/wifi.go | 6 +- modules/wifi_recon_sort.go | 46 --------- modules/wifi_show.go | 68 ++++++++++++- modules/wifi_show_sort.go | 96 +++++++++++++++++++ 6 files changed, 164 insertions(+), 52 deletions(-) rename modules/{net_recon_show.go => net_show.go} (100%) rename modules/{net_recon_sort.go => net_show_sort.go} (100%) delete mode 100644 modules/wifi_recon_sort.go create mode 100644 modules/wifi_show_sort.go diff --git a/modules/net_recon_show.go b/modules/net_show.go similarity index 100% rename from modules/net_recon_show.go rename to modules/net_show.go diff --git a/modules/net_recon_sort.go b/modules/net_show_sort.go similarity index 100% rename from modules/net_recon_sort.go rename to modules/net_show_sort.go diff --git a/modules/wifi.go b/modules/wifi.go index 2ab0c0b0..af044017 100644 --- a/modules/wifi.go +++ b/modules/wifi.go @@ -40,6 +40,7 @@ type WiFiModule struct { writes *sync.WaitGroup reads *sync.WaitGroup chanLock *sync.Mutex + selector *ViewSelector } func NewWiFiModule(s *session.Session) *WiFiModule { @@ -143,9 +144,12 @@ func NewWiFiModule(s *session.Session) *WiFiModule { w.AddHandler(session.NewModuleHandler("wifi.show", "", "Show current wireless stations list (default sorting by essid).", func(args []string) error { - return w.Show("rssi") + return w.Show() })) + w.selector = ViewSelectorFor(&w.SessionModule, "wifi.show", + []string{"rssi", "bssid", "essid", "channel", "encryption", "seen", "sent", "rcvd"}, "rssi") + w.AddHandler(session.NewModuleHandler("wifi.recon.channel", `wifi\.recon\.channel[\s]+([0-9]+(?:[, ]+[0-9]+)*|clear)`, "WiFi channels (comma separated) or 'clear' for channel hopping.", func(args []string) error { diff --git a/modules/wifi_recon_sort.go b/modules/wifi_recon_sort.go deleted file mode 100644 index d650b17e..00000000 --- a/modules/wifi_recon_sort.go +++ /dev/null @@ -1,46 +0,0 @@ -package modules - -import ( - "github.com/bettercap/bettercap/network" -) - -type ByRSSISorter []*network.Station - -func (a ByRSSISorter) Len() int { return len(a) } -func (a ByRSSISorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a ByRSSISorter) Less(i, j int) bool { - if a[i].RSSI == a[j].RSSI { - return a[i].HwAddress < a[j].HwAddress - } - return a[i].RSSI > a[j].RSSI -} - -type ByChannelSorter []*network.Station - -func (a ByChannelSorter) Len() int { return len(a) } -func (a ByChannelSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a ByChannelSorter) Less(i, j int) bool { - if a[i].Frequency == a[j].Frequency { - return a[i].HwAddress < a[j].HwAddress - } - return a[i].Frequency < a[j].Frequency -} - -type ByEssidSorter []*network.Station - -func (a ByEssidSorter) Len() int { return len(a) } -func (a ByEssidSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a ByEssidSorter) Less(i, j int) bool { - if a[i].ESSID() == a[j].ESSID() { - return a[i].HwAddress < a[j].HwAddress - } - return a[i].ESSID() < a[j].ESSID() -} - -type ByWiFiSeenSorter []*network.Station - -func (a ByWiFiSeenSorter) Len() int { return len(a) } -func (a ByWiFiSeenSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a ByWiFiSeenSorter) Less(i, j int) bool { - return a[i].LastSeen.After(a[j].LastSeen) -} diff --git a/modules/wifi_show.go b/modules/wifi_show.go index 973bbe8b..67fe308e 100644 --- a/modules/wifi_show.go +++ b/modules/wifi_show.go @@ -110,30 +110,88 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) { } } -func (w *WiFiModule) Show(by string) error { - var stations []*network.Station +func (w *WiFiModule) doFilter(station *network.Station) bool { + if w.selector.Expression == nil { + return true + } + return w.selector.Expression.MatchString(station.BSSID()) || + w.selector.Expression.MatchString(station.ESSID()) || + w.selector.Expression.MatchString(station.Alias) || + w.selector.Expression.MatchString(station.Vendor) || + w.selector.Expression.MatchString(station.Encryption) +} + +func (w *WiFiModule) doSelection() (err error, stations []*network.Station) { + if err = w.selector.Update(); err != nil { + return + } apSelected := w.isApSelected() if apSelected { if ap, found := w.Session.WiFi.Get(w.ap.HwAddress); found { stations = ap.Clients() } else { - return fmt.Errorf("Could not find station %s", w.ap.HwAddress) + err = fmt.Errorf("Could not find station %s", w.ap.HwAddress) + return } } else { stations = w.Session.WiFi.Stations() } - switch by { + + filtered := []*network.Station{} + for _, station := range stations { + if w.doFilter(station) { + filtered = append(filtered, station) + } + } + stations = filtered + + // "encryption"}, "rssi" + switch w.selector.SortBy { case "seen": sort.Sort(ByWiFiSeenSorter(stations)) case "essid": sort.Sort(ByEssidSorter(stations)) + case "bssid": + sort.Sort(ByBssidSorter(stations)) case "channel": sort.Sort(ByChannelSorter(stations)) + case "sent": + sort.Sort(ByWiFiSentSorter(stations)) + case "rcvd": + sort.Sort(ByWiFiRcvdSorter(stations)) + case "rssi": default: sort.Sort(ByRSSISorter(stations)) } + // default is asc + if w.selector.Sort == "desc" { + // from https://github.com/golang/go/wiki/SliceTricks + for i := len(stations)/2 - 1; i >= 0; i-- { + opp := len(stations) - 1 - i + stations[i], stations[opp] = stations[opp], stations[i] + } + } + + if w.selector.Limit > 0 { + limit := w.selector.Limit + max := len(stations) + if limit > max { + limit = max + } + stations = stations[0:limit] + } + + return +} + +func (w *WiFiModule) Show() (err error) { + var stations []*network.Station + if err, stations = w.doSelection(); err != nil { + return + } + rows := make([][]string, 0) for _, s := range stations { if row, include := w.getRow(s); include { @@ -143,7 +201,7 @@ func (w *WiFiModule) Show(by string) error { nrows := len(rows) columns := []string{"RSSI", "BSSID", "SSID" /* "Vendor", */, "Encryption", "Channel", "Clients", "Sent", "Recvd", "Last Seen"} - if apSelected { + if w.isApSelected() { // these are clients columns = []string{"RSSI", "MAC" /* "Vendor", */, "Channel", "Sent", "Received", "Last Seen"} diff --git a/modules/wifi_show_sort.go b/modules/wifi_show_sort.go new file mode 100644 index 00000000..0ba28c6c --- /dev/null +++ b/modules/wifi_show_sort.go @@ -0,0 +1,96 @@ +package modules + +import ( + "github.com/bettercap/bettercap/network" + "github.com/bettercap/bettercap/packets" + "github.com/bettercap/bettercap/session" +) + +type ByRSSISorter []*network.Station + +func (a ByRSSISorter) Len() int { return len(a) } +func (a ByRSSISorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a ByRSSISorter) Less(i, j int) bool { + return a[i].RSSI < a[j].RSSI +} + +type ByChannelSorter []*network.Station + +func (a ByChannelSorter) Len() int { return len(a) } +func (a ByChannelSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a ByChannelSorter) Less(i, j int) bool { + return a[i].Frequency < a[j].Frequency +} + +type ByBssidSorter []*network.Station + +func (a ByBssidSorter) Len() int { return len(a) } +func (a ByBssidSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a ByBssidSorter) Less(i, j int) bool { + return a[i].BSSID() < a[j].BSSID() +} + +type ByEssidSorter []*network.Station + +func (a ByEssidSorter) Len() int { return len(a) } +func (a ByEssidSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a ByEssidSorter) Less(i, j int) bool { + if a[i].ESSID() == a[j].ESSID() { + return a[i].HwAddress < a[j].HwAddress + } + return a[i].ESSID() < a[j].ESSID() +} + +type ByWiFiSeenSorter []*network.Station + +func (a ByWiFiSeenSorter) Len() int { return len(a) } +func (a ByWiFiSeenSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a ByWiFiSeenSorter) Less(i, j int) bool { + return a[i].LastSeen.Before(a[j].LastSeen) +} + +type ByWiFiSentSorter []*network.Station + +func (a ByWiFiSentSorter) Len() int { return len(a) } +func (a ByWiFiSentSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a ByWiFiSentSorter) Less(i, j int) bool { + session.I.Queue.Lock() + defer session.I.Queue.Unlock() + + var found bool = false + var aTraffic *packets.Traffic = nil + var bTraffic *packets.Traffic = nil + + if aTraffic, found = session.I.Queue.Traffic[a[i].IpAddress]; !found { + aTraffic = &packets.Traffic{} + } + + if bTraffic, found = session.I.Queue.Traffic[a[j].IpAddress]; !found { + bTraffic = &packets.Traffic{} + } + + return bTraffic.Sent > aTraffic.Sent +} + +type ByWiFiRcvdSorter []*network.Station + +func (a ByWiFiRcvdSorter) Len() int { return len(a) } +func (a ByWiFiRcvdSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a ByWiFiRcvdSorter) Less(i, j int) bool { + session.I.Queue.Lock() + defer session.I.Queue.Unlock() + + var found bool = false + var aTraffic *packets.Traffic = nil + var bTraffic *packets.Traffic = nil + + if aTraffic, found = session.I.Queue.Traffic[a[i].IpAddress]; !found { + aTraffic = &packets.Traffic{} + } + + if bTraffic, found = session.I.Queue.Traffic[a[j].IpAddress]; !found { + bTraffic = &packets.Traffic{} + } + + return bTraffic.Received > aTraffic.Received +}