mirror of
https://github.com/bettercap/bettercap
synced 2025-08-19 13:09:49 -07:00
new: aliases can now be used along with MACs and IP ranges for the arp.spoof.targets variable (ref #204)
This commit is contained in:
parent
c304ca4696
commit
54607993ba
4 changed files with 75 additions and 42 deletions
|
@ -1,10 +1,7 @@
|
||||||
package modules
|
package modules
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -12,13 +9,8 @@ import (
|
||||||
"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/bettercap/bettercap/session"
|
||||||
|
|
||||||
"github.com/malfunkt/iprange"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// lulz this sounds like a hamburger
|
|
||||||
var macParser = regexp.MustCompile(`([a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2})`)
|
|
||||||
|
|
||||||
type ArpSpoofer struct {
|
type ArpSpoofer struct {
|
||||||
session.SessionModule
|
session.SessionModule
|
||||||
addresses []net.IP
|
addresses []net.IP
|
||||||
|
@ -140,47 +132,17 @@ func (p *ArpSpoofer) unSpoof() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ArpSpoofer) parseTargets(targets string) (err error) {
|
|
||||||
// first isolate MACs and parse them
|
|
||||||
for _, mac := range macParser.FindAllString(targets, -1) {
|
|
||||||
mac = network.NormalizeMac(mac)
|
|
||||||
log.Debug("Parsing MAC %s", mac)
|
|
||||||
hw, err := net.ParseMAC(mac)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error while parsing MAC '%s': %s", mac, err)
|
|
||||||
}
|
|
||||||
p.macs = append(p.macs, hw)
|
|
||||||
targets = strings.Replace(targets, mac, "", -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
targets = strings.Trim(targets, ", ")
|
|
||||||
|
|
||||||
log.Debug("Parsing IP range %s", targets)
|
|
||||||
if len(p.macs) == 0 || targets != "" {
|
|
||||||
list, err := iprange.ParseList(targets)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error while parsing arp.spoof.targets variable '%s': %s.", targets, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
p.addresses = list.Expand()
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debug(" addresses=%v", p.addresses)
|
|
||||||
log.Debug(" macs=%v", p.macs)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ArpSpoofer) Configure() error {
|
func (p *ArpSpoofer) Configure() error {
|
||||||
var err error
|
var err error
|
||||||
var targets string
|
var targets string
|
||||||
|
|
||||||
if err, targets = p.StringParam("arp.spoof.targets"); err != nil {
|
if err, targets = p.StringParam("arp.spoof.targets"); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if err = p.parseTargets(targets); err != nil {
|
} else if p.addresses, p.macs, err = network.ParseTargets(targets, p.Session.Lan.Aliases()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debug(" addresses=%v macs=%v", p.addresses, p.macs)
|
||||||
if p.ban == true {
|
if p.ban == true {
|
||||||
log.Warning("Running in BAN mode, forwarding not enabled!")
|
log.Warning("Running in BAN mode, forwarding not enabled!")
|
||||||
p.Session.Firewall.EnableForwarding(false)
|
p.Session.Firewall.EnableForwarding(false)
|
||||||
|
|
|
@ -83,3 +83,16 @@ func (a *Aliases) Set(mac, alias string) error {
|
||||||
|
|
||||||
return a.saveUnlocked()
|
return a.saveUnlocked()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *Aliases) Find(alias string) (mac string, found bool) {
|
||||||
|
a.Lock()
|
||||||
|
defer a.Unlock()
|
||||||
|
|
||||||
|
for m, a := range a.data {
|
||||||
|
if alias == a {
|
||||||
|
return m, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
|
@ -94,6 +94,10 @@ func (lan *LAN) List() (list []*Endpoint) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (lan *LAN) Aliases() *Aliases {
|
||||||
|
return lan.aliases
|
||||||
|
}
|
||||||
|
|
||||||
func (lan *LAN) WasMissed(mac string) bool {
|
func (lan *LAN) WasMissed(mac string) bool {
|
||||||
if mac == lan.iface.HwAddress || mac == lan.gateway.HwAddress {
|
if mac == lan.iface.HwAddress || mac == lan.gateway.HwAddress {
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -8,6 +8,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/bettercap/bettercap/core"
|
"github.com/bettercap/bettercap/core"
|
||||||
|
|
||||||
|
"github.com/malfunkt/iprange"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrNoIfaces = errors.New("No active interfaces found.")
|
var ErrNoIfaces = errors.New("No active interfaces found.")
|
||||||
|
@ -23,7 +25,12 @@ const (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
BroadcastHw = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
|
BroadcastHw = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
|
||||||
IPv4Validator = regexp.MustCompile("^[0-9\\.]+/?\\d*$")
|
IPv4Validator = regexp.MustCompile(`^[0-9\.]+/?\d*$`)
|
||||||
|
IPv4RangeValidator = regexp.MustCompile(`^[0-9\.\-]+/?\d*$`)
|
||||||
|
MACValidator = regexp.MustCompile(`(?i)^[a-f0-9]{1,2}:[a-f0-9]{1,2}:[a-f0-9]{1,2}:[a-f0-9]{1,2}:[a-f0-9]{1,2}:[a-f0-9]{1,2}$`)
|
||||||
|
// lulz this sounds like a hamburger
|
||||||
|
macParser = regexp.MustCompile(`(?i)([a-f0-9]{1,2}:[a-f0-9]{1,2}:[a-f0-9]{1,2}:[a-f0-9]{1,2}:[a-f0-9]{1,2}:[a-f0-9]{1,2})`)
|
||||||
|
aliasParser = regexp.MustCompile(`(?i)([a-z_][a-z_0-9]+)`)
|
||||||
)
|
)
|
||||||
|
|
||||||
func IsZeroMac(mac net.HardwareAddr) bool {
|
func IsZeroMac(mac net.HardwareAddr) bool {
|
||||||
|
@ -60,6 +67,53 @@ func NormalizeMac(mac string) string {
|
||||||
return strings.ToLower(strings.Join(parts, ":"))
|
return strings.ToLower(strings.Join(parts, ":"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ParseTargets(targets string, aliasMap *Aliases) (ips []net.IP, macs []net.HardwareAddr, err error) {
|
||||||
|
ips = make([]net.IP, 0)
|
||||||
|
macs = make([]net.HardwareAddr, 0)
|
||||||
|
|
||||||
|
// first isolate MACs and parse them
|
||||||
|
for _, mac := range macParser.FindAllString(targets, -1) {
|
||||||
|
mac = NormalizeMac(mac)
|
||||||
|
hw, err := net.ParseMAC(mac)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("Error while parsing MAC '%s': %s", mac, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
macs = append(macs, hw)
|
||||||
|
targets = strings.Replace(targets, mac, "", -1)
|
||||||
|
}
|
||||||
|
targets = strings.Trim(targets, ", ")
|
||||||
|
|
||||||
|
// check and resolve aliases
|
||||||
|
for _, alias := range aliasParser.FindAllString(targets, -1) {
|
||||||
|
if mac, found := aliasMap.Find(alias); found == true {
|
||||||
|
mac = NormalizeMac(mac)
|
||||||
|
hw, err := net.ParseMAC(mac)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("Error while parsing MAC '%s': %s", mac, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
macs = append(macs, hw)
|
||||||
|
targets = strings.Replace(targets, alias, "", -1)
|
||||||
|
} else {
|
||||||
|
return nil, nil, fmt.Errorf("Could not resolve alias %s", alias)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
targets = strings.Trim(targets, ", ")
|
||||||
|
|
||||||
|
// parse what's left
|
||||||
|
if targets != "" {
|
||||||
|
list, err := iprange.ParseList(targets)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("Error while parsing address list '%s': %s.", targets, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ips = list.Expand()
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func buildEndpointFromInterface(iface net.Interface) (*Endpoint, error) {
|
func buildEndpointFromInterface(iface net.Interface) (*Endpoint, error) {
|
||||||
addrs, err := iface.Addrs()
|
addrs, err := iface.Addrs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue