From 9b81e5b96a0627b2c3ea136f317a5e3ea1d88b04 Mon Sep 17 00:00:00 2001 From: evilsocket Date: Sat, 17 Feb 2018 05:15:52 +0100 Subject: [PATCH] new: parsing encryption in wifi.recon module ( ref #53 ) --- modules/wifi_recon.go | 22 +++++++++++++++---- modules/wifi_stats.go | 10 +++++++++ packets/dot11.go | 51 ++++++++++++++++++++++++++++++------------- 3 files changed, 64 insertions(+), 19 deletions(-) diff --git a/modules/wifi_recon.go b/modules/wifi_recon.go index b2692c25..74512f24 100644 --- a/modules/wifi_recon.go +++ b/modules/wifi_recon.go @@ -142,7 +142,12 @@ func (w *WiFiRecon) getRow(station *WiFiStation) []string { seen = core.Dim(seen) } + ssid := station.ESSID() + encryption := w.stats.EncryptionOf(station.HW) + if encryption == "OPEN" { + encryption = core.Green(encryption) + } sent := "" bytes := w.stats.SentFrom(station.HW) @@ -159,7 +164,7 @@ func (w *WiFiRecon) getRow(station *WiFiStation) []string { row := []string{ fmt.Sprintf("%d dBm", station.RSSI), bssid, - station.ESSID(), + ssid, station.Vendor, encryption, strconv.Itoa(station.Channel), @@ -227,15 +232,23 @@ func (w *WiFiRecon) Show(by string) error { for _, s := range stations { rows = append(rows, w.getRow(s)) } + nrows := len(rows) columns := []string{"RSSI", "BSSID", "SSID", "Vendor", "Encryption", "Channel", "Sent", "Recvd", "Last Seen"} if w.isApSelected() { // these are clients columns = []string{"RSSI", "MAC", "Vendor", "Channel", "Sent", "Received", "Last Seen"} - fmt.Printf("\n%s clients:\n", w.accessPoint.String()) + + if nrows == 0 { + fmt.Printf("\nNo authenticated clients detected for %s.\n", w.accessPoint.String()) + } else { + fmt.Printf("\n%s clients:\n", w.accessPoint.String()) + } } - w.showTable(columns, rows) + if nrows > 0 { + w.showTable(columns, rows) + } w.Session.Refresh() @@ -265,7 +278,7 @@ func (w *WiFiRecon) Configure() error { } else { w.channel = 0 // we need to start somewhere, this is just to check if - // this OS support switching channel programmatically. + // this OS supports switching channel programmatically. if err = network.SetInterfaceChannel(w.Session.Interface.Name(), 1); err != nil { return err } @@ -369,6 +382,7 @@ func (w *WiFiRecon) updateStats(dot11 *layers.Dot11, packet gopacket.Packet) { } if ok, enc := packets.Dot11ParseEncryption(packet, dot11); ok == true { + w.stats.ResetEncryption(dot11.Address3) for _, e := range enc { w.stats.CollectEncryption(dot11.Address3, e) } diff --git a/modules/wifi_stats.go b/modules/wifi_stats.go index cb345c52..9b666774 100644 --- a/modules/wifi_stats.go +++ b/modules/wifi_stats.go @@ -55,6 +55,16 @@ func (s *WiFiStats) CollectReceived(station net.HardwareAddr, bytes uint64) { } } +func (s *WiFiStats) ResetEncryption(station net.HardwareAddr) { + s.Lock() + defer s.Unlock() + + bssid := station.String() + if sstats, found := s.stats[bssid]; found == true { + sstats.Encryption = make(map[string]bool) + } +} + func (s *WiFiStats) CollectEncryption(station net.HardwareAddr, enc string) { s.Lock() defer s.Unlock() diff --git a/packets/dot11.go b/packets/dot11.go index d0e8f63f..e95e7e1f 100644 --- a/packets/dot11.go +++ b/packets/dot11.go @@ -49,26 +49,47 @@ func Dot11Parse(packet gopacket.Packet) (ok bool, radiotap *layers.RadioTap, dot } func Dot11ParseIDSSID(packet gopacket.Packet) (bool, string) { - dot11infoLayer := packet.Layer(layers.LayerTypeDot11InformationElement) - if dot11infoLayer == nil { - return false, "" + for _, layer := range packet.Layers() { + if layer.LayerType() == layers.LayerTypeDot11InformationElement { + dot11info, ok := layer.(*layers.Dot11InformationElement) + if ok == true && dot11info.ID == layers.Dot11InformationElementIDSSID && len(dot11info.Info) > 0 { + return true, string(dot11info.Info) + } + } } - dot11info, ok := dot11infoLayer.(*layers.Dot11InformationElement) - if ok == false || (dot11info.ID != layers.Dot11InformationElementIDSSID) { - return false, "" - } - - if len(dot11info.Info) == 0 { - return false, "" - } else { - return true, string(dot11info.Info) - } + return false, "" } func Dot11ParseEncryption(packet gopacket.Packet, dot11 *layers.Dot11) (bool, []string) { - // TODO :( - return false, nil + enc := make([]string, 0) + found := false + + if dot11.Flags.WEP() { + found = true + enc = append(enc, "WEP") + } + + for _, layer := range packet.Layers() { + if layer.LayerType() == layers.LayerTypeDot11InformationElement { + info, ok := layer.(*layers.Dot11InformationElement) + if ok == true { + found = true + if info.ID == layers.Dot11InformationElementIDRSNInfo { + enc = append(enc, "WPA2") + } else if info.ID == layers.Dot11InformationElementIDVendor && bytes.Index(info.Info, []byte{0, 0x50, 0xf2, 1, 1, 0}) == 0 { + enc = append(enc, "WPA") + } + } + } + } + + if found && len(enc) == 0 { + enc = append(enc, "OPEN") + } + + return found, enc + } func Dot11IsDataFor(dot11 *layers.Dot11, station net.HardwareAddr) bool {