mirror of
https://github.com/bettercap/bettercap
synced 2025-08-14 02:36:57 -07:00
new: handshakes history is now loaded from the configured pcap
This commit is contained in:
parent
c7f28855ca
commit
9a3c252c4f
3 changed files with 74 additions and 24 deletions
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue