diff --git a/modules/wifi/wifi.go b/modules/wifi/wifi.go index 6da12fcd2..f98a07b17 100644 --- a/modules/wifi/wifi.go +++ b/modules/wifi/wifi.go @@ -200,6 +200,21 @@ func NewWiFiModule(s *session.Session) *WiFiModule { mod.AddHandler(deauth) + probe := session.NewModuleHandler("wifi.probe BSSID ESSID", + `wifi\.probe\s+([a-fA-F0-9:]{11,})\s+([^\s].+)`, + "Sends a fake client probe with the given station BSSID, searching for ESSID.", + func(args []string) error { + bssid, err := net.ParseMAC(args[0]) + if err != nil { + return err + } + return mod.startProbing(bssid, args[1]) + }) + + probe.Complete("wifi.probe", s.WiFiCompleterFull) + + mod.AddHandler(probe) + mod.AddParam(session.NewStringParameter("wifi.deauth.skip", "", "", diff --git a/modules/wifi/wifi_deauth.go b/modules/wifi/wifi_deauth.go index 050bd63e2..2dd5bd0cc 100644 --- a/modules/wifi/wifi_deauth.go +++ b/modules/wifi/wifi_deauth.go @@ -159,4 +159,4 @@ func (mod *WiFiModule) startDeauth(to net.HardwareAddr) error { }() return nil -} +} \ No newline at end of file diff --git a/modules/wifi/wifi_recon.go b/modules/wifi/wifi_recon.go index 2c0949349..1c6ff0cb0 100644 --- a/modules/wifi/wifi_recon.go +++ b/modules/wifi/wifi_recon.go @@ -2,6 +2,7 @@ package wifi import ( "bytes" + "net" "time" "github.com/bettercap/bettercap/network" @@ -49,6 +50,30 @@ func (mod *WiFiModule) stationPruner() { } } +func (mod *WiFiModule) startProbing(staMac net.HardwareAddr, ssid string) error { + // if not already running, temporarily enable the pcap handle + // for packet injection + if !mod.Running() { + if err := mod.Configure(); err != nil { + return err + } + defer mod.handle.Close() + } + + for seq := uint16(0); seq < 5 && mod.Running(); seq++ { + if err, pkt := packets.NewDot11ProbeRequest(staMac, seq, ssid, network.GetInterfaceChannel(mod.iface.Name())); err != nil { + mod.Error("could not create probe packet: %s", err) + continue + } else { + mod.injectPacket(pkt) + } + } + + mod.Info("sent probe frames") + + return nil +} + func (mod *WiFiModule) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) { // search for Dot11InformationElementIDSSID if ok, ssid := packets.Dot11ParseIDSSID(packet); ok { diff --git a/packets/dot11.go b/packets/dot11.go index f0b98786f..c6e5c8362 100644 --- a/packets/dot11.go +++ b/packets/dot11.go @@ -89,6 +89,32 @@ func NewDot11Beacon(conf Dot11ApConfig, seq uint16) (error, []byte) { return Serialize(stack...) } +func NewDot11ProbeRequest(staMac net.HardwareAddr, seq uint16, ssid string, channel int) (error, []byte) { + stack := []gopacket.SerializableLayer{ + &layers.RadioTap{}, + &layers.Dot11{ + Address1: network.BroadcastHw, + Address2: staMac, + Address3: network.BroadcastHw, + Type: layers.Dot11TypeMgmtProbeReq, + SequenceNumber: seq, + }, + &layers.Dot11InformationElement{ + ID: layers.Dot11InformationElementIDSSID, + Length: uint8(len(ssid) & 0xff), + Info: []byte(ssid), + }, + Dot11Info(layers.Dot11InformationElementIDRates, []byte{0x82, 0x84, 0x8b, 0x96}), + Dot11Info(layers.Dot11InformationElementIDESRates, []byte{0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c}), + Dot11Info(layers.Dot11InformationElementIDDSSet, []byte{byte(channel & 0xff)}), + Dot11Info(layers.Dot11InformationElementIDHTCapabilities, []byte{0x2d, 0x40, 0x1b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), + Dot11Info(layers.Dot11InformationElementIDExtCapability, []byte{0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x40}), + Dot11Info(0xff /* HE Capabilities */, []byte{0x23, 0x01, 0x08, 0x08, 0x18, 0x00, 0x80, 0x20, 0x30, 0x02, 0x00, 0x0d, 0x00, 0x9f, 0x08, 0x00, 0x00, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0x39, 0x1c, 0xc7, 0x71, 0x1c, 0x07}), + } + + return Serialize(stack...) +} + func NewDot11Deauth(a1 net.HardwareAddr, a2 net.HardwareAddr, a3 net.HardwareAddr, seq uint16) (error, []byte) { return Serialize( &layers.RadioTap{},