diff --git a/modules/wifi.go b/modules/wifi.go index b80bdec2..9aad9490 100644 --- a/modules/wifi.go +++ b/modules/wifi.go @@ -33,6 +33,7 @@ type WiFiModule struct { skipBroken bool pktSourceChan chan gopacket.Packet pktSourceChanClosed bool + deauthSkip []net.HardwareAddr apRunning bool apConfig packets.Dot11ApConfig writes *sync.WaitGroup @@ -49,6 +50,7 @@ func NewWiFiModule(s *session.Session) *WiFiModule { ap: nil, skipBroken: true, apRunning: false, + deauthSkip: []net.HardwareAddr{}, writes: &sync.WaitGroup{}, reads: &sync.WaitGroup{}, chanLock: &sync.Mutex{}, @@ -99,6 +101,11 @@ func NewWiFiModule(s *session.Session) *WiFiModule { return w.startDeauth(bssid) })) + w.AddParam(session.NewStringParameter("wifi.deauth.skip", + "", + "", + "Comma separated list of BSSID to skip while sending deauth packets.")) + w.AddHandler(session.NewModuleHandler("wifi.ap", "", "Inject fake management beacons in order to create a rogue access point.", func(args []string) error { diff --git a/modules/wifi_deauth.go b/modules/wifi_deauth.go index fce8ab4f..9cb026ac 100644 --- a/modules/wifi_deauth.go +++ b/modules/wifi_deauth.go @@ -41,7 +41,25 @@ func (w *WiFiModule) sendDeauthPacket(ap net.HardwareAddr, client net.HardwareAd } } +func (w *WiFiModule) skipDeauth(to net.HardwareAddr) bool { + for _, mac := range w.deauthSkip { + if bytes.Equal(to, mac) { + return true + } + } + return false +} + func (w *WiFiModule) startDeauth(to net.HardwareAddr) error { + // parse skip list + if err, deauthSkip := w.StringParam("wifi.deauth.skip"); err != nil { + return err + } else if macs, err := network.ParseMACs(deauthSkip); err != nil { + return err + } else { + w.deauthSkip = macs + } + // if not already running, temporarily enable the pcap handle // for packet injection if !w.Running() { @@ -62,7 +80,11 @@ func (w *WiFiModule) startDeauth(to net.HardwareAddr) error { isAP := bytes.Equal(ap.HW, to) for _, client := range ap.Clients() { if isBcast || isAP || bytes.Equal(client.HW, to) { - toDeauth = append(toDeauth, flow{Ap: ap, Client: client}) + if !w.skipDeauth(ap.HW) && !w.skipDeauth(client.HW) { + toDeauth = append(toDeauth, flow{Ap: ap, Client: client}) + } else { + log.Debug("skipping ap:%v client:%v because skip list %v", ap, client, w.deauthSkip) + } } } } diff --git a/network/net.go b/network/net.go index 3e11a6b7..1d2e1099 100644 --- a/network/net.go +++ b/network/net.go @@ -68,6 +68,26 @@ func NormalizeMac(mac string) string { return strings.ToLower(strings.Join(parts, ":")) } +func ParseMACs(targets string) (macs []net.HardwareAddr, err error) { + macs = make([]net.HardwareAddr, 0) + if targets = str.Trim(targets); targets == "" { + return + } + + for _, mac := range macParser.FindAllString(targets, -1) { + mac = NormalizeMac(mac) + hw, err := net.ParseMAC(mac) + if err != nil { + return nil, fmt.Errorf("Error while parsing MAC '%s': %s", mac, err) + } + + macs = append(macs, hw) + targets = strings.Replace(targets, mac, "", -1) + } + + return +} + func ParseTargets(targets string, aliasMap *data.UnsortedKV) (ips []net.IP, macs []net.HardwareAddr, err error) { ips = make([]net.IP, 0) macs = make([]net.HardwareAddr, 0)