misc: small fix or general refactoring i did not bother commenting

This commit is contained in:
evilsocket 2019-02-13 10:12:34 +01:00
commit 4eead7eafa
No known key found for this signature in database
GPG key ID: 1564D7F30393A456
58 changed files with 2052 additions and 2052 deletions

View file

@ -53,7 +53,7 @@ type WiFiModule struct {
}
func NewWiFiModule(s *session.Session) *WiFiModule {
w := &WiFiModule{
mod := &WiFiModule{
SessionModule: session.NewSessionModule("wifi", s),
minRSSI: -200,
channel: 0,
@ -74,47 +74,47 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
chanLock: &sync.Mutex{},
}
w.AddHandler(session.NewModuleHandler("wifi.recon on", "",
mod.AddHandler(session.NewModuleHandler("wifi.recon on", "",
"Start 802.11 wireless base stations discovery and channel hopping.",
func(args []string) error {
return w.Start()
return mod.Start()
}))
w.AddHandler(session.NewModuleHandler("wifi.recon off", "",
mod.AddHandler(session.NewModuleHandler("wifi.recon off", "",
"Stop 802.11 wireless base stations discovery and channel hopping.",
func(args []string) error {
return w.Stop()
return mod.Stop()
}))
w.AddHandler(session.NewModuleHandler("wifi.recon MAC", "wifi.recon ((?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]{2}))",
mod.AddHandler(session.NewModuleHandler("wifi.recon MAC", "wifi.recon ((?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]{2}))",
"Set 802.11 base station address to filter for.",
func(args []string) error {
bssid, err := net.ParseMAC(args[0])
if err != nil {
return err
} else if ap, found := w.Session.WiFi.Get(bssid.String()); found {
w.ap = ap
w.stickChan = ap.Channel()
} else if ap, found := mod.Session.WiFi.Get(bssid.String()); found {
mod.ap = ap
mod.stickChan = ap.Channel()
return nil
}
return fmt.Errorf("Could not find station with BSSID %s", args[0])
}))
w.AddHandler(session.NewModuleHandler("wifi.recon clear", "",
mod.AddHandler(session.NewModuleHandler("wifi.recon clear", "",
"Remove the 802.11 base station filter.",
func(args []string) (err error) {
w.ap = nil
w.stickChan = 0
w.frequencies, err = network.GetSupportedFrequencies(w.Session.Interface.Name())
w.hopChanges <- true
mod.ap = nil
mod.stickChan = 0
mod.frequencies, err = network.GetSupportedFrequencies(mod.Session.Interface.Name())
mod.hopChanges <- true
return err
}))
w.AddParam(session.NewIntParameter("wifi.rssi.min",
mod.AddParam(session.NewIntParameter("wifi.rssi.min",
"-200",
"Minimum WiFi signal strength in dBm."))
w.AddHandler(session.NewModuleHandler("wifi.deauth BSSID", `wifi\.deauth ((?:[a-fA-F0-9:]{11,})|all|\*)`,
mod.AddHandler(session.NewModuleHandler("wifi.deauth BSSID", `wifi\.deauth ((?:[a-fA-F0-9:]{11,})|all|\*)`,
"Start a 802.11 deauth attack, if an access point BSSID is provided, every client will be deauthenticated, otherwise only the selected client. Use 'all', '*' or a broadcast BSSID (ff:ff:ff:ff:ff:ff) to iterate every access point with at least one client and start a deauth attack for each one.",
func(args []string) error {
if args[0] == "all" || args[0] == "*" {
@ -124,23 +124,23 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
if err != nil {
return err
}
return w.startDeauth(bssid)
return mod.startDeauth(bssid)
}))
w.AddParam(session.NewStringParameter("wifi.deauth.skip",
mod.AddParam(session.NewStringParameter("wifi.deauth.skip",
"",
"",
"Comma separated list of BSSID to skip while sending deauth packets."))
w.AddParam(session.NewBoolParameter("wifi.deauth.silent",
mod.AddParam(session.NewBoolParameter("wifi.deauth.silent",
"false",
"If true, messages from wifi.deauth will be suppressed."))
w.AddParam(session.NewBoolParameter("wifi.deauth.open",
mod.AddParam(session.NewBoolParameter("wifi.deauth.open",
"true",
"Send wifi deauth packets to open networks."))
w.AddHandler(session.NewModuleHandler("wifi.assoc BSSID", `wifi\.assoc ((?:[a-fA-F0-9:]{11,})|all|\*)`,
mod.AddHandler(session.NewModuleHandler("wifi.assoc BSSID", `wifi\.assoc ((?:[a-fA-F0-9:]{11,})|all|\*)`,
"Send an association request to the selected BSSID in order to receive a RSN PMKID key. Use 'all', '*' or a broadcast BSSID (ff:ff:ff:ff:ff:ff) to iterate for every access point.",
func(args []string) error {
if args[0] == "all" || args[0] == "*" {
@ -150,81 +150,81 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
if err != nil {
return err
}
return w.startAssoc(bssid)
return mod.startAssoc(bssid)
}))
w.AddParam(session.NewStringParameter("wifi.assoc.skip",
mod.AddParam(session.NewStringParameter("wifi.assoc.skip",
"",
"",
"Comma separated list of BSSID to skip while sending association requests."))
w.AddParam(session.NewBoolParameter("wifi.assoc.silent",
mod.AddParam(session.NewBoolParameter("wifi.assoc.silent",
"false",
"If true, messages from wifi.assoc will be suppressed."))
w.AddParam(session.NewBoolParameter("wifi.assoc.open",
mod.AddParam(session.NewBoolParameter("wifi.assoc.open",
"false",
"Send association requests to open networks."))
w.AddHandler(session.NewModuleHandler("wifi.ap", "",
mod.AddHandler(session.NewModuleHandler("wifi.ap", "",
"Inject fake management beacons in order to create a rogue access point.",
func(args []string) error {
if err := w.parseApConfig(); err != nil {
if err := mod.parseApConfig(); err != nil {
return err
} else {
return w.startAp()
return mod.startAp()
}
}))
w.AddParam(session.NewStringParameter("wifi.handshakes.file",
mod.AddParam(session.NewStringParameter("wifi.handshakes.file",
"~/bettercap-wifi-handshakes.pcap",
"",
"File path of the pcap file to save handshakes to."))
w.AddParam(session.NewStringParameter("wifi.ap.ssid",
mod.AddParam(session.NewStringParameter("wifi.ap.ssid",
"FreeWiFi",
"",
"SSID of the fake access point."))
w.AddParam(session.NewStringParameter("wifi.ap.bssid",
mod.AddParam(session.NewStringParameter("wifi.ap.bssid",
session.ParamRandomMAC,
"[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}",
"BSSID of the fake access point."))
w.AddParam(session.NewIntParameter("wifi.ap.channel",
mod.AddParam(session.NewIntParameter("wifi.ap.channel",
"1",
"Channel of the fake access point."))
w.AddParam(session.NewBoolParameter("wifi.ap.encryption",
mod.AddParam(session.NewBoolParameter("wifi.ap.encryption",
"true",
"If true, the fake access point will use WPA2, otherwise it'll result as an open AP."))
w.AddHandler(session.NewModuleHandler("wifi.show.wps BSSID",
mod.AddHandler(session.NewModuleHandler("wifi.show.wps BSSID",
`wifi\.show\.wps ((?:[a-fA-F0-9:]{11,})|all|\*)`,
"Show WPS information about a given station (use 'all', '*' or a broadcast BSSID for all).",
func(args []string) error {
if args[0] == "all" || args[0] == "*" {
args[0] = "ff:ff:ff:ff:ff:ff"
}
return w.ShowWPS(args[0])
return mod.ShowWPS(args[0])
}))
w.AddHandler(session.NewModuleHandler("wifi.show", "",
mod.AddHandler(session.NewModuleHandler("wifi.show", "",
"Show current wireless stations list (default sorting by essid).",
func(args []string) error {
return w.Show()
return mod.Show()
}))
w.selector = utils.ViewSelectorFor(&w.SessionModule, "wifi.show",
mod.selector = utils.ViewSelectorFor(&mod.SessionModule, "wifi.show",
[]string{"rssi", "bssid", "essid", "channel", "encryption", "clients", "seen", "sent", "rcvd"}, "rssi asc")
w.AddHandler(session.NewModuleHandler("wifi.recon.channel", `wifi\.recon\.channel[\s]+([0-9]+(?:[, ]+[0-9]+)*|clear)`,
mod.AddHandler(session.NewModuleHandler("wifi.recon.channel", `wifi\.recon\.channel[\s]+([0-9]+(?:[, ]+[0-9]+)*|clear)`,
"WiFi channels (comma separated) or 'clear' for channel hopping.",
func(args []string) (err error) {
freqs := []int{}
if args[0] != "clear" {
w.Debug("setting hopping channels to %s", args[0])
mod.Debug("setting hopping channels to %s", args[0])
for _, s := range str.Comma(args[0]) {
if ch, err := strconv.Atoi(s); err != nil {
return err
@ -239,48 +239,48 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
}
if len(freqs) == 0 {
w.Debug("resetting hopping channels")
if freqs, err = network.GetSupportedFrequencies(w.Session.Interface.Name()); err != nil {
mod.Debug("resetting hopping channels")
if freqs, err = network.GetSupportedFrequencies(mod.Session.Interface.Name()); err != nil {
return err
}
}
w.Debug("new frequencies: %v", freqs)
w.frequencies = freqs
mod.Debug("new frequencies: %v", freqs)
mod.frequencies = freqs
// if wifi.recon is not running, this would block forever
if w.Running() {
w.hopChanges <- true
if mod.Running() {
mod.hopChanges <- true
}
return nil
}))
w.AddParam(session.NewStringParameter("wifi.source.file",
mod.AddParam(session.NewStringParameter("wifi.source.file",
"",
"",
"If set, the wifi module will read from this pcap file instead of the hardware interface."))
w.AddParam(session.NewIntParameter("wifi.hop.period",
mod.AddParam(session.NewIntParameter("wifi.hop.period",
"250",
"If channel hopping is enabled (empty wifi.recon.channel), this is the time in milliseconds the algorithm will hop on every channel (it'll be doubled if both 2.4 and 5.0 bands are available)."))
w.AddParam(session.NewBoolParameter("wifi.skip-broken",
mod.AddParam(session.NewBoolParameter("wifi.skip-broken",
"true",
"If true, dot11 packets with an invalid checksum will be skipped."))
return w
return mod
}
func (w WiFiModule) Name() string {
func (mod WiFiModule) Name() string {
return "wifi"
}
func (w WiFiModule) Description() string {
func (mod WiFiModule) Description() string {
return "A module to monitor and perform wireless attacks on 802.11."
}
func (w WiFiModule) Author() string {
func (mod WiFiModule) Author() string {
return "Simone Margaritelli <evilsocket@gmail.com> && Gianluca Braga <matrix86@gmail.com>"
}
@ -290,31 +290,31 @@ const (
ErrIfaceNotUp = "Interface Not Up"
)
func (w *WiFiModule) Configure() error {
func (mod *WiFiModule) Configure() error {
var hopPeriod int
var err error
if err, w.source = w.StringParam("wifi.source.file"); err != nil {
if err, mod.source = mod.StringParam("wifi.source.file"); err != nil {
return err
}
if err, w.shakesFile = w.StringParam("wifi.handshakes.file"); err != nil {
if err, mod.shakesFile = mod.StringParam("wifi.handshakes.file"); err != nil {
return err
} else if w.shakesFile != "" {
if w.shakesFile, err = fs.Expand(w.shakesFile); err != nil {
} else if mod.shakesFile != "" {
if mod.shakesFile, err = fs.Expand(mod.shakesFile); err != nil {
return err
}
}
if err, w.minRSSI = w.IntParam("wifi.rssi.min"); err != nil {
if err, mod.minRSSI = mod.IntParam("wifi.rssi.min"); err != nil {
return err
}
ifName := w.Session.Interface.Name()
ifName := mod.Session.Interface.Name()
if w.source != "" {
if w.handle, err = pcap.OpenOffline(w.source); err != nil {
return fmt.Errorf("error while opening file %s: %s", w.source, err)
if mod.source != "" {
if mod.handle, err = pcap.OpenOffline(mod.source); err != nil {
return fmt.Errorf("error while opening file %s: %s", mod.source, err)
}
} else {
for retry := 0; ; retry++ {
@ -336,9 +336,9 @@ func (w *WiFiModule) Configure() error {
readTimeout := 500 * time.Millisecond
if err = ihandle.SetTimeout(readTimeout); err != nil {
return fmt.Errorf("error while setting timeout: %s", err)
} else if w.handle, err = ihandle.Activate(); err != nil {
} else if mod.handle, err = ihandle.Activate(); err != nil {
if retry == 0 && err.Error() == ErrIfaceNotUp {
w.Warning("interface %s is down, bringing it up ...", ifName)
mod.Warning("interface %s is down, bringing it up ...", ifName)
if err := network.ActivateInterface(ifName); err != nil {
return err
}
@ -351,39 +351,39 @@ func (w *WiFiModule) Configure() error {
}
}
if err, w.skipBroken = w.BoolParam("wifi.skip-broken"); err != nil {
if err, mod.skipBroken = mod.BoolParam("wifi.skip-broken"); err != nil {
return err
} else if err, hopPeriod = w.IntParam("wifi.hop.period"); err != nil {
} else if err, hopPeriod = mod.IntParam("wifi.hop.period"); err != nil {
return err
}
w.hopPeriod = time.Duration(hopPeriod) * time.Millisecond
mod.hopPeriod = time.Duration(hopPeriod) * time.Millisecond
if w.source == "" {
if mod.source == "" {
// No channels setted, retrieve frequencies supported by the card
if len(w.frequencies) == 0 {
if w.frequencies, err = network.GetSupportedFrequencies(ifName); err != nil {
if len(mod.frequencies) == 0 {
if mod.frequencies, err = network.GetSupportedFrequencies(ifName); err != nil {
return fmt.Errorf("error while getting supported frequencies of %s: %s", ifName, err)
}
w.Debug("wifi supported frequencies: %v", w.frequencies)
mod.Debug("wifi supported frequencies: %v", mod.frequencies)
// we need to start somewhere, this is just to check if
// this OS supports switching channel programmatically.
if err = network.SetInterfaceChannel(ifName, 1); err != nil {
return fmt.Errorf("error while initializing %s to channel 1: %s", ifName, err)
}
w.Info("started (min rssi: %d dBm)", w.minRSSI)
mod.Info("started (min rssi: %d dBm)", mod.minRSSI)
}
}
return nil
}
func (w *WiFiModule) updateInfo(dot11 *layers.Dot11, packet gopacket.Packet) {
func (mod *WiFiModule) updateInfo(dot11 *layers.Dot11, packet gopacket.Packet) {
if ok, enc, cipher, auth := packets.Dot11ParseEncryption(packet, dot11); ok {
bssid := dot11.Address3.String()
if station, found := w.Session.WiFi.Get(bssid); found {
if station, found := mod.Session.WiFi.Get(bssid); found {
station.Encryption = enc
station.Cipher = cipher
station.Authentication = auth
@ -391,7 +391,7 @@ func (w *WiFiModule) updateInfo(dot11 *layers.Dot11, packet gopacket.Packet) {
}
if ok, bssid, info := packets.Dot11ParseWPS(packet, dot11); ok {
if station, found := w.Session.WiFi.Get(bssid.String()); found {
if station, found := mod.Session.WiFi.Get(bssid.String()); found {
for name, value := range info {
station.WPS[name] = value
}
@ -399,84 +399,84 @@ func (w *WiFiModule) updateInfo(dot11 *layers.Dot11, packet gopacket.Packet) {
}
}
func (w *WiFiModule) updateStats(dot11 *layers.Dot11, packet gopacket.Packet) {
func (mod *WiFiModule) updateStats(dot11 *layers.Dot11, packet gopacket.Packet) {
// collect stats from data frames
if dot11.Type.MainType() == layers.Dot11TypeData {
bytes := uint64(len(packet.Data()))
dst := dot11.Address1.String()
if station, found := w.Session.WiFi.Get(dst); found {
if station, found := mod.Session.WiFi.Get(dst); found {
station.Received += bytes
}
src := dot11.Address2.String()
if station, found := w.Session.WiFi.Get(src); found {
if station, found := mod.Session.WiFi.Get(src); found {
station.Sent += bytes
}
}
}
func (w *WiFiModule) Start() error {
if err := w.Configure(); err != nil {
func (mod *WiFiModule) Start() error {
if err := mod.Configure(); err != nil {
return err
}
w.SetRunning(true, func() {
mod.SetRunning(true, func() {
// start channel hopper if needed
if w.channel == 0 && w.source == "" {
go w.channelHopper()
if mod.channel == 0 && mod.source == "" {
go mod.channelHopper()
}
// start the pruner
go w.stationPruner()
go mod.stationPruner()
w.reads.Add(1)
defer w.reads.Done()
mod.reads.Add(1)
defer mod.reads.Done()
src := gopacket.NewPacketSource(w.handle, w.handle.LinkType())
w.pktSourceChan = src.Packets()
for packet := range w.pktSourceChan {
if !w.Running() {
src := gopacket.NewPacketSource(mod.handle, mod.handle.LinkType())
mod.pktSourceChan = src.Packets()
for packet := range mod.pktSourceChan {
if !mod.Running() {
break
} else if packet == nil {
continue
}
w.Session.Queue.TrackPacket(uint64(len(packet.Data())))
mod.Session.Queue.TrackPacket(uint64(len(packet.Data())))
// perform initial dot11 parsing and layers validation
if ok, radiotap, dot11 := packets.Dot11Parse(packet); ok {
// check FCS checksum
if w.skipBroken && !dot11.ChecksumValid() {
w.Debug("skipping dot11 packet with invalid checksum.")
if mod.skipBroken && !dot11.ChecksumValid() {
mod.Debug("skipping dot11 packet with invalid checksum.")
continue
}
w.discoverProbes(radiotap, dot11, packet)
w.discoverAccessPoints(radiotap, dot11, packet)
w.discoverClients(radiotap, dot11, packet)
w.discoverHandshakes(radiotap, dot11, packet)
w.updateInfo(dot11, packet)
w.updateStats(dot11, packet)
mod.discoverProbes(radiotap, dot11, packet)
mod.discoverAccessPoints(radiotap, dot11, packet)
mod.discoverClients(radiotap, dot11, packet)
mod.discoverHandshakes(radiotap, dot11, packet)
mod.updateInfo(dot11, packet)
mod.updateStats(dot11, packet)
}
}
w.pktSourceChanClosed = true
mod.pktSourceChanClosed = true
})
return nil
}
func (w *WiFiModule) Stop() error {
return w.SetRunning(false, func() {
func (mod *WiFiModule) Stop() error {
return mod.SetRunning(false, func() {
// wait any pending write operation
w.writes.Wait()
mod.writes.Wait()
// signal the main for loop we want to exit
if !w.pktSourceChanClosed {
w.pktSourceChan <- nil
if !mod.pktSourceChanClosed {
mod.pktSourceChan <- nil
}
w.reads.Wait()
mod.reads.Wait()
// close the pcap handle to make the main for exit
w.handle.Close()
mod.handle.Close()
})
}

View file

@ -14,54 +14,54 @@ import (
var errNoRecon = errors.New("Module wifi.ap requires module wifi.recon to be activated.")
func (w *WiFiModule) parseApConfig() (err error) {
func (mod *WiFiModule) parseApConfig() (err error) {
var bssid string
if err, w.apConfig.SSID = w.StringParam("wifi.ap.ssid"); err != nil {
if err, mod.apConfig.SSID = mod.StringParam("wifi.ap.ssid"); err != nil {
return
} else if err, bssid = w.StringParam("wifi.ap.bssid"); err != nil {
} else if err, bssid = mod.StringParam("wifi.ap.bssid"); err != nil {
return
} else if w.apConfig.BSSID, err = net.ParseMAC(network.NormalizeMac(bssid)); err != nil {
} else if mod.apConfig.BSSID, err = net.ParseMAC(network.NormalizeMac(bssid)); err != nil {
return
} else if err, w.apConfig.Channel = w.IntParam("wifi.ap.channel"); err != nil {
} else if err, mod.apConfig.Channel = mod.IntParam("wifi.ap.channel"); err != nil {
return
} else if err, w.apConfig.Encryption = w.BoolParam("wifi.ap.encryption"); err != nil {
} else if err, mod.apConfig.Encryption = mod.BoolParam("wifi.ap.encryption"); err != nil {
return
}
return
}
func (w *WiFiModule) startAp() error {
func (mod *WiFiModule) startAp() error {
// we need channel hopping and packet injection for this
if !w.Running() {
if !mod.Running() {
return errNoRecon
} else if w.apRunning {
} else if mod.apRunning {
return session.ErrAlreadyStarted
}
go func() {
w.apRunning = true
mod.apRunning = true
defer func() {
w.apRunning = false
mod.apRunning = false
}()
enc := tui.Yellow("WPA2")
if !w.apConfig.Encryption {
if !mod.apConfig.Encryption {
enc = tui.Green("Open")
}
w.Info("sending beacons as SSID %s (%s) on channel %d (%s).",
tui.Bold(w.apConfig.SSID),
w.apConfig.BSSID.String(),
w.apConfig.Channel,
mod.Info("sending beacons as SSID %s (%s) on channel %d (%s).",
tui.Bold(mod.apConfig.SSID),
mod.apConfig.BSSID.String(),
mod.apConfig.Channel,
enc)
for seqn := uint16(0); w.Running(); seqn++ {
w.writes.Add(1)
defer w.writes.Done()
for seqn := uint16(0); mod.Running(); seqn++ {
mod.writes.Add(1)
defer mod.writes.Done()
if err, pkt := packets.NewDot11Beacon(w.apConfig, seqn); err != nil {
w.Error("could not create beacon packet: %s", err)
if err, pkt := packets.NewDot11Beacon(mod.apConfig, seqn); err != nil {
mod.Error("could not create beacon packet: %s", err)
} else {
w.injectPacket(pkt)
mod.injectPacket(pkt)
}
time.Sleep(100 * time.Millisecond)

View file

@ -10,22 +10,22 @@ import (
"github.com/bettercap/bettercap/packets"
)
func (w *WiFiModule) sendAssocPacket(ap *network.AccessPoint) {
if err, pkt := packets.NewDot11Auth(w.Session.Interface.HW, ap.HW, 1); err != nil {
w.Error("cloud not create auth packet: %s", err)
func (mod *WiFiModule) sendAssocPacket(ap *network.AccessPoint) {
if err, pkt := packets.NewDot11Auth(mod.Session.Interface.HW, ap.HW, 1); err != nil {
mod.Error("cloud not create auth packet: %s", err)
} else {
w.injectPacket(pkt)
mod.injectPacket(pkt)
}
if err, pkt := packets.NewDot11AssociationRequest(w.Session.Interface.HW, ap.HW, ap.ESSID(), 1); err != nil {
w.Error("cloud not create association request packet: %s", err)
if err, pkt := packets.NewDot11AssociationRequest(mod.Session.Interface.HW, ap.HW, ap.ESSID(), 1); err != nil {
mod.Error("cloud not create association request packet: %s", err)
} else {
w.injectPacket(pkt)
mod.injectPacket(pkt)
}
}
func (w *WiFiModule) skipAssoc(to net.HardwareAddr) bool {
for _, mac := range w.assocSkip {
func (mod *WiFiModule) skipAssoc(to net.HardwareAddr) bool {
for _, mac := range mod.assocSkip {
if bytes.Equal(to, mac) {
return true
}
@ -33,51 +33,51 @@ func (w *WiFiModule) skipAssoc(to net.HardwareAddr) bool {
return false
}
func (w *WiFiModule) isAssocSilent() bool {
if err, is := w.BoolParam("wifi.assoc.silent"); err != nil {
w.Warning("%v", err)
func (mod *WiFiModule) isAssocSilent() bool {
if err, is := mod.BoolParam("wifi.assoc.silent"); err != nil {
mod.Warning("%v", err)
} else {
w.assocSilent = is
mod.assocSilent = is
}
return w.assocSilent
return mod.assocSilent
}
func (w *WiFiModule) doAssocOpen() bool {
if err, is := w.BoolParam("wifi.assoc.open"); err != nil {
w.Warning("%v", err)
func (mod *WiFiModule) doAssocOpen() bool {
if err, is := mod.BoolParam("wifi.assoc.open"); err != nil {
mod.Warning("%v", err)
} else {
w.assocOpen = is
mod.assocOpen = is
}
return w.assocOpen
return mod.assocOpen
}
func (w *WiFiModule) startAssoc(to net.HardwareAddr) error {
func (mod *WiFiModule) startAssoc(to net.HardwareAddr) error {
// parse skip list
if err, assocSkip := w.StringParam("wifi.assoc.skip"); err != nil {
if err, assocSkip := mod.StringParam("wifi.assoc.skip"); err != nil {
return err
} else if macs, err := network.ParseMACs(assocSkip); err != nil {
return err
} else {
w.assocSkip = macs
mod.assocSkip = macs
}
// if not already running, temporarily enable the pcap handle
// for packet injection
if !w.Running() {
if err := w.Configure(); err != nil {
if !mod.Running() {
if err := mod.Configure(); err != nil {
return err
}
defer w.handle.Close()
defer mod.handle.Close()
}
toAssoc := make([]*network.AccessPoint, 0)
isBcast := network.IsBroadcastMac(to)
for _, ap := range w.Session.WiFi.List() {
for _, ap := range mod.Session.WiFi.List() {
if isBcast || bytes.Equal(ap.HW, to) {
if !w.skipAssoc(ap.HW) {
if !mod.skipAssoc(ap.HW) {
toAssoc = append(toAssoc, ap)
} else {
w.Debug("skipping ap:%v because skip list %v", ap, w.assocSkip)
mod.Debug("skipping ap:%v because skip list %v", ap, mod.assocSkip)
}
}
}
@ -90,8 +90,8 @@ func (w *WiFiModule) startAssoc(to net.HardwareAddr) error {
}
go func() {
w.writes.Add(1)
defer w.writes.Done()
mod.writes.Add(1)
defer mod.writes.Done()
// since we need to change the wifi adapter channel for each
// association request, let's sort by channel so we do the minimum
@ -102,19 +102,19 @@ func (w *WiFiModule) startAssoc(to net.HardwareAddr) error {
// send the association request frames
for _, ap := range toAssoc {
if w.Running() {
logger := w.Info
if w.isAssocSilent() {
logger = w.Debug
if mod.Running() {
logger := mod.Info
if mod.isAssocSilent() {
logger = mod.Debug
}
if ap.IsOpen() && !w.doAssocOpen() {
w.Debug("skipping association for open network %s (wifi.assoc.open is false)", ap.ESSID())
if ap.IsOpen() && !mod.doAssocOpen() {
mod.Debug("skipping association for open network %s (wifi.assoc.open is false)", ap.ESSID())
} else {
logger("sending association request to AP %s (channel:%d encryption:%s)", ap.ESSID(), ap.Channel(), ap.Encryption)
w.onChannel(ap.Channel(), func() {
w.sendAssocPacket(ap)
mod.onChannel(ap.Channel(), func() {
mod.sendAssocPacket(ap)
})
}
}

View file

@ -11,37 +11,37 @@ import (
"github.com/bettercap/bettercap/packets"
)
func (w *WiFiModule) injectPacket(data []byte) {
if err := w.handle.WritePacketData(data); err != nil {
w.Error("could not inject WiFi packet: %s", err)
w.Session.Queue.TrackError()
func (mod *WiFiModule) injectPacket(data []byte) {
if err := mod.handle.WritePacketData(data); err != nil {
mod.Error("could not inject WiFi packet: %s", err)
mod.Session.Queue.TrackError()
} else {
w.Session.Queue.TrackSent(uint64(len(data)))
mod.Session.Queue.TrackSent(uint64(len(data)))
}
// let the network card breath a little
time.Sleep(10 * time.Millisecond)
}
func (w *WiFiModule) sendDeauthPacket(ap net.HardwareAddr, client net.HardwareAddr) {
for seq := uint16(0); seq < 64 && w.Running(); seq++ {
func (mod *WiFiModule) sendDeauthPacket(ap net.HardwareAddr, client net.HardwareAddr) {
for seq := uint16(0); seq < 64 && mod.Running(); seq++ {
if err, pkt := packets.NewDot11Deauth(ap, client, ap, seq); err != nil {
w.Error("could not create deauth packet: %s", err)
mod.Error("could not create deauth packet: %s", err)
continue
} else {
w.injectPacket(pkt)
mod.injectPacket(pkt)
}
if err, pkt := packets.NewDot11Deauth(client, ap, ap, seq); err != nil {
w.Error("could not create deauth packet: %s", err)
mod.Error("could not create deauth packet: %s", err)
continue
} else {
w.injectPacket(pkt)
mod.injectPacket(pkt)
}
}
}
func (w *WiFiModule) skipDeauth(to net.HardwareAddr) bool {
for _, mac := range w.deauthSkip {
func (mod *WiFiModule) skipDeauth(to net.HardwareAddr) bool {
for _, mac := range mod.deauthSkip {
if bytes.Equal(to, mac) {
return true
}
@ -49,41 +49,41 @@ func (w *WiFiModule) skipDeauth(to net.HardwareAddr) bool {
return false
}
func (w *WiFiModule) isDeauthSilent() bool {
if err, is := w.BoolParam("wifi.deauth.silent"); err != nil {
w.Warning("%v", err)
func (mod *WiFiModule) isDeauthSilent() bool {
if err, is := mod.BoolParam("wifi.deauth.silent"); err != nil {
mod.Warning("%v", err)
} else {
w.deauthSilent = is
mod.deauthSilent = is
}
return w.deauthSilent
return mod.deauthSilent
}
func (w *WiFiModule) doDeauthOpen() bool {
if err, is := w.BoolParam("wifi.deauth.open"); err != nil {
w.Warning("%v", err)
func (mod *WiFiModule) doDeauthOpen() bool {
if err, is := mod.BoolParam("wifi.deauth.open"); err != nil {
mod.Warning("%v", err)
} else {
w.deauthOpen = is
mod.deauthOpen = is
}
return w.deauthOpen
return mod.deauthOpen
}
func (w *WiFiModule) startDeauth(to net.HardwareAddr) error {
func (mod *WiFiModule) startDeauth(to net.HardwareAddr) error {
// parse skip list
if err, deauthSkip := w.StringParam("wifi.deauth.skip"); err != nil {
if err, deauthSkip := mod.StringParam("wifi.deauth.skip"); err != nil {
return err
} else if macs, err := network.ParseMACs(deauthSkip); err != nil {
return err
} else {
w.deauthSkip = macs
mod.deauthSkip = macs
}
// if not already running, temporarily enable the pcap handle
// for packet injection
if !w.Running() {
if err := w.Configure(); err != nil {
if !mod.Running() {
if err := mod.Configure(); err != nil {
return err
}
defer w.handle.Close()
defer mod.handle.Close()
}
type flow struct {
@ -93,14 +93,14 @@ func (w *WiFiModule) startDeauth(to net.HardwareAddr) error {
toDeauth := make([]flow, 0)
isBcast := network.IsBroadcastMac(to)
for _, ap := range w.Session.WiFi.List() {
for _, ap := range mod.Session.WiFi.List() {
isAP := bytes.Equal(ap.HW, to)
for _, client := range ap.Clients() {
if isBcast || isAP || bytes.Equal(client.HW, to) {
if !w.skipDeauth(ap.HW) && !w.skipDeauth(client.HW) {
if !mod.skipDeauth(ap.HW) && !mod.skipDeauth(client.HW) {
toDeauth = append(toDeauth, flow{Ap: ap, Client: client})
} else {
w.Debug("skipping ap:%v client:%v because skip list %v", ap, client, w.deauthSkip)
mod.Debug("skipping ap:%v client:%v because skip list %v", ap, client, mod.deauthSkip)
}
}
}
@ -114,8 +114,8 @@ func (w *WiFiModule) startDeauth(to net.HardwareAddr) error {
}
go func() {
w.writes.Add(1)
defer w.writes.Done()
mod.writes.Add(1)
defer mod.writes.Done()
// since we need to change the wifi adapter channel for each
// deauth packet, let's sort by channel so we do the minimum
@ -128,19 +128,19 @@ func (w *WiFiModule) startDeauth(to net.HardwareAddr) error {
for _, deauth := range toDeauth {
client := deauth.Client
ap := deauth.Ap
if w.Running() {
logger := w.Info
if w.isDeauthSilent() {
logger = w.Debug
if mod.Running() {
logger := mod.Info
if mod.isDeauthSilent() {
logger = mod.Debug
}
if ap.IsOpen() && !w.doDeauthOpen() {
w.Debug("skipping deauth for open network %s (wifi.deauth.open is false)", ap.ESSID())
if ap.IsOpen() && !mod.doDeauthOpen() {
mod.Debug("skipping deauth for open network %s (wifi.deauth.open is false)", ap.ESSID())
} else {
logger("deauthing client %s from AP %s (channel:%d encryption:%s)", client.String(), ap.ESSID(), ap.Channel(), ap.Encryption)
w.onChannel(ap.Channel(), func() {
w.sendDeauthPacket(ap.HW, client.HW)
mod.onChannel(ap.Channel(), func() {
mod.sendDeauthPacket(ap.HW, client.HW)
})
}
}

View file

@ -6,12 +6,12 @@ import (
"github.com/bettercap/bettercap/network"
)
type WiFiClientEvent struct {
type ClientEvent struct {
AP *network.AccessPoint
Client *network.Station
}
type WiFiProbeEvent struct {
type ProbeEvent struct {
FromAddr net.HardwareAddr
FromVendor string
FromAlias string
@ -19,7 +19,7 @@ type WiFiProbeEvent struct {
RSSI int8
}
type WiFiHandshakeEvent struct {
type HandshakeEvent struct {
File string
NewPackets int
AP net.HardwareAddr

View file

@ -6,64 +6,64 @@ import (
"github.com/bettercap/bettercap/network"
)
func (w *WiFiModule) onChannel(channel int, cb func()) {
w.chanLock.Lock()
defer w.chanLock.Unlock()
func (mod *WiFiModule) onChannel(channel int, cb func()) {
mod.chanLock.Lock()
defer mod.chanLock.Unlock()
prev := w.stickChan
w.stickChan = channel
prev := mod.stickChan
mod.stickChan = channel
if err := network.SetInterfaceChannel(w.Session.Interface.Name(), channel); err != nil {
w.Warning("error while hopping to channel %d: %s", channel, err)
if err := network.SetInterfaceChannel(mod.Session.Interface.Name(), channel); err != nil {
mod.Warning("error while hopping to channel %d: %s", channel, err)
} else {
w.Debug("hopped on channel %d", channel)
mod.Debug("hopped on channel %d", channel)
}
cb()
w.stickChan = prev
mod.stickChan = prev
}
func (w *WiFiModule) channelHopper() {
w.reads.Add(1)
defer w.reads.Done()
func (mod *WiFiModule) channelHopper() {
mod.reads.Add(1)
defer mod.reads.Done()
w.Info("channel hopper started.")
mod.Info("channel hopper started.")
for w.Running() {
delay := w.hopPeriod
for mod.Running() {
delay := mod.hopPeriod
// if we have both 2.4 and 5ghz capabilities, we have
// more channels, therefore we need to increase the time
// we hop on each one otherwise me lose information
if len(w.frequencies) > 14 {
if len(mod.frequencies) > 14 {
delay = delay * 2
}
frequencies := w.frequencies
frequencies := mod.frequencies
loopCurrentChannels:
for _, frequency := range frequencies {
channel := network.Dot11Freq2Chan(frequency)
// stick to the access point channel as long as it's selected
// or as long as we're deauthing on it
if w.stickChan != 0 {
channel = w.stickChan
if mod.stickChan != 0 {
channel = mod.stickChan
}
w.Debug("hopping on channel %d", channel)
mod.Debug("hopping on channel %d", channel)
w.chanLock.Lock()
if err := network.SetInterfaceChannel(w.Session.Interface.Name(), channel); err != nil {
w.Warning("error while hopping to channel %d: %s", channel, err)
mod.chanLock.Lock()
if err := network.SetInterfaceChannel(mod.Session.Interface.Name(), channel); err != nil {
mod.Warning("error while hopping to channel %d: %s", channel, err)
}
w.chanLock.Unlock()
mod.chanLock.Unlock()
select {
case _ = <-w.hopChanges:
w.Debug("hop changed")
case _ = <-mod.hopChanges:
mod.Debug("hop changed")
break loopCurrentChannels
case <-time.After(delay):
if !w.Running() {
if !mod.Running() {
return
}
}

View file

@ -13,28 +13,28 @@ import (
var maxStationTTL = 5 * time.Minute
func (w *WiFiModule) stationPruner() {
w.reads.Add(1)
defer w.reads.Done()
func (mod *WiFiModule) stationPruner() {
mod.reads.Add(1)
defer mod.reads.Done()
w.Debug("wifi stations pruner started.")
for w.Running() {
mod.Debug("wifi stations pruner started.")
for mod.Running() {
// loop every AP
for _, ap := range w.Session.WiFi.List() {
for _, ap := range mod.Session.WiFi.List() {
sinceLastSeen := time.Since(ap.LastSeen)
if sinceLastSeen > maxStationTTL {
w.Debug("station %s not seen in %s, removing.", ap.BSSID(), sinceLastSeen)
w.Session.WiFi.Remove(ap.BSSID())
mod.Debug("station %s not seen in %s, removing.", ap.BSSID(), sinceLastSeen)
mod.Session.WiFi.Remove(ap.BSSID())
continue
}
// loop every AP client
for _, c := range ap.Clients() {
sinceLastSeen := time.Since(c.LastSeen)
if sinceLastSeen > maxStationTTL {
w.Debug("client %s of station %s not seen in %s, removing.", c.String(), ap.BSSID(), sinceLastSeen)
mod.Debug("client %s of station %s not seen in %s, removing.", c.String(), ap.BSSID(), sinceLastSeen)
ap.RemoveClient(c.BSSID())
w.Session.Events.Add("wifi.client.lost", WiFiClientEvent{
mod.Session.Events.Add("wifi.client.lost", ClientEvent{
AP: ap,
Client: c,
})
@ -45,18 +45,18 @@ func (w *WiFiModule) stationPruner() {
}
}
func (w *WiFiModule) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
func (mod *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) {
if mod.apRunning && bytes.Equal(from, mod.apConfig.BSSID) {
return
}
if !network.IsZeroMac(from) && !network.IsBroadcastMac(from) {
if int(radiotap.DBMAntennaSignal) >= w.minRSSI {
if int(radiotap.DBMAntennaSignal) >= mod.minRSSI {
var frequency int
bssid := from.String()
@ -66,19 +66,19 @@ func (w *WiFiModule) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *laye
frequency = int(radiotap.ChannelFrequency)
}
if ap, isNew := w.Session.WiFi.AddIfNew(ssid, bssid, frequency, radiotap.DBMAntennaSignal); !isNew {
if ap, isNew := mod.Session.WiFi.AddIfNew(ssid, bssid, frequency, radiotap.DBMAntennaSignal); !isNew {
ap.EachClient(func(mac string, station *network.Station) {
station.Handshake.SetBeacon(packet)
})
}
} else {
w.Debug("skipping %s with %d dBm", from.String(), radiotap.DBMAntennaSignal)
mod.Debug("skipping %s with %d dBm", from.String(), radiotap.DBMAntennaSignal)
}
}
}
}
func (w *WiFiModule) discoverProbes(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
func (mod *WiFiModule) discoverProbes(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
if dot11.Type != layers.Dot11TypeMgmtProbeReq {
return
}
@ -107,17 +107,17 @@ func (w *WiFiModule) discoverProbes(radiotap *layers.RadioTap, dot11 *layers.Dot
return
}
w.Session.Events.Add("wifi.client.probe", WiFiProbeEvent{
mod.Session.Events.Add("wifi.client.probe", ProbeEvent{
FromAddr: dot11.Address2,
FromVendor: network.ManufLookup(dot11.Address2.String()),
FromAlias: w.Session.Lan.GetAlias(dot11.Address2.String()),
FromAlias: mod.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) {
func (mod *WiFiModule) discoverClients(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
mod.Session.WiFi.EachAccessPoint(func(bssid string, ap *network.AccessPoint) {
// packet going to this specific BSSID?
if packets.Dot11IsDataFor(dot11, ap.HW) {
bssid := dot11.Address2.String()
@ -125,7 +125,7 @@ func (w *WiFiModule) discoverClients(radiotap *layers.RadioTap, dot11 *layers.Do
rssi := radiotap.DBMAntennaSignal
if station, isNew := ap.AddClientIfNew(bssid, freq, rssi); isNew {
w.Session.Events.Add("wifi.client.new", WiFiClientEvent{
mod.Session.Events.Add("wifi.client.new", ClientEvent{
AP: ap,
Client: station,
})
@ -143,12 +143,12 @@ func allZeros(s []byte) bool {
return true
}
func (w *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
func (mod *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
if ok, key, apMac, staMac := packets.Dot11ParseEAPOL(packet, dot11); ok {
// first, locate the AP in our list by its BSSID
ap, found := w.Session.WiFi.Get(apMac.String())
ap, found := mod.Session.WiFi.Get(apMac.String())
if !found {
w.Warning("could not find AP with BSSID %s", apMac.String())
mod.Warning("could not find AP with BSSID %s", apMac.String())
return
}
@ -158,7 +158,7 @@ func (w *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers
// (Reference about PMKID https://hashcat.net/forum/thread-7717.html)
// In this case, we need to add ourselves as a client station of the AP
// in order to have a consistent association of AP, client and handshakes.
staIsUs := bytes.Equal(staMac, w.Session.Interface.HW)
staIsUs := bytes.Equal(staMac, mod.Session.Interface.HW)
station, found := ap.Get(staMac.String())
if !found {
station, _ = ap.AddClientIfNew(staMac.String(), ap.Frequency, ap.RSSI)
@ -173,7 +173,7 @@ func (w *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers
PMKID = "with PMKID"
}
w.Debug("got frame 1/4 of the %s <-> %s handshake (%s) (anonce:%x)",
mod.Debug("got frame 1/4 of the %s <-> %s handshake (%s) (anonce:%x)",
apMac,
staMac,
PMKID,
@ -182,7 +182,7 @@ func (w *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers
// [2] (MIC) client is sending SNonce+MIC to the API
station.Handshake.AddFrame(1, packet)
w.Debug("got frame 2/4 of the %s <-> %s handshake (snonce:%x mic:%x)",
mod.Debug("got frame 2/4 of the %s <-> %s handshake (snonce:%x mic:%x)",
apMac,
staMac,
key.Nonce,
@ -191,7 +191,7 @@ func (w *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers
// [3]: (INSTALL+ACK+MIC) AP informs the client that the PTK is installed
station.Handshake.AddFrame(2, packet)
w.Debug("got frame 3/4 of the %s <-> %s handshake (mic:%x)",
mod.Debug("got frame 3/4 of the %s <-> %s handshake (mic:%x)",
apMac,
staMac,
key.MIC)
@ -200,18 +200,18 @@ func (w *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers
// if we have unsaved packets as part of the handshake, save them.
numUnsaved := station.Handshake.NumUnsaved()
doSave := numUnsaved > 0
if doSave && w.shakesFile != "" {
w.Debug("saving handshake frames to %s", w.shakesFile)
if err := w.Session.WiFi.SaveHandshakesTo(w.shakesFile, w.handle.LinkType()); err != nil {
w.Error("error while saving handshake frames to %s: %s", w.shakesFile, err)
if doSave && mod.shakesFile != "" {
mod.Debug("saving handshake frames to %s", mod.shakesFile)
if err := mod.Session.WiFi.SaveHandshakesTo(mod.shakesFile, mod.handle.LinkType()); err != nil {
mod.Error("error while saving handshake frames to %s: %s", mod.shakesFile, err)
}
}
// if we had unsaved packets and either the handshake is complete
// or it contains the PMKID, generate a new event.
if doSave && (rawPMKID != nil || station.Handshake.Complete()) {
w.Session.Events.Add("wifi.client.handshake", WiFiHandshakeEvent{
File: w.shakesFile,
mod.Session.Events.Add("wifi.client.handshake", HandshakeEvent{
File: mod.shakesFile,
NewPackets: numUnsaved,
AP: apMac,
Station: staMac,

View file

@ -8,7 +8,7 @@ import (
"strings"
"time"
"github.com/bettercap/bettercap/modules/discovery"
"github.com/bettercap/bettercap/modules/net_recon"
"github.com/bettercap/bettercap/network"
"github.com/dustin/go-humanize"
@ -17,11 +17,11 @@ import (
"github.com/evilsocket/islazy/tui"
)
func (w *WiFiModule) isApSelected() bool {
return w.ap != nil
func (mod *WiFiModule) isApSelected() bool {
return mod.ap != nil
}
func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) {
func (mod *WiFiModule) getRow(station *network.Station) ([]string, bool) {
// ref. https://www.metageek.com/training/resources/understanding-rssi-2.html
rssi := fmt.Sprintf("%d dBm", station.RSSI)
if station.RSSI >= -67 {
@ -35,19 +35,19 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) {
}
bssid := station.HwAddress
sinceStarted := time.Since(w.Session.StartedAt)
sinceStarted := time.Since(mod.Session.StartedAt)
sinceFirstSeen := time.Since(station.FirstSeen)
if sinceStarted > (discovery.JustJoinedTimeInterval*2) && sinceFirstSeen <= discovery.JustJoinedTimeInterval {
if sinceStarted > (net_recon.JustJoinedTimeInterval*2) && sinceFirstSeen <= net_recon.JustJoinedTimeInterval {
// if endpoint was first seen in the last 10 seconds
bssid = tui.Bold(bssid)
}
seen := station.LastSeen.Format("15:04:05")
sinceLastSeen := time.Since(station.LastSeen)
if sinceStarted > discovery.AliveTimeInterval && sinceLastSeen <= discovery.AliveTimeInterval {
if sinceStarted > net_recon.AliveTimeInterval && sinceLastSeen <= net_recon.AliveTimeInterval {
// if endpoint seen in the last 10 seconds
seen = tui.Bold(seen)
} else if sinceLastSeen > discovery.PresentTimeInterval {
} else if sinceLastSeen > net_recon.PresentTimeInterval {
// if endpoint not seen in the last 60 seconds
seen = tui.Dim(seen)
}
@ -67,7 +67,7 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) {
// this is ugly, but necessary in order to have this
// method handle both access point and clients
// transparently
if ap, found := w.Session.WiFi.Get(station.HwAddress); found && (ap.HasHandshakes() || ap.HasPMKID()) {
if ap, found := mod.Session.WiFi.Get(station.HwAddress); found && (ap.HasHandshakes() || ap.HasPMKID()) {
encryption = tui.Red(encryption)
}
}
@ -76,8 +76,8 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) {
recvd := ops.Ternary(station.Received > 0, humanize.Bytes(station.Received), "").(string)
include := false
if w.source == "" {
for _, frequencies := range w.frequencies {
if mod.source == "" {
for _, frequencies := range mod.frequencies {
if frequencies == station.Frequency {
include = true
break
@ -87,11 +87,11 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) {
include = true
}
if int(station.RSSI) < w.minRSSI {
if int(station.RSSI) < mod.minRSSI {
include = false
}
if w.isApSelected() {
if mod.isApSelected() {
return []string{
rssi,
bssid,
@ -105,7 +105,7 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) {
// method handle both access point and clients
// transparently
clients := ""
if ap, found := w.Session.WiFi.Get(station.HwAddress); found {
if ap, found := mod.Session.WiFi.Get(station.HwAddress); found {
if ap.NumClients() > 0 {
clients = strconv.Itoa(ap.NumClients())
}
@ -143,43 +143,43 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) {
}
}
func (w *WiFiModule) doFilter(station *network.Station) bool {
if w.selector.Expression == nil {
func (mod *WiFiModule) doFilter(station *network.Station) bool {
if mod.selector.Expression == nil {
return true
}
return w.selector.Expression.MatchString(station.BSSID()) ||
w.selector.Expression.MatchString(station.ESSID()) ||
w.selector.Expression.MatchString(station.Alias) ||
w.selector.Expression.MatchString(station.Vendor) ||
w.selector.Expression.MatchString(station.Encryption)
return mod.selector.Expression.MatchString(station.BSSID()) ||
mod.selector.Expression.MatchString(station.ESSID()) ||
mod.selector.Expression.MatchString(station.Alias) ||
mod.selector.Expression.MatchString(station.Vendor) ||
mod.selector.Expression.MatchString(station.Encryption)
}
func (w *WiFiModule) doSelection() (err error, stations []*network.Station) {
if err = w.selector.Update(); err != nil {
func (mod *WiFiModule) doSelection() (err error, stations []*network.Station) {
if err = mod.selector.Update(); err != nil {
return
}
apSelected := w.isApSelected()
apSelected := mod.isApSelected()
if apSelected {
if ap, found := w.Session.WiFi.Get(w.ap.HwAddress); found {
if ap, found := mod.Session.WiFi.Get(mod.ap.HwAddress); found {
stations = ap.Clients()
} else {
err = fmt.Errorf("Could not find station %s", w.ap.HwAddress)
err = fmt.Errorf("Could not find station %s", mod.ap.HwAddress)
return
}
} else {
stations = w.Session.WiFi.Stations()
stations = mod.Session.WiFi.Stations()
}
filtered := []*network.Station{}
for _, station := range stations {
if w.doFilter(station) {
if mod.doFilter(station) {
filtered = append(filtered, station)
}
}
stations = filtered
switch w.selector.SortField {
switch mod.selector.SortField {
case "seen":
sort.Sort(ByWiFiSeenSorter(stations))
case "essid":
@ -203,7 +203,7 @@ func (w *WiFiModule) doSelection() (err error, stations []*network.Station) {
}
// default is asc
if w.selector.Sort == "desc" {
if mod.selector.Sort == "desc" {
// from https://github.com/golang/go/wiki/SliceTricks
for i := len(stations)/2 - 1; i >= 0; i-- {
opp := len(stations) - 1 - i
@ -211,8 +211,8 @@ func (w *WiFiModule) doSelection() (err error, stations []*network.Station) {
}
}
if w.selector.Limit > 0 {
limit := w.selector.Limit
if mod.selector.Limit > 0 {
limit := mod.selector.Limit
max := len(stations)
if limit > max {
limit = max
@ -223,7 +223,7 @@ func (w *WiFiModule) doSelection() (err error, stations []*network.Station) {
return
}
func (w *WiFiModule) colDecorate(colNames []string, name string, dir string) {
func (mod *WiFiModule) colDecorate(colNames []string, name string, dir string) {
for i, c := range colNames {
if c == name {
colNames[i] += " " + dir
@ -232,101 +232,101 @@ func (w *WiFiModule) colDecorate(colNames []string, name string, dir string) {
}
}
func (w *WiFiModule) colNames(nrows int) []string {
func (mod *WiFiModule) colNames(nrows int) []string {
columns := []string(nil)
if !w.isApSelected() {
if !mod.isApSelected() {
columns = []string{"RSSI", "BSSID", "SSID", "Encryption", "WPS", "Ch", "Clients", "Sent", "Recvd", "Seen"}
} else if nrows > 0 {
columns = []string{"RSSI", "BSSID", "Ch", "Sent", "Recvd", "Seen"}
fmt.Printf("\n%s clients:\n", w.ap.HwAddress)
fmt.Printf("\n%s clients:\n", mod.ap.HwAddress)
} else {
fmt.Printf("\nNo authenticated clients detected for %s.\n", w.ap.HwAddress)
fmt.Printf("\nNo authenticated clients detected for %s.\n", mod.ap.HwAddress)
}
if columns != nil {
switch w.selector.SortField {
switch mod.selector.SortField {
case "seen":
w.colDecorate(columns, "Seen", w.selector.SortSymbol)
mod.colDecorate(columns, "Seen", mod.selector.SortSymbol)
case "essid":
w.colDecorate(columns, "SSID", w.selector.SortSymbol)
mod.colDecorate(columns, "SSID", mod.selector.SortSymbol)
case "bssid":
w.colDecorate(columns, "BSSID", w.selector.SortSymbol)
mod.colDecorate(columns, "BSSID", mod.selector.SortSymbol)
case "channel":
w.colDecorate(columns, "Ch", w.selector.SortSymbol)
mod.colDecorate(columns, "Ch", mod.selector.SortSymbol)
case "clients":
w.colDecorate(columns, "Clients", w.selector.SortSymbol)
mod.colDecorate(columns, "Clients", mod.selector.SortSymbol)
case "encryption":
w.colDecorate(columns, "Encryption", w.selector.SortSymbol)
mod.colDecorate(columns, "Encryption", mod.selector.SortSymbol)
case "sent":
w.colDecorate(columns, "Sent", w.selector.SortSymbol)
mod.colDecorate(columns, "Sent", mod.selector.SortSymbol)
case "rcvd":
w.colDecorate(columns, "Recvd", w.selector.SortSymbol)
mod.colDecorate(columns, "Recvd", mod.selector.SortSymbol)
case "rssi":
w.colDecorate(columns, "RSSI", w.selector.SortSymbol)
mod.colDecorate(columns, "RSSI", mod.selector.SortSymbol)
}
}
return columns
}
func (w *WiFiModule) showStatusBar() {
w.Session.Queue.Stats.RLock()
defer w.Session.Queue.Stats.RUnlock()
func (mod *WiFiModule) showStatusBar() {
mod.Session.Queue.Stats.RLock()
defer mod.Session.Queue.Stats.RUnlock()
parts := []string{
fmt.Sprintf("%s (ch. %d)", w.Session.Interface.Name(), network.GetInterfaceChannel(w.Session.Interface.Name())),
fmt.Sprintf("%s %s", tui.Red("↑"), humanize.Bytes(w.Session.Queue.Stats.Sent)),
fmt.Sprintf("%s %s", tui.Green("↓"), humanize.Bytes(w.Session.Queue.Stats.Received)),
fmt.Sprintf("%d pkts", w.Session.Queue.Stats.PktReceived),
fmt.Sprintf("%s (ch. %d)", mod.Session.Interface.Name(), network.GetInterfaceChannel(mod.Session.Interface.Name())),
fmt.Sprintf("%s %s", tui.Red("↑"), humanize.Bytes(mod.Session.Queue.Stats.Sent)),
fmt.Sprintf("%s %s", tui.Green("↓"), humanize.Bytes(mod.Session.Queue.Stats.Received)),
fmt.Sprintf("%d pkts", mod.Session.Queue.Stats.PktReceived),
}
if nErrors := w.Session.Queue.Stats.Errors; nErrors > 0 {
if nErrors := mod.Session.Queue.Stats.Errors; nErrors > 0 {
parts = append(parts, fmt.Sprintf("%d errs", nErrors))
}
if nHandshakes := w.Session.WiFi.NumHandshakes(); nHandshakes > 0 {
if nHandshakes := mod.Session.WiFi.NumHandshakes(); nHandshakes > 0 {
parts = append(parts, fmt.Sprintf("%d handshakes", nHandshakes))
}
fmt.Printf("\n%s\n\n", strings.Join(parts, " / "))
}
func (w *WiFiModule) Show() (err error) {
func (mod *WiFiModule) Show() (err error) {
var stations []*network.Station
if err, stations = w.doSelection(); err != nil {
if err, stations = mod.doSelection(); err != nil {
return
}
rows := make([][]string, 0)
for _, s := range stations {
if row, include := w.getRow(s); include {
if row, include := mod.getRow(s); include {
rows = append(rows, row)
}
}
nrows := len(rows)
if nrows > 0 {
tui.Table(os.Stdout, w.colNames(nrows), rows)
tui.Table(os.Stdout, mod.colNames(nrows), rows)
}
w.showStatusBar()
mod.showStatusBar()
w.Session.Refresh()
mod.Session.Refresh()
return nil
}
func (w *WiFiModule) ShowWPS(bssid string) (err error) {
func (mod *WiFiModule) ShowWPS(bssid string) (err error) {
toShow := []*network.Station{}
if bssid == network.BroadcastMac {
for _, station := range w.Session.WiFi.List() {
for _, station := range mod.Session.WiFi.List() {
if station.HasWPS() {
toShow = append(toShow, station.Station)
}
}
} else {
if station, found := w.Session.WiFi.Get(bssid); found {
if station, found := mod.Session.WiFi.Get(bssid); found {
if station.HasWPS() {
toShow = append(toShow, station.Station)
}