From 9a3c252c4f95c9147fcdd5ca739439b75d15281f Mon Sep 17 00:00:00 2001 From: evilsocket Date: Fri, 22 Mar 2019 23:31:11 +0100 Subject: [PATCH] new: handshakes history is now loaded from the configured pcap --- modules/wifi/wifi.go | 68 +++++++++++++++++++++------ modules/wifi/wifi_recon.go | 6 +++ modules/wifi/wifi_recon_handshakes.go | 24 ++++++---- 3 files changed, 74 insertions(+), 24 deletions(-) diff --git a/modules/wifi/wifi.go b/modules/wifi/wifi.go index 2007aa62..a61af5e3 100644 --- a/modules/wifi/wifi.go +++ b/modules/wifi/wifi.go @@ -23,21 +23,31 @@ import ( "github.com/evilsocket/islazy/tui" ) +type parsedShake struct { + Radiotap *layers.RadioTap + Dot11 *layers.Dot11 + Packet gopacket.Packet +} + type WiFiModule struct { session.SessionModule - iface *network.Endpoint - handle *pcap.Handle - source string - region string - txPower int - minRSSI int - channel int - hopPeriod time.Duration - hopChanges chan bool - frequencies []int - ap *network.AccessPoint - stickChan int + iface *network.Endpoint + handle *pcap.Handle + source string + region string + txPower int + minRSSI int + channel int + hopPeriod time.Duration + hopChanges chan bool + frequencies []int + ap *network.AccessPoint + stickChan int + + shakesFile string + shakesHistory []parsedShake + skipBroken bool pktSourceChan chan gopacket.Packet pktSourceChanClosed bool @@ -47,7 +57,6 @@ type WiFiModule struct { assocSkip []net.HardwareAddr assocSilent bool assocOpen bool - shakesFile string apRunning bool showManuf bool apConfig packets.Dot11ApConfig @@ -66,6 +75,7 @@ func NewWiFiModule(s *session.Session) *WiFiModule { stickChan: 0, hopPeriod: 250 * time.Millisecond, hopChanges: make(chan bool), + shakesHistory: make([]parsedShake, 0), ap: nil, skipBroken: true, apRunning: false, @@ -510,11 +520,41 @@ func (mod *WiFiModule) updateStats(dot11 *layers.Dot11, packet gopacket.Packet) } } +func (mod *WiFiModule) loadHandshakes() { + mod.shakesHistory = make([]parsedShake, 0) + + if !fs.Exists(mod.shakesFile) { + return + } + + handle, err := pcap.OpenOffline(mod.shakesFile) + if err != nil { + mod.Debug("can't open handshakes file: %v", mod.shakesFile) + return + } + defer handle.Close() + + mod.Info("loading handshakes from %s", mod.shakesFile) + + src := gopacket.NewPacketSource(handle, handle.LinkType()) + for packet := range src.Packets() { + if ok, radiotap, dot11 := packets.Dot11Parse(packet); ok { + mod.shakesHistory = append(mod.shakesHistory, parsedShake{ + Radiotap: radiotap, + Dot11: dot11, + Packet: packet, + }) + } + } +} + func (mod *WiFiModule) Start() error { if err := mod.Configure(); err != nil { return err } + mod.loadHandshakes() + mod.SetRunning(true, func() { // start channel hopper if needed if mod.channel == 0 && mod.source == "" { @@ -551,7 +591,7 @@ func (mod *WiFiModule) Start() error { mod.discoverProbes(radiotap, dot11, packet) mod.discoverAccessPoints(radiotap, dot11, packet) mod.discoverClients(radiotap, dot11, packet) - mod.discoverHandshakes(radiotap, dot11, packet) + mod.discoverHandshakes(radiotap, dot11, packet, false) mod.updateInfo(dot11, packet) mod.updateStats(dot11, packet) } diff --git a/modules/wifi/wifi_recon.go b/modules/wifi/wifi_recon.go index 6e62d0d9..5ec36e0a 100644 --- a/modules/wifi/wifi_recon.go +++ b/modules/wifi/wifi_recon.go @@ -70,6 +70,12 @@ func (mod *WiFiModule) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *la ap.EachClient(func(mac string, station *network.Station) { station.Handshake.SetBeacon(packet) }) + } else { + // every time we detect a new ap, see if we have + // its handshakes in our pcap already + for _, h := range mod.shakesHistory { + mod.discoverHandshakes(h.Radiotap, h.Dot11, h.Packet, true) + } } } else { mod.Debug("skipping %s with %d dBm", from.String(), radiotap.DBMAntennaSignal) diff --git a/modules/wifi/wifi_recon_handshakes.go b/modules/wifi/wifi_recon_handshakes.go index a8eb676e..2896debb 100644 --- a/modules/wifi/wifi_recon_handshakes.go +++ b/modules/wifi/wifi_recon_handshakes.go @@ -18,12 +18,14 @@ func allZeros(s []byte) bool { return true } -func (mod *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) { +func (mod *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet, readOnly bool) { if ok, key, apMac, staMac := packets.Dot11ParseEAPOL(packet, dot11); ok { // first, locate the AP in our list by its BSSID ap, found := mod.Session.WiFi.Get(apMac.String()) if !found { - mod.Warning("could not find AP with BSSID %s", apMac.String()) + if !readOnly { + mod.Warning("could not find AP with BSSID %s", apMac.String()) + } return } @@ -75,7 +77,7 @@ func (mod *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *laye // if we have unsaved packets as part of the handshake, save them. numUnsaved := station.Handshake.NumUnsaved() doSave := numUnsaved > 0 - if doSave && mod.shakesFile != "" { + if !readOnly && doSave && mod.shakesFile != "" { mod.Debug("saving handshake frames to %s", mod.shakesFile) if err := mod.Session.WiFi.SaveHandshakesTo(mod.shakesFile, mod.handle.LinkType()); err != nil { mod.Error("error while saving handshake frames to %s: %s", mod.shakesFile, err) @@ -85,13 +87,15 @@ func (mod *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *laye // if we had unsaved packets and either the handshake is complete // or it contains the PMKID, generate a new event. if doSave && (rawPMKID != nil || station.Handshake.Complete()) { - mod.Session.Events.Add("wifi.client.handshake", HandshakeEvent{ - File: mod.shakesFile, - NewPackets: numUnsaved, - AP: apMac.String(), - Station: staMac.String(), - PMKID: rawPMKID, - }) + if !readOnly { + mod.Session.Events.Add("wifi.client.handshake", HandshakeEvent{ + File: mod.shakesFile, + NewPackets: numUnsaved, + AP: apMac.String(), + Station: staMac.String(), + PMKID: rawPMKID, + }) + } // make sure the info that we have key material for this AP // is persisted even after stations are pruned due to inactivity ap.WithKeyMaterial(true)