mirror of
https://github.com/bettercap/bettercap
synced 2025-07-16 10:03:39 -07:00
new: implemented wifi probes tracking (closes #78)
This commit is contained in:
parent
6c739a4d63
commit
ef172c1b01
2 changed files with 88 additions and 33 deletions
|
@ -21,31 +21,41 @@ func (s EventsStream) viewLogEvent(e session.Event) {
|
||||||
e.Data.(session.LogMessage).Message)
|
e.Data.(session.LogMessage).Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s EventsStream) viewApEvent(e session.Event) {
|
func (s EventsStream) viewWiFiEvent(e session.Event) {
|
||||||
ap := e.Data.(*network.AccessPoint)
|
|
||||||
vend := ""
|
|
||||||
if ap.Vendor != "" {
|
|
||||||
vend = fmt.Sprintf(" (%s)", ap.Vendor)
|
|
||||||
}
|
|
||||||
|
|
||||||
if e.Tag == "wifi.ap.new" {
|
if strings.HasPrefix(e.Tag, "wifi.ap.") {
|
||||||
fmt.Printf("[%s] [%s] WiFi access point %s detected as %s%s.\n",
|
ap := e.Data.(*network.AccessPoint)
|
||||||
|
vend := ""
|
||||||
|
if ap.Vendor != "" {
|
||||||
|
vend = fmt.Sprintf(" (%s)", ap.Vendor)
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.Tag == "wifi.ap.new" {
|
||||||
|
fmt.Printf("[%s] [%s] WiFi access point %s detected as %s%s.\n",
|
||||||
|
e.Time.Format(eventTimeFormat),
|
||||||
|
core.Green(e.Tag),
|
||||||
|
core.Bold(ap.ESSID()),
|
||||||
|
core.Green(ap.BSSID()),
|
||||||
|
vend)
|
||||||
|
} else if e.Tag == "wifi.ap.lost" {
|
||||||
|
fmt.Printf("[%s] [%s] WiFi access point %s (%s) lost.\n",
|
||||||
|
e.Time.Format(eventTimeFormat),
|
||||||
|
core.Green(e.Tag),
|
||||||
|
core.Red(ap.ESSID()),
|
||||||
|
ap.BSSID())
|
||||||
|
} else {
|
||||||
|
fmt.Printf("[%s] [%s] %s\n",
|
||||||
|
e.Time.Format(eventTimeFormat),
|
||||||
|
core.Green(e.Tag),
|
||||||
|
ap.String())
|
||||||
|
}
|
||||||
|
} else if e.Tag == "wifi.client.probe" {
|
||||||
|
probe := e.Data.(WiFiProbe)
|
||||||
|
fmt.Printf("[%s] [%s] Station %s is probing for SSID %s\n",
|
||||||
e.Time.Format(eventTimeFormat),
|
e.Time.Format(eventTimeFormat),
|
||||||
core.Green(e.Tag),
|
core.Green(e.Tag),
|
||||||
core.Bold(ap.ESSID()),
|
probe.From.String(),
|
||||||
core.Green(ap.BSSID()),
|
core.Bold(probe.SSID))
|
||||||
vend)
|
|
||||||
} else if e.Tag == "wifi.ap.lost" {
|
|
||||||
fmt.Printf("[%s] [%s] WiFi access point %s (%s) lost.\n",
|
|
||||||
e.Time.Format(eventTimeFormat),
|
|
||||||
core.Green(e.Tag),
|
|
||||||
core.Red(ap.ESSID()),
|
|
||||||
ap.BSSID())
|
|
||||||
} else {
|
|
||||||
fmt.Printf("[%s] [%s] %s\n",
|
|
||||||
e.Time.Format(eventTimeFormat),
|
|
||||||
core.Green(e.Tag),
|
|
||||||
ap.String())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,8 +152,8 @@ func (s *EventsStream) View(e session.Event, refresh bool) {
|
||||||
s.viewLogEvent(e)
|
s.viewLogEvent(e)
|
||||||
} else if strings.HasPrefix(e.Tag, "endpoint.") {
|
} else if strings.HasPrefix(e.Tag, "endpoint.") {
|
||||||
s.viewEndpointEvent(e)
|
s.viewEndpointEvent(e)
|
||||||
} else if strings.HasPrefix(e.Tag, "wifi.ap.") {
|
} else if strings.HasPrefix(e.Tag, "wifi.") {
|
||||||
s.viewApEvent(e)
|
s.viewWiFiEvent(e)
|
||||||
} else if strings.HasPrefix(e.Tag, "mod.") {
|
} else if strings.HasPrefix(e.Tag, "mod.") {
|
||||||
s.viewModuleEvent(e)
|
s.viewModuleEvent(e)
|
||||||
} else if strings.HasPrefix(e.Tag, "net.sniff.") {
|
} else if strings.HasPrefix(e.Tag, "net.sniff.") {
|
||||||
|
|
|
@ -24,6 +24,11 @@ import (
|
||||||
|
|
||||||
var maxStationTTL = 5 * time.Minute
|
var maxStationTTL = 5 * time.Minute
|
||||||
|
|
||||||
|
type WiFiProbe struct {
|
||||||
|
From net.HardwareAddr
|
||||||
|
SSID string
|
||||||
|
}
|
||||||
|
|
||||||
type WiFiRecon struct {
|
type WiFiRecon struct {
|
||||||
session.SessionModule
|
session.SessionModule
|
||||||
|
|
||||||
|
@ -106,7 +111,7 @@ func NewWiFiRecon(s *session.Session) *WiFiRecon {
|
||||||
|
|
||||||
w.AddParam(session.NewBoolParameter("wifi.skip-broken",
|
w.AddParam(session.NewBoolParameter("wifi.skip-broken",
|
||||||
"true",
|
"true",
|
||||||
"If true, dot11 packets with an invalid checksum will be skipped."))
|
"If true, dot11 packets wit48 61 63 6h an invalid checksum will be skipped."))
|
||||||
|
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
@ -441,6 +446,41 @@ func (w *WiFiRecon) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *layer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WiFiRecon) discoverProbes(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
|
||||||
|
if dot11.Type != layers.Dot11TypeMgmtProbeReq {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
reqLayer := packet.Layer(layers.LayerTypeDot11MgmtProbeReq)
|
||||||
|
if reqLayer == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req, ok := reqLayer.(*layers.Dot11MgmtProbeReq)
|
||||||
|
if ok == false {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tot := len(req.Contents)
|
||||||
|
if tot < 3 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
avail := uint32(tot - 2)
|
||||||
|
if avail < 2 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
size := uint32(req.Contents[1])
|
||||||
|
if size == 0 || size > avail {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Session.Events.Add("wifi.client.probe", WiFiProbe{
|
||||||
|
From: dot11.Address2,
|
||||||
|
SSID: string(req.Contents[2:size]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (w *WiFiRecon) discoverClients(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
|
func (w *WiFiRecon) discoverClients(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
|
||||||
w.Session.WiFi.EachAccessPoint(func(bssid string, ap *network.AccessPoint) {
|
w.Session.WiFi.EachAccessPoint(func(bssid string, ap *network.AccessPoint) {
|
||||||
// packet going to this specific BSSID?
|
// packet going to this specific BSSID?
|
||||||
|
@ -519,6 +559,17 @@ func (w *WiFiRecon) stationPruner() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WiFiRecon) trackPacket(pkt gopacket.Packet) {
|
||||||
|
pktSize := uint64(len(pkt.Data()))
|
||||||
|
|
||||||
|
w.Session.Queue.Stats.Lock()
|
||||||
|
|
||||||
|
w.Session.Queue.Stats.PktReceived++
|
||||||
|
w.Session.Queue.Stats.Received += pktSize
|
||||||
|
|
||||||
|
w.Session.Queue.Stats.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
func (w *WiFiRecon) Start() error {
|
func (w *WiFiRecon) Start() error {
|
||||||
if w.Running() == true {
|
if w.Running() == true {
|
||||||
return session.ErrAlreadyStarted
|
return session.ErrAlreadyStarted
|
||||||
|
@ -542,14 +593,7 @@ func (w *WiFiRecon) Start() error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
pktSize := uint64(len(packet.Data()))
|
w.trackPacket(packet)
|
||||||
|
|
||||||
w.Session.Queue.Stats.Lock()
|
|
||||||
|
|
||||||
w.Session.Queue.Stats.PktReceived++
|
|
||||||
w.Session.Queue.Stats.Received += pktSize
|
|
||||||
|
|
||||||
w.Session.Queue.Stats.Unlock()
|
|
||||||
|
|
||||||
// perform initial dot11 parsing and layers validation
|
// perform initial dot11 parsing and layers validation
|
||||||
if ok, radiotap, dot11 := packets.Dot11Parse(packet); ok == true {
|
if ok, radiotap, dot11 := packets.Dot11Parse(packet); ok == true {
|
||||||
|
@ -560,6 +604,7 @@ func (w *WiFiRecon) Start() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
w.updateStats(dot11, packet)
|
w.updateStats(dot11, packet)
|
||||||
|
w.discoverProbes(radiotap, dot11, packet)
|
||||||
w.discoverAccessPoints(radiotap, dot11, packet)
|
w.discoverAccessPoints(radiotap, dot11, packet)
|
||||||
w.discoverClients(radiotap, dot11, packet)
|
w.discoverClients(radiotap, dot11, packet)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue