diff --git a/modules/arp_spoof.go b/modules/arp_spoof.go index 39590f12..3216f050 100644 --- a/modules/arp_spoof.go +++ b/modules/arp_spoof.go @@ -1,8 +1,10 @@ package modules import ( + "bytes" "fmt" "net" + "runtime" "time" "github.com/evilsocket/bettercap-ng/log" @@ -10,6 +12,8 @@ import ( "github.com/evilsocket/bettercap-ng/packets" "github.com/evilsocket/bettercap-ng/session" + "github.com/google/gopacket" + "github.com/google/gopacket/layers" "github.com/malfunkt/iprange" ) @@ -135,6 +139,20 @@ func (p *ArpSpoofer) unSpoof() error { return nil } +func (p *ArpSpoofer) pktRouter(eth *layers.Ethernet, ip4 *layers.IPv4, pkt gopacket.Packet) { + if eth == nil || ip4 == nil { + return + } + + for _, target := range p.addresses { + if bytes.Compare(ip4.SrcIP, target) == 0 { + // TODO: get real mac && patch + } else if bytes.Compare(ip4.DstIP, target) == 0 { + // TODO: get real mac && patch + } + } +} + func (p *ArpSpoofer) Configure() error { var err error var targets string @@ -153,8 +171,14 @@ func (p *ArpSpoofer) Configure() error { log.Warning("Running in BAN mode, forwarding not enabled!") p.Session.Firewall.EnableForwarding(false) } else if p.Session.Firewall.IsForwardingEnabled() == false { - log.Info("Enabling forwarding.") - p.Session.Firewall.EnableForwarding(true) + if runtime.GOOS == "windows" { + log.Info("Using user space packet routing, disable forwarding.") + p.Session.Firewall.EnableForwarding(false) + p.Session.Queue.Route(p.pktRouter) + } else { + log.Info("Enabling forwarding.") + p.Session.Firewall.EnableForwarding(true) + } } return nil @@ -186,5 +210,6 @@ func (p *ArpSpoofer) Stop() error { <-p.done p.unSpoof() p.ban = false + p.Session.Queue.Route(nil) }) } diff --git a/packets/queue.go b/packets/queue.go index b6dd9c19..cb6d2d6e 100644 --- a/packets/queue.go +++ b/packets/queue.go @@ -32,6 +32,8 @@ type Stats struct { Errors uint64 } +type PacketHandler func(eth *layers.Ethernet, ip4 *layers.IPv4, pkt gopacket.Packet) + type Queue struct { sync.Mutex @@ -45,6 +47,7 @@ type Queue struct { handle *pcap.Handle source *gopacket.PacketSource active bool + router PacketHandler } func NewQueue(iface *bnet.Endpoint) (q *Queue, err error) { @@ -55,6 +58,7 @@ func NewQueue(iface *bnet.Endpoint) (q *Queue, err error) { iface: iface, active: true, + router: nil, } if q.handle, err = pcap.OpenLive(iface.Name(), 1024, true, pcap.BlockForever); err != nil { @@ -115,6 +119,13 @@ func (q *Queue) trackActivity(eth *layers.Ethernet, ip4 *layers.IPv4, address ne } } +func (q *Queue) Route(r PacketHandler) { + q.Lock() + defer q.Unlock() + + q.router = r +} + func (q *Queue) worker() { for pkt := range q.source.Packets() { if q.active == false { @@ -135,6 +146,10 @@ func (q *Queue) worker() { eth := leth.(*layers.Ethernet) ip4 := lip4.(*layers.IPv4) + if q.router != nil { + q.router(eth, ip4, pkt) + } + // coming from our network if bytes.Compare(q.iface.IP, ip4.SrcIP) != 0 && q.iface.Net.Contains(ip4.SrcIP) { q.trackActivity(eth, ip4, ip4.SrcIP, pktSize, true)