mirror of
https://github.com/bettercap/bettercap.git
synced 2025-03-12 04:36:03 -07:00
120 lines
3.1 KiB
Go
120 lines
3.1 KiB
Go
package firewall
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/bettercap/bettercap/core"
|
|
"github.com/bettercap/bettercap/network"
|
|
)
|
|
|
|
type WindowsFirewall struct {
|
|
iface *network.Endpoint
|
|
forwarding bool
|
|
redirections map[string]*Redirection
|
|
}
|
|
|
|
func Make(iface *network.Endpoint) FirewallManager {
|
|
firewall := &WindowsFirewall{
|
|
iface: iface,
|
|
forwarding: false,
|
|
redirections: make(map[string]*Redirection, 0),
|
|
}
|
|
|
|
firewall.forwarding = firewall.IsForwardingEnabled()
|
|
|
|
return firewall
|
|
}
|
|
|
|
func (f WindowsFirewall) IsForwardingEnabled() bool {
|
|
if out, err := core.Exec("netsh", []string{"interface", "ipv4", "dump"}); err != nil {
|
|
fmt.Printf("%s\n", err)
|
|
return false
|
|
} else {
|
|
return strings.Contains(out, "forwarding=enabled")
|
|
}
|
|
}
|
|
|
|
func (f WindowsFirewall) EnableForwarding(enabled bool) error {
|
|
v := "enabled"
|
|
if enabled == false {
|
|
v = "disabled"
|
|
}
|
|
|
|
if _, err := core.Exec("netsh", []string{"interface", "ipv4", "set", "interface", fmt.Sprintf("%d", f.iface.Index), fmt.Sprintf("forwarding=\"%s\"", v)}); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (f WindowsFirewall) generateRule(r *Redirection, enabled bool) []string {
|
|
// https://stackoverflow.com/questions/24646165/netsh-port-forwarding-from-local-port-to-local-port-not-working
|
|
rule := []string{
|
|
fmt.Sprintf("listenport=%d", r.SrcPort),
|
|
}
|
|
|
|
if enabled {
|
|
rule = append(rule, fmt.Sprintf("connectport=%d", r.DstPort))
|
|
rule = append(rule, fmt.Sprintf("connectaddress=%s", r.DstAddress))
|
|
rule = append(rule, fmt.Sprintf("protocol=%s", r.Protocol))
|
|
}
|
|
|
|
return rule
|
|
}
|
|
|
|
func (f *WindowsFirewall) AllowPort(port int, address string, proto string, allow bool) error {
|
|
ruleName := fmt.Sprintf("bettercap-rule-%s-%s-%d", address, proto, port)
|
|
nameField := fmt.Sprintf(`name="%s"`, ruleName)
|
|
protoField := fmt.Sprintf("protocol=%s", proto)
|
|
// ipField := fmt.Sprintf("lolcalip=%s", address)
|
|
portField := fmt.Sprintf("localport=%d", port)
|
|
|
|
cmd := []string{}
|
|
|
|
if allow {
|
|
cmd = []string{"advfirewall", "firewall", "add", "rule", nameField, protoField, "dir=in", portField, "action=allow"}
|
|
} else {
|
|
cmd = []string{"advfirewall", "firewall", "delete", "rule", nameField, protoField, portField}
|
|
}
|
|
|
|
if _, err := core.Exec("netsh", cmd); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (f *WindowsFirewall) EnableRedirection(r *Redirection, enabled bool) error {
|
|
if err := f.AllowPort(r.SrcPort, r.DstAddress, r.Protocol, enabled); err != nil {
|
|
return err
|
|
} else if err := f.AllowPort(r.DstPort, r.DstAddress, r.Protocol, enabled); err != nil {
|
|
return err
|
|
}
|
|
|
|
rule := f.generateRule(r, enabled)
|
|
if enabled {
|
|
rule = append([]string{"interface", "portproxy", "add", "v4tov4"}, rule...)
|
|
} else {
|
|
rule = append([]string{"interface", "portproxy", "delete", "v4tov4"}, rule...)
|
|
}
|
|
|
|
if _, err := core.Exec("netsh", rule); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (f WindowsFirewall) Restore() {
|
|
for _, r := range f.redirections {
|
|
if err := f.EnableRedirection(r, false); err != nil {
|
|
fmt.Printf("%s", err)
|
|
}
|
|
}
|
|
|
|
if err := f.EnableForwarding(f.forwarding); err != nil {
|
|
fmt.Printf("%s", err)
|
|
}
|
|
}
|