forked from bettercap/bettercap
/
wifi_recon.go
123 lines (104 loc) · 3.04 KB
/
wifi_recon.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package modules
import (
"bytes"
"net"
"time"
"github.com/bettercap/bettercap/log"
"github.com/bettercap/bettercap/network"
"github.com/bettercap/bettercap/packets"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
)
var maxStationTTL = 5 * time.Minute
type WiFiProbe struct {
FromAddr net.HardwareAddr
FromVendor string
FromAlias string
SSID string
RSSI int8
}
func (w *WiFiModule) stationPruner() {
w.reads.Add(1)
defer w.reads.Done()
log.Debug("WiFi stations pruner started.")
for w.Running() {
// loop every AP
for _, ap := range w.Session.WiFi.List() {
sinceLastSeen := time.Since(ap.LastSeen)
if sinceLastSeen > maxStationTTL {
log.Debug("Station %s not seen in %s, removing.", ap.BSSID(), sinceLastSeen)
w.Session.WiFi.Remove(ap.BSSID())
continue
}
// loop every AP client
for _, c := range ap.Clients() {
sinceLastSeen := time.Since(c.LastSeen)
if sinceLastSeen > maxStationTTL {
log.Debug("Client %s of station %s not seen in %s, removing.", c.String(), ap.BSSID(), sinceLastSeen)
ap.RemoveClient(c.BSSID())
}
}
}
time.Sleep(1 * time.Second)
}
}
func (w *WiFiModule) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
// search for Dot11InformationElementIDSSID
if ok, ssid := packets.Dot11ParseIDSSID(packet); ok {
from := dot11.Address3
// skip stuff we're sending
if w.apRunning && bytes.Equal(from, w.apConfig.BSSID) {
return
}
if !network.IsZeroMac(from) && !network.IsBroadcastMac(from) {
var frequency int
bssid := from.String()
if found, channel := packets.Dot11ParseDSSet(packet); found {
frequency = network.Dot11Chan2Freq(channel)
} else {
frequency = int(radiotap.ChannelFrequency)
}
w.Session.WiFi.AddIfNew(ssid, bssid, frequency, radiotap.DBMAntennaSignal)
}
}
}
func (w *WiFiModule) 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 {
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{
FromAddr: dot11.Address2,
FromVendor: network.ManufLookup(dot11.Address2.String()),
FromAlias: w.Session.Lan.GetAlias(dot11.Address2.String()),
SSID: string(req.Contents[2 : 2+size]),
RSSI: radiotap.DBMAntennaSignal,
})
}
func (w *WiFiModule) discoverClients(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
w.Session.WiFi.EachAccessPoint(func(bssid string, ap *network.AccessPoint) {
// packet going to this specific BSSID?
if packets.Dot11IsDataFor(dot11, ap.HW) {
ap.AddClient(dot11.Address2.String(), int(radiotap.ChannelFrequency), radiotap.DBMAntennaSignal)
}
})
}