firewall_windows.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package firewall
  2. import (
  3. "fmt"
  4. "strings"
  5. "github.com/bettercap/bettercap/core"
  6. "github.com/bettercap/bettercap/network"
  7. )
  8. type WindowsFirewall struct {
  9. iface *network.Endpoint
  10. forwarding bool
  11. redirections map[string]*Redirection
  12. }
  13. func Make(iface *network.Endpoint) FirewallManager {
  14. firewall := &WindowsFirewall{
  15. iface: iface,
  16. forwarding: false,
  17. redirections: make(map[string]*Redirection, 0),
  18. }
  19. firewall.forwarding = firewall.IsForwardingEnabled()
  20. return firewall
  21. }
  22. func (f WindowsFirewall) IsForwardingEnabled() bool {
  23. if out, err := core.Exec("netsh", []string{"interface", "ipv4", "dump"}); err != nil {
  24. fmt.Printf("%s\n", err)
  25. return false
  26. } else {
  27. return strings.Contains(out, "forwarding=enabled")
  28. }
  29. }
  30. func (f WindowsFirewall) EnableForwarding(enabled bool) error {
  31. v := "enabled"
  32. if enabled == false {
  33. v = "disabled"
  34. }
  35. if _, err := core.Exec("netsh", []string{"interface", "ipv4", "set", "interface", fmt.Sprintf("%d", f.iface.Index), fmt.Sprintf("forwarding=\"%s\"", v)}); err != nil {
  36. return err
  37. }
  38. return nil
  39. }
  40. func (f WindowsFirewall) generateRule(r *Redirection, enabled bool) []string {
  41. // https://stackoverflow.com/questions/24646165/netsh-port-forwarding-from-local-port-to-local-port-not-working
  42. rule := []string{
  43. fmt.Sprintf("listenport=%d", r.SrcPort),
  44. }
  45. if enabled {
  46. rule = append(rule, fmt.Sprintf("connectport=%d", r.DstPort))
  47. rule = append(rule, fmt.Sprintf("connectaddress=%s", r.DstAddress))
  48. rule = append(rule, fmt.Sprintf("protocol=%s", r.Protocol))
  49. }
  50. return rule
  51. }
  52. func (f *WindowsFirewall) AllowPort(port int, address string, proto string, allow bool) error {
  53. ruleName := fmt.Sprintf("bettercap-rule-%s-%s-%d", address, proto, port)
  54. nameField := fmt.Sprintf(`name="%s"`, ruleName)
  55. protoField := fmt.Sprintf("protocol=%s", proto)
  56. // ipField := fmt.Sprintf("lolcalip=%s", address)
  57. portField := fmt.Sprintf("localport=%d", port)
  58. cmd := []string{}
  59. if allow {
  60. cmd = []string{"advfirewall", "firewall", "add", "rule", nameField, protoField, "dir=in", portField, "action=allow"}
  61. } else {
  62. cmd = []string{"advfirewall", "firewall", "delete", "rule", nameField, protoField, portField}
  63. }
  64. if _, err := core.Exec("netsh", cmd); err != nil {
  65. return err
  66. }
  67. return nil
  68. }
  69. func (f *WindowsFirewall) EnableRedirection(r *Redirection, enabled bool) error {
  70. if err := f.AllowPort(r.SrcPort, r.DstAddress, r.Protocol, enabled); err != nil {
  71. return err
  72. } else if err := f.AllowPort(r.DstPort, r.DstAddress, r.Protocol, enabled); err != nil {
  73. return err
  74. }
  75. rule := f.generateRule(r, enabled)
  76. if enabled {
  77. rule = append([]string{"interface", "portproxy", "add", "v4tov4"}, rule...)
  78. } else {
  79. rule = append([]string{"interface", "portproxy", "delete", "v4tov4"}, rule...)
  80. }
  81. if _, err := core.Exec("netsh", rule); err != nil {
  82. return err
  83. }
  84. return nil
  85. }
  86. func (f WindowsFirewall) Restore() {
  87. for _, r := range f.redirections {
  88. if err := f.EnableRedirection(r, false); err != nil {
  89. fmt.Printf("%s", err)
  90. }
  91. }
  92. if err := f.EnableForwarding(f.forwarding); err != nil {
  93. fmt.Printf("%s", err)
  94. }
  95. }