From b325d0e4c0426e07abf70fe2e4d4c2780c7b260f Mon Sep 17 00:00:00 2001 From: WangYi Date: Tue, 4 Aug 2020 16:59:05 +0800 Subject: [PATCH] Avoid mess other platform. --- core/core.go | 6 +---- core/core_windows.go | 4 +++ network/net.go | 2 +- network/net_gateway.go | 46 ++++++++++++++++++---------------- network/net_gateway_windows.go | 46 ++++++++++++++++++++++++++++++++++ network/net_windows.go | 10 +++----- 6 files changed, 79 insertions(+), 35 deletions(-) create mode 100644 network/net_gateway_windows.go diff --git a/core/core.go b/core/core.go index 43e066b7..a0726dc3 100644 --- a/core/core.go +++ b/core/core.go @@ -45,8 +45,4 @@ func Exec(executable string, args []string) (string, error) { } else { return str.Trim(string(raw)), nil } -} - -func ExecInEnglish(executable string, args []string) (string, error) { - return Exec("cmd", append([]string{"/C", "chcp 437", "&&", executable}, args...)) -} +} \ No newline at end of file diff --git a/core/core_windows.go b/core/core_windows.go index 4773e290..f586188c 100644 --- a/core/core_windows.go +++ b/core/core_windows.go @@ -3,3 +3,7 @@ package core func Shell(cmd string) (string, error) { return Exec("cmd.exe", []string{"/c", cmd}) } + +func ExecInEnglish(executable string, args []string) (string, error) { + return Exec("cmd", append([]string{"/C", "chcp 437", "&&", executable}, args...)) +} \ No newline at end of file diff --git a/network/net.go b/network/net.go index a576402a..ef964f33 100644 --- a/network/net.go +++ b/network/net.go @@ -303,7 +303,7 @@ func SetInterfaceTxPower(name string, txpower int) error { } func GatewayProvidedByUser(iface *Endpoint, gateway string) (*Endpoint, error) { - Debug("GatewayProvidedByUser(%s) [cmd=%v opts=%v]", gateway, IPv4RouteCmd, IPv4RouteCmdOpts) + Debug("GatewayProvidedByUser(%s) [cmd=%v opts=%v parser=%v]", gateway, IPv4RouteCmd, IPv4RouteCmdOpts, IPv4RouteParser) if IPv4Validator.MatchString(gateway) { Debug("valid gateway ip %s", gateway) // we have the address, now we need its mac diff --git a/network/net_gateway.go b/network/net_gateway.go index 89bb8526..543f81b5 100644 --- a/network/net_gateway.go +++ b/network/net_gateway.go @@ -1,19 +1,20 @@ // +build !android +// +build !windows package network import ( - "bufio" - "fmt" "strings" "github.com/bettercap/bettercap/core" + + "github.com/evilsocket/islazy/str" ) func FindGateway(iface *Endpoint) (*Endpoint, error) { - Debug("FindGateway(%s) [cmd=%v opts=%v]", iface.Name(), IPv4RouteCmd, IPv4RouteCmdOpts) + Debug("FindGateway(%s) [cmd=%v opts=%v parser=%v]", iface.Name(), IPv4RouteCmd, IPv4RouteCmdOpts, IPv4RouteParser) - output, err := core.ExecInEnglish(IPv4RouteCmd, append(IPv4RouteCmdOpts, fmt.Sprintf("%d", iface.Index))) + output, err := core.Exec(IPv4RouteCmd, IPv4RouteCmdOpts) if err != nil { Debug("FindGateway(%s): core.Exec failed with %s", err) return nil, err @@ -22,24 +23,25 @@ func FindGateway(iface *Endpoint) (*Endpoint, error) { Debug("FindGateway(%s) output:\n%s", iface.Name(), output) ifName := iface.Name() - scanner := bufio.NewScanner(strings.NewReader(output)) - for scanner.Scan() { - keyPair := strings.Split(scanner.Text(), ":") - if len(keyPair) != 2 { - continue - } - key, value := strings.TrimSpace(keyPair[0]), strings.TrimSpace(keyPair[1]) - if key == "Default Gateway" { - if value == iface.IpAddress { - return iface, nil - } else { - // we have the address, now we need its mac - mac, err := ArpLookup(ifName, value, false) - if err != nil { - return nil, err - } - Debug("gateway is %s[%s]", value, mac) - return NewEndpoint(value, mac), nil + for _, line := range strings.Split(output, "\n") { + if line = str.Trim(line); strings.Contains(line, ifName) { + m := IPv4RouteParser.FindStringSubmatch(line) + if len(m) >= IPv4RouteTokens { + Debug("FindGateway(%s) line '%s' matched with %v", iface.Name(), line, m) + return IPv4RouteIsGateway(ifName, m, func(gateway string) (*Endpoint, error) { + if gateway == iface.IpAddress { + Debug("gateway is the interface") + return iface, nil + } else { + // we have the address, now we need its mac + mac, err := ArpLookup(ifName, gateway, false) + if err != nil { + return nil, err + } + Debug("gateway is %s[%s]", gateway, mac) + return NewEndpoint(gateway, mac), nil + } + }) } } } diff --git a/network/net_gateway_windows.go b/network/net_gateway_windows.go new file mode 100644 index 00000000..5f0ecc85 --- /dev/null +++ b/network/net_gateway_windows.go @@ -0,0 +1,46 @@ +package network + +import ( + "bufio" + "fmt" + "github.com/bettercap/bettercap/core" + "strings" +) + +func FindGateway(iface *Endpoint) (*Endpoint, error) { + Debug("FindGateway(%s) [cmd=%v opts=%v parser=%v]", iface.Name(), IPv4RouteCmd, IPv4RouteCmdOpts, IPv4RouteParser) + + output, err := core.ExecInEnglish(IPv4RouteCmd, append(IPv4RouteCmdOpts, fmt.Sprintf("%d", iface.Index))) + if err != nil { + Debug("FindGateway(%s): core.Exec failed with %s", err) + return nil, err + } + + Debug("FindGateway(%s) output:\n%s", iface.Name(), output) + + ifName := iface.Name() + scanner := bufio.NewScanner(strings.NewReader(output)) + for scanner.Scan() { + keyPair := strings.Split(scanner.Text(), ":") + if len(keyPair) != 2 { + continue + } + key, value := strings.TrimSpace(keyPair[0]), strings.TrimSpace(keyPair[1]) + if key == "Default Gateway" { + if value == iface.IpAddress { + return iface, nil + } else { + // we have the address, now we need its mac + mac, err := ArpLookup(ifName, value, false) + if err != nil { + return nil, err + } + Debug("gateway is %s[%s]", value, mac) + return NewEndpoint(value, mac), nil + } + } + } + + Debug("FindGateway(%s): nothing found :/", iface.Name()) + return nil, ErrNoGateway +} diff --git a/network/net_windows.go b/network/net_windows.go index e0bda49d..3898aafe 100644 --- a/network/net_windows.go +++ b/network/net_windows.go @@ -3,22 +3,18 @@ package network import ( "fmt" "net" + "regexp" "strings" "github.com/google/gopacket/pcap" ) // only matches gateway lines +var IPv4RouteParser = regexp.MustCompile("^.+\\s+.+\\s+\\d+\\s+([0-9\\.]+/\\d+)\\s+\\d+\\s+([0-9\\.]+).*$") +var IPv4RouteTokens = 3 var IPv4RouteCmd = "netsh" var IPv4RouteCmdOpts = []string{"interface", "ipv4", "show", "address"} -func IPv4RouteIsGateway(ifname string, tokens []string, f func(gateway string) (*Endpoint, error)) (*Endpoint, error) { - // TODO check if the subnet is the same as iface ? - // subnet := tokens[1] - gateway := tokens[2] - return f(gateway) -} - /* * net.Interface does not have the correct name on Windows and pcap.Interface * does not have the hardware address for some reason ... so this is what I