fix: better ipv6 detection logic

This commit is contained in:
Simone Margaritelli 2024-09-22 15:03:06 +02:00
parent 8446d66d12
commit a234c20650
5 changed files with 30 additions and 12 deletions

View file

@ -6,6 +6,7 @@ import (
"sync" "sync"
"github.com/bettercap/bettercap/v2/core" "github.com/bettercap/bettercap/v2/core"
"github.com/bettercap/bettercap/v2/log"
) )
type ArpTable map[string]string type ArpTable map[string]string
@ -33,6 +34,7 @@ func ArpUpdate(iface string) (ArpTable, error) {
for _, line := range strings.Split(output, "\n") { for _, line := range strings.Split(output, "\n") {
m := ArpTableParser.FindStringSubmatch(line) m := ArpTableParser.FindStringSubmatch(line)
if len(m) == ArpTableTokens { if len(m) == ArpTableTokens {
log.Debug("ARP TABLE MATCH: %v", m)
ipIndex := ArpTableTokenIndex[0] ipIndex := ArpTableTokenIndex[0]
hwIndex := ArpTableTokenIndex[1] hwIndex := ArpTableTokenIndex[1]
ifIndex := ArpTableTokenIndex[2] ifIndex := ArpTableTokenIndex[2]
@ -46,6 +48,7 @@ func ArpUpdate(iface string) (ArpTable, error) {
} }
if ifname == iface { if ifname == iface {
log.Debug(" %s = %s", address, mac)
newTable[address] = mac newTable[address] = mac
} }
} }

View file

@ -6,6 +6,7 @@ import (
"strings" "strings"
"sync" "sync"
"github.com/bettercap/bettercap/v2/log"
"github.com/evilsocket/islazy/data" "github.com/evilsocket/islazy/data"
) )
@ -136,11 +137,11 @@ func (lan *LAN) Remove(ip, mac string) {
func (lan *LAN) shouldIgnore(ip, mac string) bool { func (lan *LAN) shouldIgnore(ip, mac string) bool {
// skip our own address // skip our own address
if ip == lan.iface.IpAddress || mac == lan.iface.HwAddress { if ip == lan.iface.IpAddress || ip == lan.iface.Ip6Address || mac == lan.iface.HwAddress {
return true return true
} }
// skip the gateway // skip the gateway
if ip == lan.gateway.IpAddress || mac == lan.gateway.HwAddress { if ip == lan.gateway.IpAddress || ip == lan.gateway.Ip6Address || mac == lan.gateway.HwAddress {
return true return true
} }
// skip broadcast addresses // skip broadcast addresses
@ -190,6 +191,15 @@ func (lan *LAN) AddIfNew(ip, mac string) *Endpoint {
if lan.ttl[mac] < LANDefaultttl { if lan.ttl[mac] < LANDefaultttl {
lan.ttl[mac]++ lan.ttl[mac]++
} }
if strings.ContainsRune(ip, ':') && t.Ip6Address == "" {
log.Info("ipv6 %s detected for %s (%s)", ip, t.IpAddress, mac)
t.SetIPv6(ip)
} else if strings.ContainsRune(ip, '.') && t.IpAddress == "" {
log.Info("ipv4 %s detected for %s (%s)", ip, t.Ip6Address, mac)
t.SetIP(ip)
}
return t return t
} }

View file

@ -17,11 +17,14 @@ type Endpoint struct {
Index int `json:"-"` Index int `json:"-"`
IP net.IP `json:"-"` IP net.IP `json:"-"`
Net *net.IPNet `json:"-"` Net *net.IPNet `json:"-"`
Net6 *net.IPNet `json:"-"`
IPv6 net.IP `json:"-"` IPv6 net.IP `json:"-"`
CIDR6 string `json:"-"`
HW net.HardwareAddr `json:"-"` HW net.HardwareAddr `json:"-"`
IpAddress string `json:"ipv4"` IpAddress string `json:"ipv4"`
Ip6Address string `json:"ipv6"` Ip6Address string `json:"ipv6"`
SubnetBits uint32 `json:"-"` SubnetBits uint32 `json:"-"`
SubnetBits6 uint32 `json:"-"`
IpAddressUint32 uint32 `json:"-"` IpAddressUint32 uint32 `json:"-"`
HwAddress string `json:"mac"` HwAddress string `json:"mac"`
Hostname string `json:"hostname"` Hostname string `json:"hostname"`
@ -100,7 +103,13 @@ func (t *Endpoint) SetNetwork(netw string) {
func (t *Endpoint) SetIPv6(netw string) { func (t *Endpoint) SetIPv6(netw string) {
parts := strings.SplitN(netw, "/", 2) parts := strings.SplitN(netw, "/", 2)
address := parts[0] address := parts[0]
// bits, _ := strconv.Atoi(parts[1]) if len(parts) > 1 {
bits6, _ := strconv.Atoi(parts[1])
t.SubnetBits6 = uint32(bits6)
t.CIDR6 = netw
_, netw, _ := net.ParseCIDR(netw)
t.Net6 = netw
}
t.IPv6 = net.ParseIP(address) t.IPv6 = net.ParseIP(address)
if t.IPv6 != nil { if t.IPv6 != nil {

View file

@ -196,16 +196,12 @@ func buildEndpointFromInterface(iface net.Interface) (*Endpoint, error) {
for _, a := range addrs { for _, a := range addrs {
address := a.String() address := a.String()
switch true { if IPv4Validator.MatchString(address) {
case IPv4Validator.MatchString(address):
e.SetIP(address) e.SetIP(address)
break } else if IPv4BlockValidator.MatchString(address) {
case IPv4BlockValidator.MatchString(address):
e.SetNetwork(address) e.SetNetwork(address)
break } else {
default:
e.SetIPv6(address) e.SetIPv6(address)
break
} }
} }

View file

@ -211,7 +211,7 @@ func (q *Queue) worker() {
// something coming from someone on the LAN // something coming from someone on the LAN
isFromMe := q.iface.IP.Equal(srcIP) || q.iface.IPv6.Equal(srcIP) isFromMe := q.iface.IP.Equal(srcIP) || q.iface.IPv6.Equal(srcIP)
isFromLAN := q.iface.Net.Contains(srcIP) isFromLAN := q.iface.Net.Contains(srcIP) || q.iface.Net6.Contains(srcIP)
if !isFromMe && isFromLAN { if !isFromMe && isFromLAN {
meta := q.getPacketMeta(pkt) meta := q.getPacketMeta(pkt)
q.trackActivity(eth, srcIP, meta, pktSize, true) q.trackActivity(eth, srcIP, meta, pktSize, true)
@ -219,7 +219,7 @@ func (q *Queue) worker() {
// something going to someone on the LAN // something going to someone on the LAN
isToMe := q.iface.IP.Equal(dstIP) || q.iface.IPv6.Equal(dstIP) isToMe := q.iface.IP.Equal(dstIP) || q.iface.IPv6.Equal(dstIP)
isToLAN := q.iface.Net.Contains(dstIP) isToLAN := q.iface.Net.Contains(dstIP) || q.iface.Net6.Contains(dstIP)
if !isToMe && isToLAN { if !isToMe && isToLAN {
q.trackActivity(eth, dstIP, nil, pktSize, false) q.trackActivity(eth, dstIP, nil, pktSize, false)
} }