mirror of
https://github.com/bettercap/bettercap
synced 2025-07-15 01:23:42 -07:00
new: implemented channel hopping for wifi.recon module ( ref #53 )
This commit is contained in:
parent
e1e2e33f57
commit
a66f5fabbb
4 changed files with 87 additions and 2 deletions
|
@ -11,6 +11,7 @@ import (
|
|||
|
||||
"github.com/evilsocket/bettercap-ng/core"
|
||||
"github.com/evilsocket/bettercap-ng/log"
|
||||
"github.com/evilsocket/bettercap-ng/network"
|
||||
"github.com/evilsocket/bettercap-ng/packets"
|
||||
"github.com/evilsocket/bettercap-ng/session"
|
||||
|
||||
|
@ -28,6 +29,7 @@ type WiFiRecon struct {
|
|||
wifi *WiFi
|
||||
stats *WiFiStats
|
||||
handle *pcap.Handle
|
||||
channel int
|
||||
client net.HardwareAddr
|
||||
accessPoint net.HardwareAddr
|
||||
}
|
||||
|
@ -36,6 +38,7 @@ func NewWiFiRecon(s *session.Session) *WiFiRecon {
|
|||
w := &WiFiRecon{
|
||||
SessionModule: session.NewSessionModule("wifi.recon", s),
|
||||
stats: NewWiFiStats(),
|
||||
channel: 0,
|
||||
client: make([]byte, 0),
|
||||
accessPoint: make([]byte, 0),
|
||||
}
|
||||
|
@ -97,9 +100,13 @@ func NewWiFiRecon(s *session.Session) *WiFiRecon {
|
|||
w.AddHandler(session.NewModuleHandler("wifi.show", "",
|
||||
"Show current wireless stations list (default sorting by essid).",
|
||||
func(args []string) error {
|
||||
return w.Show("essid")
|
||||
return w.Show("channel")
|
||||
}))
|
||||
|
||||
w.AddParam(session.NewIntParameter("wifi.recon.channel",
|
||||
"",
|
||||
"WiFi channel or empty for channel hopping."))
|
||||
|
||||
return w
|
||||
}
|
||||
|
||||
|
@ -177,6 +184,17 @@ func mhz2chan(freq int) int {
|
|||
return 0
|
||||
}
|
||||
|
||||
type ByChannelSorter []*WiFiStation
|
||||
|
||||
func (a ByChannelSorter) Len() int { return len(a) }
|
||||
func (a ByChannelSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a ByChannelSorter) Less(i, j int) bool {
|
||||
if a[i].Channel == a[j].Channel {
|
||||
return a[i].HwAddress < a[j].HwAddress
|
||||
}
|
||||
return a[i].Channel < a[j].Channel
|
||||
}
|
||||
|
||||
type ByEssidSorter []*WiFiStation
|
||||
|
||||
func (a ByEssidSorter) Len() int { return len(a) }
|
||||
|
@ -221,8 +239,10 @@ func (w *WiFiRecon) Show(by string) error {
|
|||
stations := w.wifi.List()
|
||||
if by == "seen" {
|
||||
sort.Sort(BywifiSeenSorter(stations))
|
||||
} else {
|
||||
} else if by == "essid" {
|
||||
sort.Sort(ByEssidSorter(stations))
|
||||
} else {
|
||||
sort.Sort(ByChannelSorter(stations))
|
||||
}
|
||||
|
||||
rows := make([][]string, 0)
|
||||
|
@ -259,6 +279,20 @@ func (w *WiFiRecon) Configure() error {
|
|||
return err
|
||||
} else if w.handle, err = ihandle.Activate(); err != nil {
|
||||
return err
|
||||
} else if err, w.channel = w.IntParam("wifi.recon.channel"); err == nil {
|
||||
if err = network.SetInterfaceChannel(w.Session.Interface.Name(), w.channel); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info("WiFi recon active on channel %d.", w.channel)
|
||||
} else {
|
||||
w.channel = 0
|
||||
// we need to start somewhere, this is just to check if
|
||||
// this OS support switching channel programmatically.
|
||||
if err = network.SetInterfaceChannel(w.Session.Interface.Name(), 1); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info("WiFi recon active with channel hopping.")
|
||||
|
||||
}
|
||||
|
||||
w.wifi = NewWiFi(w.Session, w.Session.Interface)
|
||||
|
@ -368,6 +402,25 @@ func (w *WiFiRecon) Start() error {
|
|||
}
|
||||
|
||||
w.SetRunning(true, func() {
|
||||
// start channel hopper if needed
|
||||
if w.channel == 0 {
|
||||
go func() {
|
||||
log.Info("Channel hopper started.")
|
||||
for w.Running() == true {
|
||||
for channel := 1; channel < 15; channel++ {
|
||||
if err := network.SetInterfaceChannel(w.Session.Interface.Name(), channel); err != nil {
|
||||
log.Warning("Error while hopping to channel %d: %s", channel, err)
|
||||
}
|
||||
// this is the default for airodump-ng, good for them, good for us.
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
if w.Running() == false {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
defer w.handle.Close()
|
||||
src := gopacket.NewPacketSource(w.handle, w.handle.LinkType())
|
||||
for packet := range src.Packets() {
|
||||
|
|
|
@ -3,8 +3,12 @@ package network
|
|||
import (
|
||||
"net"
|
||||
"regexp"
|
||||
|
||||
"github.com/evilsocket/bettercap-ng/core"
|
||||
)
|
||||
|
||||
const airPortPath = "/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport"
|
||||
|
||||
var IPv4RouteParser = regexp.MustCompile("^([a-z]+)+\\s+(\\d+\\.+\\d+.\\d.+\\d)+\\s+([a-zA-z]+)+\\s+(\\d+)+\\s+(\\d+)+\\s+([a-zA-Z]+\\d+)$")
|
||||
var IPv4RouteTokens = 7
|
||||
var IPv4RouteCmd = "netstat"
|
||||
|
@ -26,3 +30,13 @@ func IPv4RouteIsGateway(ifname string, tokens []string, f func(gateway string) (
|
|||
func getInterfaceName(iface net.Interface) string {
|
||||
return iface.Name
|
||||
}
|
||||
|
||||
func SetInterfaceChannel(iface string, channel int) error {
|
||||
out, err := core.Exec(airPortPath, []string{iface, "--channel", fmt.Sprintf("%d", channel)})
|
||||
if err != nil {
|
||||
return err
|
||||
} else if out != "" {
|
||||
return fmt.Errorf("Unexpected output while setting interface %s to channel %d: %s", iface, channel, out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"regexp"
|
||||
|
||||
"github.com/evilsocket/bettercap-ng/core"
|
||||
)
|
||||
|
||||
// only matches gateway lines
|
||||
|
@ -26,3 +29,13 @@ func IPv4RouteIsGateway(ifname string, tokens []string, f func(gateway string) (
|
|||
func getInterfaceName(iface net.Interface) string {
|
||||
return iface.Name
|
||||
}
|
||||
|
||||
func SetInterfaceChannel(iface string, channel int) error {
|
||||
out, err := core.Exec("iwconfig", []string{iface, "channel", fmt.Sprintf("%d", channel)})
|
||||
if err != nil {
|
||||
return err
|
||||
} else if out != "" {
|
||||
return fmt.Errorf("Unexpected output while setting interface %s to channel %d: %s", iface, channel, out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
@ -57,3 +58,7 @@ func getInterfaceName(iface net.Interface) string {
|
|||
|
||||
return iface.Name
|
||||
}
|
||||
|
||||
func SetInterfaceChannel(iface string, channel int) error {
|
||||
return fmt.Errorf("Windows does not support WiFi channel hopping.")
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue