From 0ad426024f44ac9a48762b380b73cfdd9a1ddfcb Mon Sep 17 00:00:00 2001 From: evilsocket Date: Sat, 17 Feb 2018 04:10:37 +0100 Subject: [PATCH] new: parsing RSSI ( ref #53 ) --- modules/wifi.go | 7 +++--- modules/wifi_recon.go | 46 ++++++++++++++++++++++--------------- modules/wifi_recon_sort.go | 19 +++++++++++---- modules/wifi_station.go | 4 +++- modules/wifi_stats.go | 47 ++++++++++++++++++++++++++++++++++---- packets/dot11.go | 5 ++++ 6 files changed, 98 insertions(+), 30 deletions(-) diff --git a/modules/wifi.go b/modules/wifi.go index 25999fac..1ccc595d 100644 --- a/modules/wifi.go +++ b/modules/wifi.go @@ -44,17 +44,18 @@ func (w *WiFi) Remove(mac string) { } } -func (w *WiFi) AddIfNew(ssid, mac string, isAp bool, channel int) *WiFiStation { +func (w *WiFi) AddIfNew(ssid, mac string, isAp bool, channel int, rssi int8) *WiFiStation { w.Lock() defer w.Unlock() mac = network.NormalizeMac(mac) if station, found := w.Stations[mac]; found { - w.Stations[mac].LastSeen = time.Now() + station.LastSeen = time.Now() + station.RSSI = rssi return station } - newStation := NewWiFiStation(ssid, mac, isAp, channel) + newStation := NewWiFiStation(ssid, mac, isAp, channel, rssi) w.Stations[mac] = newStation w.Session.Events.Add("wifi.station.new", newStation) diff --git a/modules/wifi_recon.go b/modules/wifi_recon.go index 2690a0c2..b2692c25 100644 --- a/modules/wifi_recon.go +++ b/modules/wifi_recon.go @@ -100,7 +100,7 @@ func NewWiFiRecon(s *session.Session) *WiFiRecon { w.AddHandler(session.NewModuleHandler("wifi.show", "", "Show current wireless stations list (default sorting by essid).", func(args []string) error { - return w.Show("channel") + return w.Show("rssi") })) w.AddParam(session.NewIntParameter("wifi.recon.channel", @@ -142,6 +142,8 @@ func (w *WiFiRecon) getRow(station *WiFiStation) []string { seen = core.Dim(seen) } + encryption := w.stats.EncryptionOf(station.HW) + sent := "" bytes := w.stats.SentFrom(station.HW) if bytes > 0 { @@ -155,9 +157,11 @@ func (w *WiFiRecon) getRow(station *WiFiStation) []string { } row := []string{ + fmt.Sprintf("%d dBm", station.RSSI), bssid, station.ESSID(), station.Vendor, + encryption, strconv.Itoa(station.Channel), sent, recvd, @@ -165,6 +169,7 @@ func (w *WiFiRecon) getRow(station *WiFiStation) []string { } if w.isApSelected() { row = []string{ + fmt.Sprintf("%d dBm", station.RSSI), bssid, station.Vendor, strconv.Itoa(station.Channel), @@ -209,11 +214,13 @@ func (w *WiFiRecon) Show(by string) error { stations := w.wifi.List() if by == "seen" { - sort.Sort(BywifiSeenSorter(stations)) + sort.Sort(ByWiFiSeenSorter(stations)) } else if by == "essid" { sort.Sort(ByEssidSorter(stations)) - } else { + } else if by == "channel" { sort.Sort(ByChannelSorter(stations)) + } else { + sort.Sort(ByRSSISorter(stations)) } rows := make([][]string, 0) @@ -221,10 +228,10 @@ func (w *WiFiRecon) Show(by string) error { rows = append(rows, w.getRow(s)) } - columns := []string{"BSSID", "SSID", "Vendor", "Channel", "Sent", "Recvd", "Last Seen"} + columns := []string{"RSSI", "BSSID", "SSID", "Vendor", "Encryption", "Channel", "Sent", "Recvd", "Last Seen"} if w.isApSelected() { // these are clients - columns = []string{"MAC", "Vendor", "Channel", "Sent", "Received", "Last Seen"} + columns = []string{"RSSI", "MAC", "Vendor", "Channel", "Sent", "Received", "Last Seen"} fmt.Printf("\n%s clients:\n", w.accessPoint.String()) } @@ -263,7 +270,6 @@ func (w *WiFiRecon) Configure() error { return err } log.Info("WiFi recon active with channel hopping.") - } w.wifi = NewWiFi(w.Session, w.Session.Interface) @@ -337,7 +343,7 @@ func (w *WiFiRecon) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *layer if ok, ssid := packets.Dot11ParseIDSSID(packet); ok == true { bssid := dot11.Address3.String() channel := mhz2chan(int(radiotap.ChannelFrequency)) - w.wifi.AddIfNew(ssid, bssid, true, channel) + w.wifi.AddIfNew(ssid, bssid, true, channel, radiotap.DBMAntennaSignal) } } @@ -346,23 +352,27 @@ func (w *WiFiRecon) discoverClients(radiotap *layers.RadioTap, dot11 *layers.Dot if packets.Dot11IsDataFor(dot11, ap) == true { src := dot11.Address2 channel := mhz2chan(int(radiotap.ChannelFrequency)) - w.wifi.AddIfNew("", src.String(), false, channel) + w.wifi.AddIfNew("", src.String(), false, channel, radiotap.DBMAntennaSignal) } } func (w *WiFiRecon) updateStats(dot11 *layers.Dot11, packet gopacket.Packet) { - // only collect stats from data frames - if dot11.Type.MainType() != layers.Dot11TypeData { - return + // collect stats from data frames + if dot11.Type.MainType() == layers.Dot11TypeData { + bytes := uint64(len(packet.Data())) + + dst := dot11.Address1 + src := dot11.Address2 + + w.stats.CollectReceived(dst, bytes) + w.stats.CollectSent(src, bytes) } - bytes := uint64(len(packet.Data())) - - dst := dot11.Address1 - src := dot11.Address2 - - w.stats.CollectReceived(dst, bytes) - w.stats.CollectSent(src, bytes) + if ok, enc := packets.Dot11ParseEncryption(packet, dot11); ok == true { + for _, e := range enc { + w.stats.CollectEncryption(dot11.Address3, e) + } + } } func (w *WiFiRecon) Start() error { diff --git a/modules/wifi_recon_sort.go b/modules/wifi_recon_sort.go index aba6a0fd..1af352f8 100644 --- a/modules/wifi_recon_sort.go +++ b/modules/wifi_recon_sort.go @@ -1,5 +1,16 @@ package modules +type ByRSSISorter []*WiFiStation + +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 []*WiFiStation func (a ByChannelSorter) Len() int { return len(a) } @@ -22,10 +33,10 @@ func (a ByEssidSorter) Less(i, j int) bool { return a[i].ESSID() < a[j].ESSID() } -type BywifiSeenSorter []*WiFiStation +type ByWiFiSeenSorter []*WiFiStation -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 { +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_station.go b/modules/wifi_station.go index 165b51f0..ab6252bd 100644 --- a/modules/wifi_station.go +++ b/modules/wifi_station.go @@ -8,13 +8,15 @@ type WiFiStation struct { *network.Endpoint IsAP bool Channel int + RSSI int8 } -func NewWiFiStation(essid, bssid string, isAp bool, channel int) *WiFiStation { +func NewWiFiStation(essid, bssid string, isAp bool, channel int, rssi int8) *WiFiStation { return &WiFiStation{ Endpoint: network.NewEndpointNoResolve(network.MonitorModeAddress, bssid, essid, 0), IsAP: isAp, Channel: channel, + RSSI: rssi, } } diff --git a/modules/wifi_stats.go b/modules/wifi_stats.go index 79ec88cb..cb345c52 100644 --- a/modules/wifi_stats.go +++ b/modules/wifi_stats.go @@ -2,12 +2,22 @@ package modules import ( "net" + "strings" "sync" ) type WiFiStationStats struct { - Sent uint64 - Received uint64 + Sent uint64 + Received uint64 + Encryption map[string]bool +} + +func NewWiFiStationStats(sent uint64, recvd uint64) *WiFiStationStats { + return &WiFiStationStats{ + Sent: sent, + Received: recvd, + Encryption: make(map[string]bool), + } } type WiFiStats struct { @@ -29,7 +39,7 @@ func (s *WiFiStats) CollectSent(station net.HardwareAddr, bytes uint64) { if sstats, found := s.stats[bssid]; found == true { sstats.Sent += bytes } else { - s.stats[bssid] = &WiFiStationStats{Sent: bytes} + s.stats[bssid] = NewWiFiStationStats(bytes, 0) } } @@ -41,7 +51,21 @@ func (s *WiFiStats) CollectReceived(station net.HardwareAddr, bytes uint64) { if sstats, found := s.stats[bssid]; found == true { sstats.Received += bytes } else { - s.stats[bssid] = &WiFiStationStats{Received: bytes} + s.stats[bssid] = NewWiFiStationStats(0, bytes) + } +} + +func (s *WiFiStats) CollectEncryption(station net.HardwareAddr, enc string) { + s.Lock() + defer s.Unlock() + + bssid := station.String() + if sstats, found := s.stats[bssid]; found == true { + sstats.Encryption[enc] = true + } else { + stats := NewWiFiStationStats(0, 0) + stats.Encryption[enc] = true + s.stats[bssid] = stats } } @@ -66,3 +90,18 @@ func (s *WiFiStats) SentTo(station net.HardwareAddr) uint64 { } return 0 } + +func (s *WiFiStats) EncryptionOf(station net.HardwareAddr) string { + s.Lock() + defer s.Unlock() + + bssid := station.String() + if sstats, found := s.stats[bssid]; found == true { + unique := make([]string, 0) + for key := range sstats.Encryption { + unique = append(unique, key) + } + return strings.Join(unique, ", ") + } + return "" +} diff --git a/packets/dot11.go b/packets/dot11.go index 0859ead1..d0e8f63f 100644 --- a/packets/dot11.go +++ b/packets/dot11.go @@ -66,6 +66,11 @@ func Dot11ParseIDSSID(packet gopacket.Packet) (bool, string) { } } +func Dot11ParseEncryption(packet gopacket.Packet, dot11 *layers.Dot11) (bool, []string) { + // TODO :( + return false, nil +} + func Dot11IsDataFor(dot11 *layers.Dot11, station net.HardwareAddr) bool { // only check data packets of connected stations if dot11.Type.MainType() != layers.Dot11TypeData {