mirror of
https://github.com/bettercap/bettercap
synced 2025-07-05 20:42:09 -07:00
fix: collect additional frames for stations with key material (ref #810)
This commit is contained in:
parent
c68c88030d
commit
cea53b969e
3 changed files with 73 additions and 1 deletions
|
@ -3,6 +3,8 @@ package wifi
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/bettercap/bettercap/network"
|
||||
"net"
|
||||
"path"
|
||||
|
||||
"github.com/bettercap/bettercap/packets"
|
||||
|
@ -21,7 +23,11 @@ func allZeros(s []byte) bool {
|
|||
}
|
||||
|
||||
func (mod *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
|
||||
isEAPOL := false
|
||||
|
||||
if ok, key, apMac, staMac := packets.Dot11ParseEAPOL(packet, dot11); ok {
|
||||
isEAPOL = true
|
||||
|
||||
// first, locate the AP in our list by its BSSID
|
||||
ap, found := mod.Session.WiFi.Get(apMac.String())
|
||||
if !found {
|
||||
|
@ -126,4 +132,60 @@ func (mod *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *laye
|
|||
ap.RemoveClient(staMac.String())
|
||||
}
|
||||
}
|
||||
|
||||
// quick and dirty heuristic, see thread here https://github.com/bettercap/bettercap/issues/810#issuecomment-805145392
|
||||
if isEAPOL || (dot11.Type.MainType() != layers.Dot11TypeData && dot11.Type.MainType() != layers.Dot11TypeCtrl) {
|
||||
target := (* network.Station)(nil)
|
||||
targetAP := (* network.AccessPoint)(nil)
|
||||
|
||||
// collect target bssids
|
||||
bssids := make([]net.HardwareAddr, 0)
|
||||
for _, addr := range []net.HardwareAddr{dot11.Address1, dot11.Address2, dot11.Address3, dot11.Address4} {
|
||||
if bytes.Equal(addr, network.BroadcastHw) == false {
|
||||
bssids = append(bssids, addr)
|
||||
}
|
||||
}
|
||||
|
||||
// for each AP
|
||||
mod.Session.WiFi.EachAccessPoint(func(mac string, ap *network.AccessPoint) {
|
||||
// only check APs we captured handshakes of
|
||||
if target == nil && ap.HasKeyMaterial() {
|
||||
// search client station
|
||||
ap.EachClient(func(mac string, station *network.Station) {
|
||||
// any valid key material for this station?
|
||||
if station.Handshake.Any() {
|
||||
// check if target
|
||||
for _, a := range bssids {
|
||||
if bytes.Equal(a, station.HW) {
|
||||
target = station
|
||||
targetAP = ap
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if target != nil {
|
||||
mod.Info("saving extra %s frame (%d bytes) for %s",
|
||||
dot11.Type.String(),
|
||||
len(packet.Data()),
|
||||
target.String())
|
||||
|
||||
target.Handshake.AddExtra(packet)
|
||||
|
||||
shakesFileName := mod.shakesFile
|
||||
if mod.shakesAggregate == false {
|
||||
shakesFileName = path.Join(shakesFileName, fmt.Sprintf("%s.pcap", targetAP.PathFriendlyName()))
|
||||
}
|
||||
if shakesFileName != "" {
|
||||
mod.Debug("(aggregate %v) saving handshake frames to %s", mod.shakesAggregate, shakesFileName)
|
||||
if err := mod.Session.WiFi.SaveHandshakesTo(shakesFileName, mod.handle.LinkType()); err != nil {
|
||||
mod.Error("error while saving handshake frames to %s: %s", shakesFileName, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -245,7 +245,7 @@ func (w *WiFi) SaveHandshakesTo(fileName string, linkType layers.LinkType) error
|
|||
for _, ap := range w.aps {
|
||||
for _, station := range ap.Clients() {
|
||||
// if half (which includes also complete) or has pmkid
|
||||
if station.Handshake.Half() || station.Handshake.HasPMKID() {
|
||||
if station.Handshake.Any() {
|
||||
err = nil
|
||||
station.Handshake.EachUnsavedPacket(func(pkt gopacket.Packet) {
|
||||
if err == nil {
|
||||
|
|
|
@ -79,6 +79,12 @@ func (h *Handshake) AddFrame(n int, pkt gopacket.Packet) {
|
|||
h.unsaved = append(h.unsaved, pkt)
|
||||
}
|
||||
|
||||
func (h *Handshake) AddExtra(pkt gopacket.Packet) {
|
||||
h.Lock()
|
||||
defer h.Unlock()
|
||||
h.unsaved = append(h.unsaved, pkt)
|
||||
}
|
||||
|
||||
func (h *Handshake) Complete() bool {
|
||||
h.RLock()
|
||||
defer h.RUnlock()
|
||||
|
@ -115,6 +121,10 @@ func (h *Handshake) HasPMKID() bool {
|
|||
return h.hasPMKID
|
||||
}
|
||||
|
||||
func (h *Handshake) Any() bool {
|
||||
return h.HasPMKID() || h.Half() || h.Complete()
|
||||
}
|
||||
|
||||
func (h *Handshake) NumUnsaved() int {
|
||||
h.RLock()
|
||||
defer h.RUnlock()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue