fix: pruning wifi stations after a certain time of inactivity

This commit is contained in:
evilsocket 2018-02-19 14:26:00 +01:00
commit 8d2f0af82b
3 changed files with 69 additions and 20 deletions

View file

@ -24,6 +24,8 @@ import (
"github.com/olekukonko/tablewriter" "github.com/olekukonko/tablewriter"
) )
var maxStationTTL = 5 * time.Minute
type WiFiRecon struct { type WiFiRecon struct {
session.SessionModule session.SessionModule
@ -141,8 +143,15 @@ func (w *WiFiRecon) getRow(station *network.WiFiStation) []string {
if encryption == "OPEN" || encryption == "" { if encryption == "OPEN" || encryption == "" {
encryption = core.Green("OPEN") encryption = core.Green("OPEN")
} }
sent := humanize.Bytes(station.Sent) sent := ""
recvd := humanize.Bytes(station.Received) if station.Sent > 0 {
sent = humanize.Bytes(station.Sent)
}
recvd := ""
if station.Received > 0 {
recvd = humanize.Bytes(station.Received)
}
if w.isApSelected() { if w.isApSelected() {
return []string{ return []string{
@ -369,6 +378,36 @@ func (w *WiFiRecon) updateStats(dot11 *layers.Dot11, packet gopacket.Packet) {
} }
} }
func (w *WiFiRecon) channelHopper() {
log.Info("Channel hopper started.")
for w.Running() == true {
for channel := 1; channel < 15; channel++ {
if err := network.SetInterfaceChannel(w.Session.Interface.Name(), channel); err != nil {
log.Warning("Error while hopping to channel %d: %s", channel, err)
}
// this is the default for airodump-ng, good for them, good for us.
time.Sleep(250 * time.Millisecond)
if w.Running() == false {
return
}
}
}
}
func (w *WiFiRecon) stationPruner() {
log.Debug("WiFi stations pruner started.")
for w.Running() == true {
for _, s := range w.Session.WiFi.List() {
sinceLastSeen := time.Since(s.LastSeen)
if sinceLastSeen > maxStationTTL {
log.Debug("Station %s not seen in %s, removing.", s.BSSID(), sinceLastSeen)
w.Session.WiFi.Remove(s.BSSID())
}
}
time.Sleep(5 * time.Second)
}
}
func (w *WiFiRecon) Start() error { func (w *WiFiRecon) Start() error {
if w.Running() == true { if w.Running() == true {
return session.ErrAlreadyStarted return session.ErrAlreadyStarted
@ -379,23 +418,12 @@ func (w *WiFiRecon) Start() error {
w.SetRunning(true, func() { w.SetRunning(true, func() {
// start channel hopper if needed // start channel hopper if needed
if w.channel == 0 { if w.channel == 0 {
go func() { go w.channelHopper()
log.Info("Channel hopper started.")
for w.Running() == true {
for channel := 1; channel < 15; channel++ {
if err := network.SetInterfaceChannel(w.Session.Interface.Name(), channel); err != nil {
log.Warning("Error while hopping to channel %d: %s", channel, err)
}
// this is the default for airodump-ng, good for them, good for us.
time.Sleep(250 * time.Millisecond)
if w.Running() == false {
return
}
}
}
}()
} }
// start the pruner
go w.stationPruner()
defer w.handle.Close() defer w.handle.Close()
src := gopacket.NewPacketSource(w.handle, w.handle.LinkType()) src := gopacket.NewPacketSource(w.handle, w.handle.LinkType())
for packet := range src.Packets() { for packet := range src.Packets() {

View file

@ -5,16 +5,24 @@ import (
"time" "time"
) )
type StationNewCallback func(s *WiFiStation)
type StationLostCallback func(s *WiFiStation)
type WiFi struct { type WiFi struct {
sync.Mutex sync.Mutex
Interface *Endpoint Interface *Endpoint
Stations map[string]*WiFiStation Stations map[string]*WiFiStation
newCb StationNewCallback
lostCb StationLostCallback
} }
func NewWiFi(iface *Endpoint) *WiFi { func NewWiFi(iface *Endpoint, newcb StationNewCallback, lostcb StationLostCallback) *WiFi {
return &WiFi{ return &WiFi{
Interface: iface, Interface: iface,
Stations: make(map[string]*WiFiStation), Stations: make(map[string]*WiFiStation),
newCb: newcb,
lostCb: lostcb,
} }
} }
@ -33,8 +41,11 @@ func (w *WiFi) Remove(mac string) {
w.Lock() w.Lock()
defer w.Unlock() defer w.Unlock()
if _, found := w.Stations[mac]; found { if s, found := w.Stations[mac]; found {
delete(w.Stations, mac) delete(w.Stations, mac)
if w.lostCb != nil {
w.lostCb(s)
}
} }
} }
@ -52,6 +63,10 @@ func (w *WiFi) AddIfNew(ssid, mac string, isAp bool, channel int, rssi int8) *Wi
newStation := NewWiFiStation(ssid, mac, isAp, channel, rssi) newStation := NewWiFiStation(ssid, mac, isAp, channel, rssi)
w.Stations[mac] = newStation w.Stations[mac] = newStation
if w.newCb != nil {
w.newCb(newStation)
}
return nil return nil
} }

View file

@ -377,7 +377,13 @@ func (s *Session) Start() error {
} }
s.Firewall = firewall.Make(s.Interface) s.Firewall = firewall.Make(s.Interface)
s.WiFi = network.NewWiFi(s.Interface)
s.WiFi = network.NewWiFi(s.Interface, func(st *network.WiFiStation) {
s.Events.Add("wifi.station.new", st)
}, func(st *network.WiFiStation) {
s.Events.Add("wifi.station.lost", st)
})
s.Lan = network.NewLAN(s.Interface, s.Gateway, func(e *network.Endpoint) { s.Lan = network.NewLAN(s.Interface, s.Gateway, func(e *network.Endpoint) {
s.Events.Add("endpoint.new", e) s.Events.Add("endpoint.new", e)
}, func(e *network.Endpoint) { }, func(e *network.Endpoint) {