mirror of
https://github.com/bettercap/bettercap
synced 2025-07-06 04:52:10 -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 (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/bettercap/bettercap/network"
|
||||||
|
"net"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
"github.com/bettercap/bettercap/packets"
|
"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) {
|
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 {
|
if ok, key, apMac, staMac := packets.Dot11ParseEAPOL(packet, dot11); ok {
|
||||||
|
isEAPOL = true
|
||||||
|
|
||||||
// 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 {
|
||||||
|
@ -126,4 +132,60 @@ func (mod *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *laye
|
||||||
ap.RemoveClient(staMac.String())
|
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 _, ap := range w.aps {
|
||||||
for _, station := range ap.Clients() {
|
for _, station := range ap.Clients() {
|
||||||
// if half (which includes also complete) or has pmkid
|
// if half (which includes also complete) or has pmkid
|
||||||
if station.Handshake.Half() || station.Handshake.HasPMKID() {
|
if station.Handshake.Any() {
|
||||||
err = nil
|
err = nil
|
||||||
station.Handshake.EachUnsavedPacket(func(pkt gopacket.Packet) {
|
station.Handshake.EachUnsavedPacket(func(pkt gopacket.Packet) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
|
@ -79,6 +79,12 @@ func (h *Handshake) AddFrame(n int, pkt gopacket.Packet) {
|
||||||
h.unsaved = append(h.unsaved, pkt)
|
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 {
|
func (h *Handshake) Complete() bool {
|
||||||
h.RLock()
|
h.RLock()
|
||||||
defer h.RUnlock()
|
defer h.RUnlock()
|
||||||
|
@ -115,6 +121,10 @@ func (h *Handshake) HasPMKID() bool {
|
||||||
return h.hasPMKID
|
return h.hasPMKID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handshake) Any() bool {
|
||||||
|
return h.HasPMKID() || h.Half() || h.Complete()
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Handshake) NumUnsaved() int {
|
func (h *Handshake) NumUnsaved() int {
|
||||||
h.RLock()
|
h.RLock()
|
||||||
defer h.RUnlock()
|
defer h.RUnlock()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue