mirror of
https://github.com/bettercap/bettercap
synced 2025-07-16 10:03:39 -07:00
new: new wifi.ap module
This commit is contained in:
parent
8444a783a1
commit
77f8e070bc
7 changed files with 518 additions and 451 deletions
351
modules/wifi.go
Normal file
351
modules/wifi.go
Normal file
|
@ -0,0 +1,351 @@
|
||||||
|
package modules
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/bettercap/bettercap/core"
|
||||||
|
"github.com/bettercap/bettercap/log"
|
||||||
|
"github.com/bettercap/bettercap/network"
|
||||||
|
"github.com/bettercap/bettercap/packets"
|
||||||
|
"github.com/bettercap/bettercap/session"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
"github.com/google/gopacket/layers"
|
||||||
|
"github.com/google/gopacket/pcap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WiFiModule struct {
|
||||||
|
session.SessionModule
|
||||||
|
|
||||||
|
handle *pcap.Handle
|
||||||
|
source string
|
||||||
|
channel int
|
||||||
|
hopPeriod time.Duration
|
||||||
|
frequencies []int
|
||||||
|
ap *network.AccessPoint
|
||||||
|
stickChan int
|
||||||
|
skipBroken bool
|
||||||
|
pktSourceChan chan gopacket.Packet
|
||||||
|
pktSourceChanClosed bool
|
||||||
|
apRunning bool
|
||||||
|
apConfig packets.Dot11ApConfig
|
||||||
|
writes *sync.WaitGroup
|
||||||
|
reads *sync.WaitGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWiFiModule(s *session.Session) *WiFiModule {
|
||||||
|
w := &WiFiModule{
|
||||||
|
SessionModule: session.NewSessionModule("wifi", s),
|
||||||
|
channel: 0,
|
||||||
|
stickChan: 0,
|
||||||
|
hopPeriod: 250 * time.Millisecond,
|
||||||
|
ap: nil,
|
||||||
|
skipBroken: true,
|
||||||
|
apRunning: false,
|
||||||
|
writes: &sync.WaitGroup{},
|
||||||
|
reads: &sync.WaitGroup{},
|
||||||
|
}
|
||||||
|
|
||||||
|
w.AddHandler(session.NewModuleHandler("wifi.recon on", "",
|
||||||
|
"Start 802.11 wireless base stations discovery and channel hopping.",
|
||||||
|
func(args []string) error {
|
||||||
|
return w.Start()
|
||||||
|
}))
|
||||||
|
|
||||||
|
w.AddHandler(session.NewModuleHandler("wifi.recon off", "",
|
||||||
|
"Stop 802.11 wireless base stations discovery and channel hopping.",
|
||||||
|
func(args []string) error {
|
||||||
|
return w.Stop()
|
||||||
|
}))
|
||||||
|
|
||||||
|
w.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 == true {
|
||||||
|
w.ap = ap
|
||||||
|
w.stickChan = network.Dot11Freq2Chan(ap.Frequency)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Could not find station with BSSID %s", args[0])
|
||||||
|
}))
|
||||||
|
|
||||||
|
w.AddHandler(session.NewModuleHandler("wifi.recon clear", "",
|
||||||
|
"Remove the 802.11 base station filter.",
|
||||||
|
func(args []string) error {
|
||||||
|
w.ap = nil
|
||||||
|
w.stickChan = 0
|
||||||
|
var err error
|
||||||
|
if w.frequencies, err = network.GetSupportedFrequencies(w.Session.Interface.Name()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
|
|
||||||
|
w.AddHandler(session.NewModuleHandler("wifi.deauth BSSID", `wifi\.deauth ((?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]{2}))`,
|
||||||
|
"Start a 802.11 deauth attack, if an access point BSSID is provided, every client will be deauthenticated, otherwise only the selected client.",
|
||||||
|
func(args []string) error {
|
||||||
|
bssid, err := net.ParseMAC(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return w.startDeauth(bssid)
|
||||||
|
}))
|
||||||
|
|
||||||
|
w.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 {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
return w.startAp()
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
w.AddParam(session.NewStringParameter("wifi.ap.ssid",
|
||||||
|
"FreeWiFi",
|
||||||
|
"",
|
||||||
|
"SSID of the fake access point."))
|
||||||
|
|
||||||
|
w.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",
|
||||||
|
"1",
|
||||||
|
"Channel of the fake access point."))
|
||||||
|
|
||||||
|
w.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", "",
|
||||||
|
"Show current wireless stations list (default sorting by essid).",
|
||||||
|
func(args []string) error {
|
||||||
|
return w.Show("rssi")
|
||||||
|
}))
|
||||||
|
|
||||||
|
w.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) error {
|
||||||
|
newfrequencies := w.frequencies[:0]
|
||||||
|
|
||||||
|
if len(args) > 0 && args[0] != "clear" {
|
||||||
|
channels := strings.Split(args[0], ",")
|
||||||
|
for _, c := range channels {
|
||||||
|
trimmed := strings.Trim(c, " ")
|
||||||
|
channel, err := strconv.Atoi(trimmed)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newfrequencies = append(newfrequencies, network.Dot11Chan2Freq(channel))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No channels setted, retrieve frequencies supported by the card
|
||||||
|
if frequencies, err := network.GetSupportedFrequencies(w.Session.Interface.Name()); err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
newfrequencies = frequencies
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
w.frequencies = newfrequencies
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
|
|
||||||
|
w.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",
|
||||||
|
"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",
|
||||||
|
"true",
|
||||||
|
"If true, dot11 packets with an invalid checksum will be skipped."))
|
||||||
|
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WiFiModule) Name() string {
|
||||||
|
return "wifi"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WiFiModule) Description() string {
|
||||||
|
return "A module to monitor and perform wireless attacks on 802.11."
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WiFiModule) Author() string {
|
||||||
|
return "Gianluca Braga <matrix86@protonmail.com> && Simone Margaritelli <evilsocket@protonmail.com>>"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WiFiModule) Configure() error {
|
||||||
|
var hopPeriod int
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if err, w.source = w.StringParam("wifi.source.file"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if w.source != "" {
|
||||||
|
if w.handle, err = pcap.OpenOffline(w.source); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ihandle, err := pcap.NewInactiveHandle(w.Session.Interface.Name())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer ihandle.CleanUp()
|
||||||
|
|
||||||
|
if err = ihandle.SetRFMon(true); err != nil {
|
||||||
|
return fmt.Errorf("Error while setting interface %s in monitor mode: %s", core.Bold(w.Session.Interface.Name()), err)
|
||||||
|
} else if err = ihandle.SetSnapLen(65536); err != nil {
|
||||||
|
return err
|
||||||
|
} else if err = ihandle.SetTimeout(pcap.BlockForever); err != nil {
|
||||||
|
return err
|
||||||
|
} else if w.handle, err = ihandle.Activate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err, w.skipBroken = w.BoolParam("wifi.skip-broken"); err != nil {
|
||||||
|
return err
|
||||||
|
} else if err, hopPeriod = w.IntParam("wifi.hop.period"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
w.hopPeriod = time.Duration(hopPeriod) * time.Millisecond
|
||||||
|
|
||||||
|
if w.source == "" {
|
||||||
|
// No channels setted, retrieve frequencies supported by the card
|
||||||
|
if len(w.frequencies) == 0 {
|
||||||
|
if w.frequencies, err = network.GetSupportedFrequencies(w.Session.Interface.Name()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// we need to start somewhere, this is just to check if
|
||||||
|
// this OS supports switching channel programmatically.
|
||||||
|
if err = network.SetInterfaceChannel(w.Session.Interface.Name(), 1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Info("WiFi recon active with channel hopping.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *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 == true {
|
||||||
|
station.Received += bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
src := dot11.Address2.String()
|
||||||
|
if station, found := w.Session.WiFi.Get(src); found == true {
|
||||||
|
station.Sent += bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok, enc, cipher, auth := packets.Dot11ParseEncryption(packet, dot11); ok == true {
|
||||||
|
bssid := dot11.Address3.String()
|
||||||
|
if station, found := w.Session.WiFi.Get(bssid); found == true {
|
||||||
|
station.Encryption = enc
|
||||||
|
station.Cipher = cipher
|
||||||
|
station.Authentication = auth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WiFiModule) 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 *WiFiModule) Start() error {
|
||||||
|
if err := w.Configure(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
w.SetRunning(true, func() {
|
||||||
|
// start channel hopper if needed
|
||||||
|
if w.channel == 0 && w.source == "" {
|
||||||
|
go w.channelHopper()
|
||||||
|
}
|
||||||
|
|
||||||
|
// start the pruner
|
||||||
|
go w.stationPruner()
|
||||||
|
|
||||||
|
w.reads.Add(1)
|
||||||
|
defer w.reads.Done()
|
||||||
|
|
||||||
|
src := gopacket.NewPacketSource(w.handle, w.handle.LinkType())
|
||||||
|
w.pktSourceChan = src.Packets()
|
||||||
|
for packet := range w.pktSourceChan {
|
||||||
|
if w.Running() == false {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if packet == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
w.trackPacket(packet)
|
||||||
|
|
||||||
|
// perform initial dot11 parsing and layers validation
|
||||||
|
if ok, radiotap, dot11 := packets.Dot11Parse(packet); ok == true {
|
||||||
|
// check FCS checksum
|
||||||
|
if w.skipBroken && dot11.ChecksumValid() == false {
|
||||||
|
log.Debug("Skipping dot11 packet with invalid checksum.")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
w.discoverProbes(radiotap, dot11, packet)
|
||||||
|
w.discoverAccessPoints(radiotap, dot11, packet)
|
||||||
|
w.discoverClients(radiotap, dot11, packet)
|
||||||
|
w.updateStats(dot11, packet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.pktSourceChanClosed = true
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WiFiModule) Stop() error {
|
||||||
|
return w.SetRunning(false, func() {
|
||||||
|
// wait any pending write operation
|
||||||
|
w.writes.Wait()
|
||||||
|
// signal the main for loop we want to exit
|
||||||
|
if w.pktSourceChanClosed == false {
|
||||||
|
w.pktSourceChan <- nil
|
||||||
|
}
|
||||||
|
// close the pcap handle to make the main for exit
|
||||||
|
w.handle.Close()
|
||||||
|
// close the pcap handle to make the main for exit
|
||||||
|
// wait for the loop to exit.
|
||||||
|
w.reads.Wait()
|
||||||
|
})
|
||||||
|
}
|
74
modules/wifi_ap.go
Normal file
74
modules/wifi_ap.go
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
package modules
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/bettercap/bettercap/core"
|
||||||
|
"github.com/bettercap/bettercap/log"
|
||||||
|
"github.com/bettercap/bettercap/network"
|
||||||
|
"github.com/bettercap/bettercap/packets"
|
||||||
|
"github.com/bettercap/bettercap/session"
|
||||||
|
)
|
||||||
|
|
||||||
|
var errNoRecon = errors.New("Module wifi.ap requires module wifi.recon to be activated.")
|
||||||
|
|
||||||
|
func (w *WiFiModule) parseApConfig() (err error) {
|
||||||
|
var bssid string
|
||||||
|
|
||||||
|
if err, w.apConfig.SSID = w.StringParam("wifi.ap.ssid"); err != nil {
|
||||||
|
return
|
||||||
|
} else if err, bssid = w.StringParam("wifi.ap.bssid"); err != nil {
|
||||||
|
return
|
||||||
|
} else if w.apConfig.BSSID, err = net.ParseMAC(network.NormalizeMac(bssid)); err != nil {
|
||||||
|
return
|
||||||
|
} else if err, w.apConfig.Channel = w.IntParam("wifi.ap.channel"); err != nil {
|
||||||
|
return
|
||||||
|
} else if err, w.apConfig.Encryption = w.BoolParam("wifi.ap.encryption"); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WiFiModule) startAp() error {
|
||||||
|
// we need channel hopping and packet injection for this
|
||||||
|
if w.Running() == false {
|
||||||
|
return errNoRecon
|
||||||
|
} else if w.apRunning {
|
||||||
|
return session.ErrAlreadyStarted
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
w.apRunning = true
|
||||||
|
defer func() {
|
||||||
|
w.apRunning = false
|
||||||
|
}()
|
||||||
|
|
||||||
|
enc := core.Yellow("WPA2")
|
||||||
|
if w.apConfig.Encryption == false {
|
||||||
|
enc = core.Green("Open")
|
||||||
|
}
|
||||||
|
log.Info("Sending beacons as SSID %s (%s) on channel %d (%s).",
|
||||||
|
core.Bold(w.apConfig.SSID),
|
||||||
|
w.apConfig.BSSID.String(),
|
||||||
|
w.apConfig.Channel,
|
||||||
|
enc)
|
||||||
|
|
||||||
|
for seqn := uint16(0); w.Running(); seqn++ {
|
||||||
|
w.writes.Add(1)
|
||||||
|
defer w.writes.Done()
|
||||||
|
|
||||||
|
if err, pkt := packets.NewDot11Beacon(w.apConfig, seqn); err != nil {
|
||||||
|
log.Error("Could not create beacon packet: %s", err)
|
||||||
|
} else {
|
||||||
|
w.injectPacket(pkt)
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,129 +0,0 @@
|
||||||
package modules
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rand"
|
|
||||||
"fmt"
|
|
||||||
"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 (
|
|
||||||
openFlags = 1057
|
|
||||||
wpaFlags = 1041
|
|
||||||
//1-54 Mbit
|
|
||||||
supportedRates = []byte{0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, 0x03, 0x01}
|
|
||||||
wpaRSN = []byte{
|
|
||||||
0x01, 0x00, // RSN Version 1
|
|
||||||
0x00, 0x0f, 0xac, 0x02, // Group Cipher Suite : 00-0f-ac TKIP
|
|
||||||
0x02, 0x00, // 2 Pairwise Cipher Suites (next two lines)
|
|
||||||
0x00, 0x0f, 0xac, 0x04, // AES Cipher / CCMP
|
|
||||||
0x00, 0x0f, 0xac, 0x02, // TKIP Cipher
|
|
||||||
0x01, 0x00, // 1 Authentication Key Managment Suite (line below)
|
|
||||||
0x00, 0x0f, 0xac, 0x02, // Pre-Shared Key
|
|
||||||
0x00, 0x00,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
type Dot11BeaconConfig struct {
|
|
||||||
SSID string
|
|
||||||
BSSID net.HardwareAddr
|
|
||||||
Channel int
|
|
||||||
Encryption bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDot11Beacon(conf Dot11BeaconConfig) (error, []byte) {
|
|
||||||
flags := openFlags
|
|
||||||
if conf.Encryption == true {
|
|
||||||
flags = wpaFlags
|
|
||||||
}
|
|
||||||
|
|
||||||
stack := []gopacket.SerializableLayer{
|
|
||||||
&layers.RadioTap{},
|
|
||||||
&layers.Dot11{
|
|
||||||
Address1: network.BroadcastHw,
|
|
||||||
Address2: conf.BSSID,
|
|
||||||
Address3: conf.BSSID,
|
|
||||||
Type: layers.Dot11TypeMgmtBeacon,
|
|
||||||
},
|
|
||||||
&layers.Dot11MgmtBeacon{
|
|
||||||
Flags: uint16(flags),
|
|
||||||
Interval: 100,
|
|
||||||
},
|
|
||||||
&layers.Dot11InformationElement{
|
|
||||||
ID: layers.Dot11InformationElementIDSSID,
|
|
||||||
Length: uint8(len(conf.SSID) & 0xff),
|
|
||||||
Info: []byte(conf.SSID),
|
|
||||||
},
|
|
||||||
&layers.Dot11InformationElement{
|
|
||||||
ID: layers.Dot11InformationElementIDRates,
|
|
||||||
Length: uint8(len(supportedRates) & 0xff),
|
|
||||||
Info: supportedRates,
|
|
||||||
},
|
|
||||||
&layers.Dot11InformationElement{
|
|
||||||
ID: layers.Dot11InformationElementIDDSSet,
|
|
||||||
Length: 1,
|
|
||||||
Info: []byte{byte(conf.Channel & 0xff)},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if conf.Encryption == true {
|
|
||||||
stack = append(stack, &layers.Dot11InformationElement{
|
|
||||||
ID: layers.Dot11InformationElementIDRSNInfo,
|
|
||||||
Length: uint8(len(wpaRSN) & 0xff),
|
|
||||||
Info: wpaRSN,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return packets.Serialize(stack...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WiFiModule) sendBeaconPacket(counter int) {
|
|
||||||
w.writes.Add(1)
|
|
||||||
defer w.writes.Done()
|
|
||||||
|
|
||||||
hw := make([]byte, 6)
|
|
||||||
rand.Read(hw)
|
|
||||||
|
|
||||||
n := counter % len(w.frequencies)
|
|
||||||
|
|
||||||
conf := Dot11BeaconConfig{
|
|
||||||
SSID: fmt.Sprintf("Prova_%d", n),
|
|
||||||
BSSID: w.Session.Interface.HW,
|
|
||||||
Channel: network.Dot11Freq2Chan(w.frequencies[n]),
|
|
||||||
Encryption: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err, pkt := NewDot11Beacon(conf); err != nil {
|
|
||||||
log.Error("Could not create beacon packet: %s", err)
|
|
||||||
} else {
|
|
||||||
w.injectPacket(pkt)
|
|
||||||
}
|
|
||||||
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WiFiModule) startBeaconFlood() error {
|
|
||||||
// if not already running, temporarily enable the pcap handle
|
|
||||||
// for packet injection
|
|
||||||
if w.Running() == false {
|
|
||||||
if err := w.Configure(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer w.handle.Close()
|
|
||||||
for counter := 0; w.Running(); counter++ {
|
|
||||||
w.sendBeaconPacket(counter)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -27,6 +27,7 @@ func (w *WiFiModule) channelHopper() {
|
||||||
defer w.reads.Done()
|
defer w.reads.Done()
|
||||||
|
|
||||||
log.Info("Channel hopper started.")
|
log.Info("Channel hopper started.")
|
||||||
|
|
||||||
for w.Running() == true {
|
for w.Running() == true {
|
||||||
delay := w.hopPeriod
|
delay := w.hopPeriod
|
||||||
// if we have both 2.4 and 5ghz capabilities, we have
|
// if we have both 2.4 and 5ghz capabilities, we have
|
||||||
|
@ -45,6 +46,8 @@ func (w *WiFiModule) channelHopper() {
|
||||||
channel = w.stickChan
|
channel = w.stickChan
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debug("Hopping on channel %d", channel)
|
||||||
|
|
||||||
if err := network.SetInterfaceChannel(w.Session.Interface.Name(), channel); err != nil {
|
if err := network.SetInterfaceChannel(w.Session.Interface.Name(), channel); err != nil {
|
||||||
log.Warning("Error while hopping to channel %d: %s", channel, err)
|
log.Warning("Error while hopping to channel %d: %s", channel, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,16 @@
|
||||||
package modules
|
package modules
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"bytes"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/bettercap/bettercap/core"
|
|
||||||
"github.com/bettercap/bettercap/log"
|
"github.com/bettercap/bettercap/log"
|
||||||
"github.com/bettercap/bettercap/network"
|
"github.com/bettercap/bettercap/network"
|
||||||
"github.com/bettercap/bettercap/packets"
|
"github.com/bettercap/bettercap/packets"
|
||||||
"github.com/bettercap/bettercap/session"
|
|
||||||
|
|
||||||
"github.com/google/gopacket"
|
"github.com/google/gopacket"
|
||||||
"github.com/google/gopacket/layers"
|
"github.com/google/gopacket/layers"
|
||||||
"github.com/google/gopacket/pcap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var maxStationTTL = 5 * time.Minute
|
var maxStationTTL = 5 * time.Minute
|
||||||
|
@ -29,213 +23,33 @@ type WiFiProbe struct {
|
||||||
RSSI int8
|
RSSI int8
|
||||||
}
|
}
|
||||||
|
|
||||||
type WiFiModule struct {
|
func (w *WiFiModule) stationPruner() {
|
||||||
session.SessionModule
|
w.reads.Add(1)
|
||||||
|
defer w.reads.Done()
|
||||||
|
|
||||||
handle *pcap.Handle
|
log.Debug("WiFi stations pruner started.")
|
||||||
source string
|
for w.Running() == true {
|
||||||
channel int
|
for _, s := range w.Session.WiFi.List() {
|
||||||
hopPeriod time.Duration
|
sinceLastSeen := time.Since(s.LastSeen)
|
||||||
frequencies []int
|
if sinceLastSeen > maxStationTTL {
|
||||||
ap *network.AccessPoint
|
log.Debug("Station %s not seen in %s, removing.", s.BSSID(), sinceLastSeen)
|
||||||
stickChan int
|
w.Session.WiFi.Remove(s.BSSID())
|
||||||
skipBroken bool
|
|
||||||
pktSourceChan chan gopacket.Packet
|
|
||||||
pktSourceChanClosed bool
|
|
||||||
writes *sync.WaitGroup
|
|
||||||
reads *sync.WaitGroup
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewWiFiModule(s *session.Session) *WiFiModule {
|
|
||||||
w := &WiFiModule{
|
|
||||||
SessionModule: session.NewSessionModule("wifi.recon", s),
|
|
||||||
channel: 0,
|
|
||||||
stickChan: 0,
|
|
||||||
hopPeriod: 250 * time.Millisecond,
|
|
||||||
ap: nil,
|
|
||||||
skipBroken: true,
|
|
||||||
writes: &sync.WaitGroup{},
|
|
||||||
reads: &sync.WaitGroup{},
|
|
||||||
}
|
|
||||||
|
|
||||||
w.AddHandler(session.NewModuleHandler("wifi.recon on", "",
|
|
||||||
"Start 802.11 wireless base stations discovery.",
|
|
||||||
func(args []string) error {
|
|
||||||
return w.Start()
|
|
||||||
}))
|
|
||||||
|
|
||||||
w.AddHandler(session.NewModuleHandler("wifi.recon off", "",
|
|
||||||
"Stop 802.11 wireless base stations discovery.",
|
|
||||||
func(args []string) error {
|
|
||||||
return w.Stop()
|
|
||||||
}))
|
|
||||||
|
|
||||||
w.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 == true {
|
|
||||||
w.ap = ap
|
|
||||||
w.stickChan = network.Dot11Freq2Chan(ap.Frequency)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Could not find station with BSSID %s", args[0])
|
|
||||||
}))
|
|
||||||
|
|
||||||
w.AddHandler(session.NewModuleHandler("wifi.recon clear", "",
|
|
||||||
"Remove the 802.11 base station filter.",
|
|
||||||
func(args []string) error {
|
|
||||||
w.ap = nil
|
|
||||||
w.stickChan = 0
|
|
||||||
var err error
|
|
||||||
if w.frequencies, err = network.GetSupportedFrequencies(w.Session.Interface.Name()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}))
|
|
||||||
|
|
||||||
w.AddHandler(session.NewModuleHandler("wifi.deauth BSSID", `wifi\.deauth ((?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]{2}))`,
|
|
||||||
"Start a 802.11 deauth attack, if an access point BSSID is provided, every client will be deauthenticated, otherwise only the selected client.",
|
|
||||||
func(args []string) error {
|
|
||||||
bssid, err := net.ParseMAC(args[0])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return w.startDeauth(bssid)
|
|
||||||
}))
|
|
||||||
|
|
||||||
w.AddHandler(session.NewModuleHandler("wifi.beacon.flood", "",
|
|
||||||
"todo",
|
|
||||||
func(args []string) error {
|
|
||||||
return w.startBeaconFlood()
|
|
||||||
}))
|
|
||||||
|
|
||||||
w.AddHandler(session.NewModuleHandler("wifi.show", "",
|
|
||||||
"Show current wireless stations list (default sorting by essid).",
|
|
||||||
func(args []string) error {
|
|
||||||
return w.Show("rssi")
|
|
||||||
}))
|
|
||||||
|
|
||||||
w.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) error {
|
|
||||||
newfrequencies := w.frequencies[:0]
|
|
||||||
|
|
||||||
if len(args) > 0 && args[0] != "clear" {
|
|
||||||
channels := strings.Split(args[0], ",")
|
|
||||||
for _, c := range channels {
|
|
||||||
trimmed := strings.Trim(c, " ")
|
|
||||||
channel, err := strconv.Atoi(trimmed)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
newfrequencies = append(newfrequencies, network.Dot11Chan2Freq(channel))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// No channels setted, retrieve frequencies supported by the card
|
|
||||||
if frequencies, err := network.GetSupportedFrequencies(w.Session.Interface.Name()); err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
newfrequencies = frequencies
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
w.frequencies = newfrequencies
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}))
|
|
||||||
|
|
||||||
w.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",
|
|
||||||
"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",
|
|
||||||
"true",
|
|
||||||
"If true, dot11 packets with an invalid checksum will be skipped."))
|
|
||||||
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w WiFiModule) Name() string {
|
|
||||||
return "wifi.recon"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w WiFiModule) Description() string {
|
|
||||||
return "A module to monitor and perform wireless attacks on 802.11."
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w WiFiModule) Author() string {
|
|
||||||
return "Gianluca Braga <matrix86@protonmail.com> && Simone Margaritelli <evilsocket@protonmail.com>>"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WiFiModule) Configure() error {
|
|
||||||
var hopPeriod int
|
|
||||||
var err error
|
|
||||||
|
|
||||||
if err, w.source = w.StringParam("wifi.source.file"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if w.source != "" {
|
|
||||||
if w.handle, err = pcap.OpenOffline(w.source); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ihandle, err := pcap.NewInactiveHandle(w.Session.Interface.Name())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer ihandle.CleanUp()
|
|
||||||
|
|
||||||
if err = ihandle.SetRFMon(true); err != nil {
|
|
||||||
return fmt.Errorf("Error while setting interface %s in monitor mode: %s", core.Bold(w.Session.Interface.Name()), err)
|
|
||||||
} else if err = ihandle.SetSnapLen(65536); err != nil {
|
|
||||||
return err
|
|
||||||
} else if err = ihandle.SetTimeout(pcap.BlockForever); err != nil {
|
|
||||||
return err
|
|
||||||
} else if w.handle, err = ihandle.Activate(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err, w.skipBroken = w.BoolParam("wifi.skip-broken"); err != nil {
|
|
||||||
return err
|
|
||||||
} else if err, hopPeriod = w.IntParam("wifi.hop.period"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
w.hopPeriod = time.Duration(hopPeriod) * time.Millisecond
|
|
||||||
|
|
||||||
if w.source == "" {
|
|
||||||
// No channels setted, retrieve frequencies supported by the card
|
|
||||||
if len(w.frequencies) == 0 {
|
|
||||||
if w.frequencies, err = network.GetSupportedFrequencies(w.Session.Interface.Name()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// we need to start somewhere, this is just to check if
|
|
||||||
// this OS supports switching channel programmatically.
|
|
||||||
if err = network.SetInterfaceChannel(w.Session.Interface.Name(), 1); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Info("WiFi recon active with channel hopping.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
|
func (w *WiFiModule) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
|
||||||
// search for Dot11InformationElementIDSSID
|
// search for Dot11InformationElementIDSSID
|
||||||
if ok, ssid := packets.Dot11ParseIDSSID(packet); ok == true {
|
if ok, ssid := packets.Dot11ParseIDSSID(packet); ok == true {
|
||||||
from := dot11.Address3
|
from := dot11.Address3
|
||||||
|
|
||||||
|
// skip stuff we're sending
|
||||||
|
if w.apRunning && bytes.Compare(from, w.apConfig.BSSID) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if network.IsZeroMac(from) == false && network.IsBroadcastMac(from) == false {
|
if network.IsZeroMac(from) == false && network.IsBroadcastMac(from) == false {
|
||||||
var frequency int
|
var frequency int
|
||||||
bssid := from.String()
|
bssid := from.String()
|
||||||
|
@ -297,118 +111,3 @@ func (w *WiFiModule) discoverClients(radiotap *layers.RadioTap, dot11 *layers.Do
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *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 == true {
|
|
||||||
station.Received += bytes
|
|
||||||
}
|
|
||||||
|
|
||||||
src := dot11.Address2.String()
|
|
||||||
if station, found := w.Session.WiFi.Get(src); found == true {
|
|
||||||
station.Sent += bytes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ok, enc, cipher, auth := packets.Dot11ParseEncryption(packet, dot11); ok == true {
|
|
||||||
bssid := dot11.Address3.String()
|
|
||||||
if station, found := w.Session.WiFi.Get(bssid); found == true {
|
|
||||||
station.Encryption = enc
|
|
||||||
station.Cipher = cipher
|
|
||||||
station.Authentication = auth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WiFiModule) stationPruner() {
|
|
||||||
w.reads.Add(1)
|
|
||||||
defer w.reads.Done()
|
|
||||||
|
|
||||||
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(1 * time.Second)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WiFiModule) 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 *WiFiModule) Start() error {
|
|
||||||
if err := w.Configure(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
w.SetRunning(true, func() {
|
|
||||||
// start the pruner
|
|
||||||
go w.stationPruner()
|
|
||||||
|
|
||||||
w.reads.Add(1)
|
|
||||||
defer w.reads.Done()
|
|
||||||
|
|
||||||
src := gopacket.NewPacketSource(w.handle, w.handle.LinkType())
|
|
||||||
w.pktSourceChan = src.Packets()
|
|
||||||
for packet := range w.pktSourceChan {
|
|
||||||
if w.Running() == false {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if packet == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
w.trackPacket(packet)
|
|
||||||
|
|
||||||
// perform initial dot11 parsing and layers validation
|
|
||||||
if ok, radiotap, dot11 := packets.Dot11Parse(packet); ok == true {
|
|
||||||
// check FCS checksum
|
|
||||||
if w.skipBroken && dot11.ChecksumValid() == false {
|
|
||||||
log.Debug("Skipping dot11 packet with invalid checksum.")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
w.discoverProbes(radiotap, dot11, packet)
|
|
||||||
w.discoverAccessPoints(radiotap, dot11, packet)
|
|
||||||
w.discoverClients(radiotap, dot11, packet)
|
|
||||||
w.updateStats(dot11, packet)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.pktSourceChanClosed = true
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WiFiModule) Stop() error {
|
|
||||||
return w.SetRunning(false, func() {
|
|
||||||
// wait any pending write operation
|
|
||||||
w.writes.Wait()
|
|
||||||
// signal the main for loop we want to exit
|
|
||||||
if w.pktSourceChanClosed == false {
|
|
||||||
w.pktSourceChan <- nil
|
|
||||||
}
|
|
||||||
// close the pcap handle to make the main for exit
|
|
||||||
w.handle.Close()
|
|
||||||
// close the pcap handle to make the main for exit
|
|
||||||
// wait for the loop to exit.
|
|
||||||
w.reads.Wait()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,11 +4,82 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/bettercap/bettercap/network"
|
||||||
|
|
||||||
"github.com/google/gopacket"
|
"github.com/google/gopacket"
|
||||||
"github.com/google/gopacket/layers"
|
"github.com/google/gopacket/layers"
|
||||||
)
|
)
|
||||||
|
|
||||||
var wpaSignatureBytes = []byte{0, 0x50, 0xf2, 1}
|
var (
|
||||||
|
openFlags = 1057
|
||||||
|
wpaFlags = 1041
|
||||||
|
//1-54 Mbit
|
||||||
|
supportedRates = []byte{0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, 0x03, 0x01}
|
||||||
|
wpaRSN = []byte{
|
||||||
|
0x01, 0x00, // RSN Version 1
|
||||||
|
0x00, 0x0f, 0xac, 0x02, // Group Cipher Suite : 00-0f-ac TKIP
|
||||||
|
0x02, 0x00, // 2 Pairwise Cipher Suites (next two lines)
|
||||||
|
0x00, 0x0f, 0xac, 0x04, // AES Cipher / CCMP
|
||||||
|
0x00, 0x0f, 0xac, 0x02, // TKIP Cipher
|
||||||
|
0x01, 0x00, // 1 Authentication Key Managment Suite (line below)
|
||||||
|
0x00, 0x0f, 0xac, 0x02, // Pre-Shared Key
|
||||||
|
0x00, 0x00,
|
||||||
|
}
|
||||||
|
wpaSignatureBytes = []byte{0, 0x50, 0xf2, 1}
|
||||||
|
)
|
||||||
|
|
||||||
|
type Dot11ApConfig struct {
|
||||||
|
SSID string
|
||||||
|
BSSID net.HardwareAddr
|
||||||
|
Channel int
|
||||||
|
Encryption bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func Dot11Info(id layers.Dot11InformationElementID, info []byte) *layers.Dot11InformationElement {
|
||||||
|
return &layers.Dot11InformationElement{
|
||||||
|
ID: id,
|
||||||
|
Length: uint8(len(info) & 0xff),
|
||||||
|
Info: info,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDot11Beacon(conf Dot11ApConfig, seq uint16) (error, []byte) {
|
||||||
|
flags := openFlags
|
||||||
|
if conf.Encryption == true {
|
||||||
|
flags = wpaFlags
|
||||||
|
}
|
||||||
|
|
||||||
|
stack := []gopacket.SerializableLayer{
|
||||||
|
&layers.RadioTap{
|
||||||
|
DBMAntennaSignal: int8(-10),
|
||||||
|
ChannelFrequency: layers.RadioTapChannelFrequency(network.Dot11Chan2Freq(conf.Channel)),
|
||||||
|
},
|
||||||
|
&layers.Dot11{
|
||||||
|
Address1: network.BroadcastHw,
|
||||||
|
Address2: conf.BSSID,
|
||||||
|
Address3: conf.BSSID,
|
||||||
|
Type: layers.Dot11TypeMgmtBeacon,
|
||||||
|
SequenceNumber: seq,
|
||||||
|
},
|
||||||
|
&layers.Dot11MgmtBeacon{
|
||||||
|
Flags: uint16(flags),
|
||||||
|
Interval: 100,
|
||||||
|
},
|
||||||
|
Dot11Info(layers.Dot11InformationElementIDSSID, []byte(conf.SSID)),
|
||||||
|
Dot11Info(layers.Dot11InformationElementIDRates, supportedRates),
|
||||||
|
Dot11Info(layers.Dot11InformationElementIDDSSet, []byte{byte(conf.Channel & 0xff)}),
|
||||||
|
}
|
||||||
|
|
||||||
|
if conf.Encryption == true {
|
||||||
|
stack = append(stack, &layers.Dot11InformationElement{
|
||||||
|
ID: layers.Dot11InformationElementIDRSNInfo,
|
||||||
|
Length: uint8(len(wpaRSN) & 0xff),
|
||||||
|
Info: wpaRSN,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return Serialize(stack...)
|
||||||
|
}
|
||||||
|
|
||||||
func NewDot11Deauth(a1 net.HardwareAddr, a2 net.HardwareAddr, a3 net.HardwareAddr, seq uint16) (error, []byte) {
|
func NewDot11Deauth(a1 net.HardwareAddr, a2 net.HardwareAddr, a3 net.HardwareAddr, seq uint16) (error, []byte) {
|
||||||
return Serialize(
|
return Serialize(
|
||||||
|
|
|
@ -85,8 +85,6 @@ func (p *EventPool) Add(tag string, data interface{}) {
|
||||||
for _, l := range p.listeners {
|
for _, l := range p.listeners {
|
||||||
select {
|
select {
|
||||||
case l <- e:
|
case l <- e:
|
||||||
default:
|
|
||||||
fmt.Fprintf(os.Stderr, "Message not sent!\n")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue