new: handshakes history is now loaded from the configured pcap

This commit is contained in:
evilsocket 2019-03-22 23:31:11 +01:00
commit 9a3c252c4f
No known key found for this signature in database
GPG key ID: 1564D7F30393A456
3 changed files with 74 additions and 24 deletions

View file

@ -23,21 +23,31 @@ import (
"github.com/evilsocket/islazy/tui" "github.com/evilsocket/islazy/tui"
) )
type parsedShake struct {
Radiotap *layers.RadioTap
Dot11 *layers.Dot11
Packet gopacket.Packet
}
type WiFiModule struct { type WiFiModule struct {
session.SessionModule session.SessionModule
iface *network.Endpoint iface *network.Endpoint
handle *pcap.Handle handle *pcap.Handle
source string source string
region string region string
txPower int txPower int
minRSSI int minRSSI int
channel int channel int
hopPeriod time.Duration hopPeriod time.Duration
hopChanges chan bool hopChanges chan bool
frequencies []int frequencies []int
ap *network.AccessPoint ap *network.AccessPoint
stickChan int stickChan int
shakesFile string
shakesHistory []parsedShake
skipBroken bool skipBroken bool
pktSourceChan chan gopacket.Packet pktSourceChan chan gopacket.Packet
pktSourceChanClosed bool pktSourceChanClosed bool
@ -47,7 +57,6 @@ type WiFiModule struct {
assocSkip []net.HardwareAddr assocSkip []net.HardwareAddr
assocSilent bool assocSilent bool
assocOpen bool assocOpen bool
shakesFile string
apRunning bool apRunning bool
showManuf bool showManuf bool
apConfig packets.Dot11ApConfig apConfig packets.Dot11ApConfig
@ -66,6 +75,7 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
stickChan: 0, stickChan: 0,
hopPeriod: 250 * time.Millisecond, hopPeriod: 250 * time.Millisecond,
hopChanges: make(chan bool), hopChanges: make(chan bool),
shakesHistory: make([]parsedShake, 0),
ap: nil, ap: nil,
skipBroken: true, skipBroken: true,
apRunning: false, 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 { func (mod *WiFiModule) Start() error {
if err := mod.Configure(); err != nil { if err := mod.Configure(); err != nil {
return err return err
} }
mod.loadHandshakes()
mod.SetRunning(true, func() { mod.SetRunning(true, func() {
// start channel hopper if needed // start channel hopper if needed
if mod.channel == 0 && mod.source == "" { if mod.channel == 0 && mod.source == "" {
@ -551,7 +591,7 @@ func (mod *WiFiModule) Start() error {
mod.discoverProbes(radiotap, dot11, packet) mod.discoverProbes(radiotap, dot11, packet)
mod.discoverAccessPoints(radiotap, dot11, packet) mod.discoverAccessPoints(radiotap, dot11, packet)
mod.discoverClients(radiotap, dot11, packet) mod.discoverClients(radiotap, dot11, packet)
mod.discoverHandshakes(radiotap, dot11, packet) mod.discoverHandshakes(radiotap, dot11, packet, false)
mod.updateInfo(dot11, packet) mod.updateInfo(dot11, packet)
mod.updateStats(dot11, packet) mod.updateStats(dot11, packet)
} }

View file

@ -70,6 +70,12 @@ func (mod *WiFiModule) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *la
ap.EachClient(func(mac string, station *network.Station) { ap.EachClient(func(mac string, station *network.Station) {
station.Handshake.SetBeacon(packet) 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 { } else {
mod.Debug("skipping %s with %d dBm", from.String(), radiotap.DBMAntennaSignal) mod.Debug("skipping %s with %d dBm", from.String(), radiotap.DBMAntennaSignal)

View file

@ -18,12 +18,14 @@ func allZeros(s []byte) bool {
return true 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 { if ok, key, apMac, staMac := packets.Dot11ParseEAPOL(packet, dot11); ok {
// first, locate the AP in our list by its BSSID // first, locate the AP in our list by its BSSID
ap, found := mod.Session.WiFi.Get(apMac.String()) ap, found := mod.Session.WiFi.Get(apMac.String())
if !found { 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 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. // if we have unsaved packets as part of the handshake, save them.
numUnsaved := station.Handshake.NumUnsaved() numUnsaved := station.Handshake.NumUnsaved()
doSave := numUnsaved > 0 doSave := numUnsaved > 0
if doSave && mod.shakesFile != "" { if !readOnly && doSave && mod.shakesFile != "" {
mod.Debug("saving handshake frames to %s", mod.shakesFile) mod.Debug("saving handshake frames to %s", mod.shakesFile)
if err := mod.Session.WiFi.SaveHandshakesTo(mod.shakesFile, mod.handle.LinkType()); err != nil { 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) 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 // if we had unsaved packets and either the handshake is complete
// or it contains the PMKID, generate a new event. // or it contains the PMKID, generate a new event.
if doSave && (rawPMKID != nil || station.Handshake.Complete()) { if doSave && (rawPMKID != nil || station.Handshake.Complete()) {
mod.Session.Events.Add("wifi.client.handshake", HandshakeEvent{ if !readOnly {
File: mod.shakesFile, mod.Session.Events.Add("wifi.client.handshake", HandshakeEvent{
NewPackets: numUnsaved, File: mod.shakesFile,
AP: apMac.String(), NewPackets: numUnsaved,
Station: staMac.String(), AP: apMac.String(),
PMKID: rawPMKID, Station: staMac.String(),
}) PMKID: rawPMKID,
})
}
// make sure the info that we have key material for this AP // make sure the info that we have key material for this AP
// is persisted even after stations are pruned due to inactivity // is persisted even after stations are pruned due to inactivity
ap.WithKeyMaterial(true) ap.WithKeyMaterial(true)