Skip to content

Commit

Permalink
fix: collect additional frames for stations with key material (ref #810)
Browse files Browse the repository at this point in the history
  • Loading branch information
evilsocket committed Mar 30, 2021
1 parent c68c880 commit cea53b9
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 1 deletion.
62 changes: 62 additions & 0 deletions modules/wifi/wifi_recon_handshakes.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package wifi
import (
"bytes"
"fmt"
"github.com/bettercap/bettercap/network"
"net"
"path"

"github.com/bettercap/bettercap/packets"
Expand All @@ -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 {
Expand Down Expand Up @@ -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)
}
}
}
}

}
2 changes: 1 addition & 1 deletion network/wifi.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
10 changes: 10 additions & 0 deletions network/wifi_handshake.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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()
Expand Down

0 comments on commit cea53b9

Please sign in to comment.