From 4eead7eafaec57282ad435473e420d7bad7a602e Mon Sep 17 00:00:00 2001 From: evilsocket Date: Wed, 13 Feb 2019 10:12:34 +0100 Subject: [PATCH] misc: small fix or general refactoring i did not bother commenting --- modules/any_proxy/any_proxy.go | 78 +++---- modules/api_rest/api_rest.go | 146 ++++++------ modules/api_rest/api_rest_controller.go | 130 +++++------ modules/api_rest/api_rest_ws.go | 42 ++-- modules/arp_spoof/arp_spoof.go | 198 ++++++++-------- modules/ble/ble_recon.go | 134 +++++------ modules/ble/ble_recon_events.go | 48 ++-- modules/ble/ble_recon_view.go | 34 +-- modules/ble/ble_unsupported.go | 20 +- modules/caplets/caplets.go | 40 ++-- modules/dhcp6_spoof/dhcp6_spoof.go | 170 +++++++------- modules/dns_spoof/dns_spoof.go | 120 +++++----- modules/events_stream/events_stream.go | 148 ++++++------ modules/events_stream/events_view.go | 90 ++++---- modules/events_stream/events_view_ble.go | 6 +- .../events_view_ble_unsupported.go | 2 +- modules/events_stream/events_view_http.go | 66 +++--- modules/events_stream/events_view_wifi.go | 44 ++-- modules/gps/gps.go | 86 +++---- modules/http_proxy/http_proxy.go | 62 ++--- modules/http_server/http_server.go | 56 ++--- modules/https_proxy/https_proxy.go | 84 +++---- modules/https_server/https_server.go | 82 +++---- modules/mac_changer/mac_changer.go | 62 ++--- modules/modules.go | 8 +- modules/mysql_server/mysql_server.go | 101 ++++---- modules/net_probe/net_probe.go | 156 +++++++++++++ modules/net_probe/net_probe_mdns.go | 19 ++ .../{prober => net_probe}/net_probe_nbns.go | 12 +- .../{prober => net_probe}/net_probe_upnp.go | 12 +- .../{prober => net_probe}/net_probe_wsd.go | 12 +- modules/{discovery => net_recon}/net_recon.go | 64 +++--- modules/{discovery => net_recon}/net_show.go | 102 ++++----- .../{discovery => net_recon}/net_show_sort.go | 2 +- modules/net_sniff/net_sniff.go | 144 ++++++------ modules/net_sniff/net_sniff_context.go | 16 +- modules/net_sniff/net_sniff_fuzz.go | 52 ++--- modules/packet_proxy/packet_proxy_darwin.go | 12 +- modules/packet_proxy/packet_proxy_linux.go | 12 +- .../packet_proxy/packet_proxy_linux_amd64.go | 96 ++++---- modules/packet_proxy/packet_proxy_windows.go | 12 +- modules/prober/net_probe.go | 156 ------------- modules/prober/net_probe_mdns.go | 19 -- modules/syn_scan/syn_scan.go | 166 +++++++------- modules/syn_scan/syn_scan_reader.go | 20 +- modules/tcp_proxy/tcp_proxy.go | 138 +++++------ modules/ticker/ticker.go | 56 ++--- modules/update/update.go | 39 ++-- modules/{ => utils}/script_builtins.go | 2 +- modules/wifi/wifi.go | 216 +++++++++--------- modules/wifi/wifi_ap.go | 44 ++-- modules/wifi/wifi_assoc.go | 76 +++--- modules/wifi/wifi_deauth.go | 84 +++---- modules/wifi/wifi_events.go | 6 +- modules/wifi/wifi_hopping.go | 54 ++--- modules/wifi/wifi_recon.go | 68 +++--- modules/wifi/wifi_show.go | 130 +++++------ modules/wol/wol.go | 50 ++-- 58 files changed, 2052 insertions(+), 2052 deletions(-) create mode 100644 modules/net_probe/net_probe.go create mode 100644 modules/net_probe/net_probe_mdns.go rename modules/{prober => net_probe}/net_probe_nbns.go (57%) rename modules/{prober => net_probe}/net_probe_upnp.go (60%) rename modules/{prober => net_probe}/net_probe_wsd.go (60%) rename modules/{discovery => net_recon}/net_recon.go (53%) rename modules/{discovery => net_recon}/net_show.go (63%) rename modules/{discovery => net_recon}/net_show_sort.go (99%) delete mode 100644 modules/prober/net_probe.go delete mode 100644 modules/prober/net_probe_mdns.go rename modules/{ => utils}/script_builtins.go (99%) diff --git a/modules/any_proxy/any_proxy.go b/modules/any_proxy/any_proxy.go index f3bc7ca2..427c0499 100644 --- a/modules/any_proxy/any_proxy.go +++ b/modules/any_proxy/any_proxy.go @@ -11,66 +11,66 @@ type AnyProxy struct { } func NewAnyProxy(s *session.Session) *AnyProxy { - p := &AnyProxy{ + mod := &AnyProxy{ SessionModule: session.NewSessionModule("any.proxy", s), } - p.AddParam(session.NewStringParameter("any.proxy.iface", + mod.AddParam(session.NewStringParameter("any.proxy.iface", session.ParamIfaceName, "", "Interface to redirect packets from.")) - p.AddParam(session.NewStringParameter("any.proxy.protocol", + mod.AddParam(session.NewStringParameter("any.proxy.protocol", "TCP", "(TCP|UDP)", "Proxy protocol.")) - p.AddParam(session.NewIntParameter("any.proxy.src_port", + mod.AddParam(session.NewIntParameter("any.proxy.src_port", "80", "Remote port to redirect when the module is activated.")) - p.AddParam(session.NewStringParameter("any.proxy.src_address", + mod.AddParam(session.NewStringParameter("any.proxy.src_address", "", "", "Leave empty to intercept any source address.")) - p.AddParam(session.NewStringParameter("any.proxy.dst_address", + mod.AddParam(session.NewStringParameter("any.proxy.dst_address", session.ParamIfaceAddress, session.IPv4Validator, "Address where the proxy is listening.")) - p.AddParam(session.NewIntParameter("any.proxy.dst_port", + mod.AddParam(session.NewIntParameter("any.proxy.dst_port", "8080", "Port where the proxy is listening.")) - p.AddHandler(session.NewModuleHandler("any.proxy on", "", + mod.AddHandler(session.NewModuleHandler("any.proxy on", "", "Start the custom proxy redirection.", func(args []string) error { - return p.Start() + return mod.Start() })) - p.AddHandler(session.NewModuleHandler("any.proxy off", "", + mod.AddHandler(session.NewModuleHandler("any.proxy off", "", "Stop the custom proxy redirection.", func(args []string) error { - return p.Stop() + return mod.Stop() })) - return p + return mod } -func (p *AnyProxy) Name() string { +func (mod *AnyProxy) Name() string { return "any.proxy" } -func (p *AnyProxy) Description() string { +func (mod *AnyProxy) Description() string { return "A firewall redirection to any custom proxy." } -func (p *AnyProxy) Author() string { +func (mod *AnyProxy) Author() string { return "Simone Margaritelli " } -func (p *AnyProxy) Configure() error { +func (mod *AnyProxy) Configure() error { var err error var srcPort int var dstPort int @@ -79,62 +79,62 @@ func (p *AnyProxy) Configure() error { var srcAddress string var dstAddress string - if p.Running() { + if mod.Running() { return session.ErrAlreadyStarted - } else if err, iface = p.StringParam("any.proxy.iface"); err != nil { + } else if err, iface = mod.StringParam("any.proxy.iface"); err != nil { return err - } else if err, protocol = p.StringParam("any.proxy.protocol"); err != nil { + } else if err, protocol = mod.StringParam("any.proxy.protocol"); err != nil { return err - } else if err, srcPort = p.IntParam("any.proxy.src_port"); err != nil { + } else if err, srcPort = mod.IntParam("any.proxy.src_port"); err != nil { return err - } else if err, dstPort = p.IntParam("any.proxy.dst_port"); err != nil { + } else if err, dstPort = mod.IntParam("any.proxy.dst_port"); err != nil { return err - } else if err, srcAddress = p.StringParam("any.proxy.src_address"); err != nil { + } else if err, srcAddress = mod.StringParam("any.proxy.src_address"); err != nil { return err - } else if err, dstAddress = p.StringParam("any.proxy.dst_address"); err != nil { + } else if err, dstAddress = mod.StringParam("any.proxy.dst_address"); err != nil { return err } - if !p.Session.Firewall.IsForwardingEnabled() { - p.Info("Enabling forwarding.") - p.Session.Firewall.EnableForwarding(true) + if !mod.Session.Firewall.IsForwardingEnabled() { + mod.Info("Enabling forwarding.") + mod.Session.Firewall.EnableForwarding(true) } - p.Redirection = firewall.NewRedirection(iface, + mod.Redirection = firewall.NewRedirection(iface, protocol, srcPort, dstAddress, dstPort) if srcAddress != "" { - p.Redirection.SrcAddress = srcAddress + mod.Redirection.SrcAddress = srcAddress } - if err := p.Session.Firewall.EnableRedirection(p.Redirection, true); err != nil { + if err := mod.Session.Firewall.EnableRedirection(mod.Redirection, true); err != nil { return err } - p.Info("Applied redirection %s", p.Redirection.String()) + mod.Info("Applied redirection %s", mod.Redirection.String()) return nil } -func (p *AnyProxy) Start() error { - if err := p.Configure(); err != nil { +func (mod *AnyProxy) Start() error { + if err := mod.Configure(); err != nil { return err } - return p.SetRunning(true, func() {}) + return mod.SetRunning(true, func() {}) } -func (p *AnyProxy) Stop() error { - if p.Redirection != nil { - p.Info("Disabling redirection %s", p.Redirection.String()) - if err := p.Session.Firewall.EnableRedirection(p.Redirection, false); err != nil { +func (mod *AnyProxy) Stop() error { + if mod.Redirection != nil { + mod.Info("Disabling redirection %s", mod.Redirection.String()) + if err := mod.Session.Firewall.EnableRedirection(mod.Redirection, false); err != nil { return err } - p.Redirection = nil + mod.Redirection = nil } - return p.SetRunning(false, func() {}) + return mod.SetRunning(false, func() {}) } diff --git a/modules/api_rest/api_rest.go b/modules/api_rest/api_rest.go index 2325c777..48e04832 100644 --- a/modules/api_rest/api_rest.go +++ b/modules/api_rest/api_rest.go @@ -29,7 +29,7 @@ type RestAPI struct { } func NewRestAPI(s *session.Session) *RestAPI { - api := &RestAPI{ + mod := &RestAPI{ SessionModule: session.NewSessionModule("api.rest", s), server: &http.Server{}, quit: make(chan bool), @@ -41,59 +41,59 @@ func NewRestAPI(s *session.Session) *RestAPI { }, } - api.AddParam(session.NewStringParameter("api.rest.address", + mod.AddParam(session.NewStringParameter("api.rest.address", session.ParamIfaceAddress, session.IPv4Validator, "Address to bind the API REST server to.")) - api.AddParam(session.NewIntParameter("api.rest.port", + mod.AddParam(session.NewIntParameter("api.rest.port", "8081", "Port to bind the API REST server to.")) - api.AddParam(session.NewStringParameter("api.rest.alloworigin", - api.allowOrigin, + mod.AddParam(session.NewStringParameter("api.rest.alloworigin", + mod.allowOrigin, "", "Value of the Access-Control-Allow-Origin header of the API server.")) - api.AddParam(session.NewStringParameter("api.rest.username", + mod.AddParam(session.NewStringParameter("api.rest.username", "", "", "API authentication username.")) - api.AddParam(session.NewStringParameter("api.rest.password", + mod.AddParam(session.NewStringParameter("api.rest.password", "", "", "API authentication password.")) - api.AddParam(session.NewStringParameter("api.rest.certificate", + mod.AddParam(session.NewStringParameter("api.rest.certificate", "", "", "API TLS certificate.")) - tls.CertConfigToModule("api.rest", &api.SessionModule, tls.DefaultLegitConfig) + tls.CertConfigToModule("api.rest", &mod.SessionModule, tls.DefaultLegitConfig) - api.AddParam(session.NewStringParameter("api.rest.key", + mod.AddParam(session.NewStringParameter("api.rest.key", "", "", "API TLS key")) - api.AddParam(session.NewBoolParameter("api.rest.websocket", + mod.AddParam(session.NewBoolParameter("api.rest.websocket", "false", "If true the /api/events route will be available as a websocket endpoint instead of HTTPS.")) - api.AddHandler(session.NewModuleHandler("api.rest on", "", + mod.AddHandler(session.NewModuleHandler("api.rest on", "", "Start REST API server.", func(args []string) error { - return api.Start() + return mod.Start() })) - api.AddHandler(session.NewModuleHandler("api.rest off", "", + mod.AddHandler(session.NewModuleHandler("api.rest off", "", "Stop REST API server.", func(args []string) error { - return api.Stop() + return mod.Stop() })) - return api + return mod } type JSSessionRequest struct { @@ -104,113 +104,113 @@ type JSSessionResponse struct { Error string `json:"error"` } -func (api *RestAPI) Name() string { +func (mod *RestAPI) Name() string { return "api.rest" } -func (api *RestAPI) Description() string { +func (mod *RestAPI) Description() string { return "Expose a RESTful API." } -func (api *RestAPI) Author() string { +func (mod *RestAPI) Author() string { return "Simone Margaritelli " } -func (api *RestAPI) isTLS() bool { - return api.certFile != "" && api.keyFile != "" +func (mod *RestAPI) isTLS() bool { + return mod.certFile != "" && mod.keyFile != "" } -func (api *RestAPI) Configure() error { +func (mod *RestAPI) Configure() error { var err error var ip string var port int - if api.Running() { + if mod.Running() { return session.ErrAlreadyStarted - } else if err, ip = api.StringParam("api.rest.address"); err != nil { + } else if err, ip = mod.StringParam("api.rest.address"); err != nil { return err - } else if err, port = api.IntParam("api.rest.port"); err != nil { + } else if err, port = mod.IntParam("api.rest.port"); err != nil { return err - } else if err, api.allowOrigin = api.StringParam("api.rest.alloworigin"); err != nil { + } else if err, mod.allowOrigin = mod.StringParam("api.rest.alloworigin"); err != nil { return err - } else if err, api.certFile = api.StringParam("api.rest.certificate"); err != nil { + } else if err, mod.certFile = mod.StringParam("api.rest.certificate"); err != nil { return err - } else if api.certFile, err = fs.Expand(api.certFile); err != nil { + } else if mod.certFile, err = fs.Expand(mod.certFile); err != nil { return err - } else if err, api.keyFile = api.StringParam("api.rest.key"); err != nil { + } else if err, mod.keyFile = mod.StringParam("api.rest.key"); err != nil { return err - } else if api.keyFile, err = fs.Expand(api.keyFile); err != nil { + } else if mod.keyFile, err = fs.Expand(mod.keyFile); err != nil { return err - } else if err, api.username = api.StringParam("api.rest.username"); err != nil { + } else if err, mod.username = mod.StringParam("api.rest.username"); err != nil { return err - } else if err, api.password = api.StringParam("api.rest.password"); err != nil { + } else if err, mod.password = mod.StringParam("api.rest.password"); err != nil { return err - } else if err, api.useWebsocket = api.BoolParam("api.rest.websocket"); err != nil { + } else if err, mod.useWebsocket = mod.BoolParam("api.rest.websocket"); err != nil { return err } - if api.isTLS() { - if !fs.Exists(api.certFile) || !fs.Exists(api.keyFile) { - err, cfg := tls.CertConfigFromModule("api.rest", api.SessionModule) + if mod.isTLS() { + if !fs.Exists(mod.certFile) || !fs.Exists(mod.keyFile) { + err, cfg := tls.CertConfigFromModule("api.rest", mod.SessionModule) if err != nil { return err } - api.Debug("%+v", cfg) - api.Info("generating TLS key to %s", api.keyFile) - api.Info("generating TLS certificate to %s", api.certFile) - if err := tls.Generate(cfg, api.certFile, api.keyFile); err != nil { + mod.Debug("%+v", cfg) + mod.Info("generating TLS key to %s", mod.keyFile) + mod.Info("generating TLS certificate to %s", mod.certFile) + if err := tls.Generate(cfg, mod.certFile, mod.keyFile); err != nil { return err } } else { - api.Info("loading TLS key from %s", api.keyFile) - api.Info("loading TLS certificate from %s", api.certFile) + mod.Info("loading TLS key from %s", mod.keyFile) + mod.Info("loading TLS certificate from %s", mod.certFile) } } - api.server.Addr = fmt.Sprintf("%s:%d", ip, port) + mod.server.Addr = fmt.Sprintf("%s:%d", ip, port) router := mux.NewRouter() - router.HandleFunc("/api/events", api.eventsRoute) - router.HandleFunc("/api/session", api.sessionRoute) - router.HandleFunc("/api/session/ble", api.sessionRoute) - router.HandleFunc("/api/session/ble/{mac}", api.sessionRoute) - router.HandleFunc("/api/session/env", api.sessionRoute) - router.HandleFunc("/api/session/gateway", api.sessionRoute) - router.HandleFunc("/api/session/interface", api.sessionRoute) - router.HandleFunc("/api/session/modules", api.sessionRoute) - router.HandleFunc("/api/session/lan", api.sessionRoute) - router.HandleFunc("/api/session/lan/{mac}", api.sessionRoute) - router.HandleFunc("/api/session/options", api.sessionRoute) - router.HandleFunc("/api/session/packets", api.sessionRoute) - router.HandleFunc("/api/session/started-at", api.sessionRoute) - router.HandleFunc("/api/session/wifi", api.sessionRoute) - router.HandleFunc("/api/session/wifi/{mac}", api.sessionRoute) + router.HandleFunc("/api/events", mod.eventsRoute) + router.HandleFunc("/api/session", mod.sessionRoute) + router.HandleFunc("/api/session/ble", mod.sessionRoute) + router.HandleFunc("/api/session/ble/{mac}", mod.sessionRoute) + router.HandleFunc("/api/session/env", mod.sessionRoute) + router.HandleFunc("/api/session/gateway", mod.sessionRoute) + router.HandleFunc("/api/session/interface", mod.sessionRoute) + router.HandleFunc("/api/session/modules", mod.sessionRoute) + router.HandleFunc("/api/session/lan", mod.sessionRoute) + router.HandleFunc("/api/session/lan/{mac}", mod.sessionRoute) + router.HandleFunc("/api/session/options", mod.sessionRoute) + router.HandleFunc("/api/session/packets", mod.sessionRoute) + router.HandleFunc("/api/session/started-at", mod.sessionRoute) + router.HandleFunc("/api/session/wifi", mod.sessionRoute) + router.HandleFunc("/api/session/wifi/{mac}", mod.sessionRoute) - api.server.Handler = router + mod.server.Handler = router - if api.username == "" || api.password == "" { - api.Warning("api.rest.username and/or api.rest.password parameters are empty, authentication is disabled.") + if mod.username == "" || mod.password == "" { + mod.Warning("api.rest.username and/or api.rest.password parameters are empty, authentication is disabled.") } return nil } -func (api *RestAPI) Start() error { - if err := api.Configure(); err != nil { +func (mod *RestAPI) Start() error { + if err := mod.Configure(); err != nil { return err } - api.SetRunning(true, func() { + mod.SetRunning(true, func() { var err error - if api.isTLS() { - api.Info("api server starting on https://%s", api.server.Addr) - err = api.server.ListenAndServeTLS(api.certFile, api.keyFile) + if mod.isTLS() { + mod.Info("api server starting on https://%s", mod.server.Addr) + err = mod.server.ListenAndServeTLS(mod.certFile, mod.keyFile) } else { - api.Info("api server starting on http://%s", api.server.Addr) - err = api.server.ListenAndServe() + mod.Info("api server starting on http://%s", mod.server.Addr) + err = mod.server.ListenAndServe() } if err != nil && err != http.ErrServerClosed { @@ -221,14 +221,14 @@ func (api *RestAPI) Start() error { return nil } -func (api *RestAPI) Stop() error { - return api.SetRunning(false, func() { +func (mod *RestAPI) Stop() error { + return mod.SetRunning(false, func() { go func() { - api.quit <- true + mod.quit <- true }() ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() - api.server.Shutdown(ctx) + mod.server.Shutdown(ctx) }) } diff --git a/modules/api_rest/api_rest_controller.go b/modules/api_rest/api_rest_controller.go index 2148212c..72e94be3 100644 --- a/modules/api_rest/api_rest_controller.go +++ b/modules/api_rest/api_rest_controller.go @@ -21,116 +21,116 @@ type APIResponse struct { Message string `json:"msg"` } -func (api *RestAPI) setAuthFailed(w http.ResponseWriter, r *http.Request) { - api.Warning("Unauthorized authentication attempt from %s", r.RemoteAddr) +func (mod *RestAPI) setAuthFailed(w http.ResponseWriter, r *http.Request) { + mod.Warning("Unauthorized authentication attempt from %s", r.RemoteAddr) w.Header().Set("WWW-Authenticate", `Basic realm="auth"`) w.WriteHeader(401) w.Write([]byte("Unauthorized")) } -func (api *RestAPI) toJSON(w http.ResponseWriter, o interface{}) { +func (mod *RestAPI) toJSON(w http.ResponseWriter, o interface{}) { w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(o); err != nil { - api.Error("error while encoding object to JSON: %v", err) + mod.Error("error while encoding object to JSON: %v", err) } } -func (api *RestAPI) setSecurityHeaders(w http.ResponseWriter) { +func (mod *RestAPI) setSecurityHeaders(w http.ResponseWriter) { w.Header().Add("X-Frame-Options", "DENY") w.Header().Add("X-Content-Type-Options", "nosniff") w.Header().Add("X-XSS-Protection", "1; mode=block") w.Header().Add("Referrer-Policy", "same-origin") - w.Header().Set("Access-Control-Allow-Origin", api.allowOrigin) + w.Header().Set("Access-Control-Allow-Origin", mod.allowOrigin) } -func (api *RestAPI) checkAuth(r *http.Request) bool { - if api.username != "" && api.password != "" { +func (mod *RestAPI) checkAuth(r *http.Request) bool { + if mod.username != "" && mod.password != "" { user, pass, _ := r.BasicAuth() // timing attack my ass - if subtle.ConstantTimeCompare([]byte(user), []byte(api.username)) != 1 { + if subtle.ConstantTimeCompare([]byte(user), []byte(mod.username)) != 1 { return false - } else if subtle.ConstantTimeCompare([]byte(pass), []byte(api.password)) != 1 { + } else if subtle.ConstantTimeCompare([]byte(pass), []byte(mod.password)) != 1 { return false } } return true } -func (api *RestAPI) showSession(w http.ResponseWriter, r *http.Request) { - api.toJSON(w, session.I) +func (mod *RestAPI) showSession(w http.ResponseWriter, r *http.Request) { + mod.toJSON(w, session.I) } -func (api *RestAPI) showBle(w http.ResponseWriter, r *http.Request) { +func (mod *RestAPI) showBle(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) mac := strings.ToLower(params["mac"]) if mac == "" { - api.toJSON(w, session.I.BLE) + mod.toJSON(w, session.I.BLE) } else if dev, found := session.I.BLE.Get(mac); found { - api.toJSON(w, dev) + mod.toJSON(w, dev) } else { http.Error(w, "Not Found", 404) } } -func (api *RestAPI) showEnv(w http.ResponseWriter, r *http.Request) { - api.toJSON(w, session.I.Env) +func (mod *RestAPI) showEnv(w http.ResponseWriter, r *http.Request) { + mod.toJSON(w, session.I.Env) } -func (api *RestAPI) showGateway(w http.ResponseWriter, r *http.Request) { - api.toJSON(w, session.I.Gateway) +func (mod *RestAPI) showGateway(w http.ResponseWriter, r *http.Request) { + mod.toJSON(w, session.I.Gateway) } -func (api *RestAPI) showInterface(w http.ResponseWriter, r *http.Request) { - api.toJSON(w, session.I.Interface) +func (mod *RestAPI) showInterface(w http.ResponseWriter, r *http.Request) { + mod.toJSON(w, session.I.Interface) } -func (api *RestAPI) showModules(w http.ResponseWriter, r *http.Request) { - api.toJSON(w, session.I.Modules) +func (mod *RestAPI) showModules(w http.ResponseWriter, r *http.Request) { + mod.toJSON(w, session.I.Modules) } -func (api *RestAPI) showLan(w http.ResponseWriter, r *http.Request) { +func (mod *RestAPI) showLan(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) mac := strings.ToLower(params["mac"]) if mac == "" { - api.toJSON(w, session.I.Lan) + mod.toJSON(w, session.I.Lan) } else if host, found := session.I.Lan.Get(mac); found { - api.toJSON(w, host) + mod.toJSON(w, host) } else { http.Error(w, "Not Found", 404) } } -func (api *RestAPI) showOptions(w http.ResponseWriter, r *http.Request) { - api.toJSON(w, session.I.Options) +func (mod *RestAPI) showOptions(w http.ResponseWriter, r *http.Request) { + mod.toJSON(w, session.I.Options) } -func (api *RestAPI) showPackets(w http.ResponseWriter, r *http.Request) { - api.toJSON(w, session.I.Queue) +func (mod *RestAPI) showPackets(w http.ResponseWriter, r *http.Request) { + mod.toJSON(w, session.I.Queue) } -func (api *RestAPI) showStartedAt(w http.ResponseWriter, r *http.Request) { - api.toJSON(w, session.I.StartedAt) +func (mod *RestAPI) showStartedAt(w http.ResponseWriter, r *http.Request) { + mod.toJSON(w, session.I.StartedAt) } -func (api *RestAPI) showWiFi(w http.ResponseWriter, r *http.Request) { +func (mod *RestAPI) showWiFi(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) mac := strings.ToLower(params["mac"]) if mac == "" { - api.toJSON(w, session.I.WiFi) + mod.toJSON(w, session.I.WiFi) } else if station, found := session.I.WiFi.Get(mac); found { - api.toJSON(w, station) + mod.toJSON(w, station) } else if client, found := session.I.WiFi.GetClient(mac); found { - api.toJSON(w, client) + mod.toJSON(w, client) } else { http.Error(w, "Not Found", 404) } } -func (api *RestAPI) runSessionCommand(w http.ResponseWriter, r *http.Request) { +func (mod *RestAPI) runSessionCommand(w http.ResponseWriter, r *http.Request) { var err error var cmd CommandRequest @@ -141,15 +141,15 @@ func (api *RestAPI) runSessionCommand(w http.ResponseWriter, r *http.Request) { } else if err = session.I.Run(cmd.Command); err != nil { http.Error(w, err.Error(), 400) } else { - api.toJSON(w, APIResponse{Success: true}) + mod.toJSON(w, APIResponse{Success: true}) } } -func (api *RestAPI) showEvents(w http.ResponseWriter, r *http.Request) { +func (mod *RestAPI) showEvents(w http.ResponseWriter, r *http.Request) { var err error - if api.useWebsocket { - api.startStreamingEvents(w, r) + if mod.useWebsocket { + mod.startStreamingEvents(w, r) } else { events := session.I.Events.Sorted() nevents := len(events) @@ -169,22 +169,22 @@ func (api *RestAPI) showEvents(w http.ResponseWriter, r *http.Request) { } } - api.toJSON(w, events[nevents-n:]) + mod.toJSON(w, events[nevents-n:]) } } -func (api *RestAPI) clearEvents(w http.ResponseWriter, r *http.Request) { +func (mod *RestAPI) clearEvents(w http.ResponseWriter, r *http.Request) { session.I.Events.Clear() } -func (api *RestAPI) sessionRoute(w http.ResponseWriter, r *http.Request) { - api.setSecurityHeaders(w) +func (mod *RestAPI) sessionRoute(w http.ResponseWriter, r *http.Request) { + mod.setSecurityHeaders(w) - if !api.checkAuth(r) { - api.setAuthFailed(w, r) + if !mod.checkAuth(r) { + mod.setAuthFailed(w, r) return } else if r.Method == "POST" { - api.runSessionCommand(w, r) + mod.runSessionCommand(w, r) return } else if r.Method != "GET" { http.Error(w, "Bad Request", 400) @@ -197,55 +197,55 @@ func (api *RestAPI) sessionRoute(w http.ResponseWriter, r *http.Request) { path := r.URL.String() switch { case path == "/api/session": - api.showSession(w, r) + mod.showSession(w, r) case path == "/api/session/env": - api.showEnv(w, r) + mod.showEnv(w, r) case path == "/api/session/gateway": - api.showGateway(w, r) + mod.showGateway(w, r) case path == "/api/session/interface": - api.showInterface(w, r) + mod.showInterface(w, r) case strings.HasPrefix(path, "/api/session/modules"): - api.showModules(w, r) + mod.showModules(w, r) case strings.HasPrefix(path, "/api/session/lan"): - api.showLan(w, r) + mod.showLan(w, r) case path == "/api/session/options": - api.showOptions(w, r) + mod.showOptions(w, r) case path == "/api/session/packets": - api.showPackets(w, r) + mod.showPackets(w, r) case path == "/api/session/started-at": - api.showStartedAt(w, r) + mod.showStartedAt(w, r) case strings.HasPrefix(path, "/api/session/ble"): - api.showBle(w, r) + mod.showBle(w, r) case strings.HasPrefix(path, "/api/session/wifi"): - api.showWiFi(w, r) + mod.showWiFi(w, r) default: http.Error(w, "Not Found", 404) } } -func (api *RestAPI) eventsRoute(w http.ResponseWriter, r *http.Request) { - api.setSecurityHeaders(w) +func (mod *RestAPI) eventsRoute(w http.ResponseWriter, r *http.Request) { + mod.setSecurityHeaders(w) - if !api.checkAuth(r) { - api.setAuthFailed(w, r) + if !mod.checkAuth(r) { + mod.setAuthFailed(w, r) return } if r.Method == "GET" { - api.showEvents(w, r) + mod.showEvents(w, r) } else if r.Method == "DELETE" { - api.clearEvents(w, r) + mod.clearEvents(w, r) } else { http.Error(w, "Bad Request", 400) } diff --git a/modules/api_rest/api_rest_ws.go b/modules/api_rest/api_rest_ws.go index 2dfa971c..4d51afae 100644 --- a/modules/api_rest/api_rest_ws.go +++ b/modules/api_rest/api_rest_ws.go @@ -20,17 +20,17 @@ const ( pingPeriod = (pongWait * 9) / 10 ) -func (api *RestAPI) streamEvent(ws *websocket.Conn, event session.Event) error { +func (mod *RestAPI) streamEvent(ws *websocket.Conn, event session.Event) error { msg, err := json.Marshal(event) if err != nil { - api.Error("Error while creating websocket message: %s", err) + mod.Error("Error while creating websocket message: %s", err) return err } ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.TextMessage, msg); err != nil { if !strings.Contains(err.Error(), "closed connection") { - api.Error("Error while writing websocket message: %s", err) + mod.Error("Error while writing websocket message: %s", err) return err } } @@ -38,25 +38,25 @@ func (api *RestAPI) streamEvent(ws *websocket.Conn, event session.Event) error { return nil } -func (api *RestAPI) sendPing(ws *websocket.Conn) error { +func (mod *RestAPI) sendPing(ws *websocket.Conn) error { ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil { - api.Error("Error while writing websocket ping message: %s", err) + mod.Error("Error while writing websocket ping message: %s", err) return err } return nil } -func (api *RestAPI) streamWriter(ws *websocket.Conn, w http.ResponseWriter, r *http.Request) { +func (mod *RestAPI) streamWriter(ws *websocket.Conn, w http.ResponseWriter, r *http.Request) { defer ws.Close() // first we stream what we already have events := session.I.Events.Sorted() n := len(events) if n > 0 { - api.Debug("Sending %d events.", n) + mod.Debug("Sending %d events.", n) for _, event := range events { - if err := api.streamEvent(ws, event); err != nil { + if err := mod.streamEvent(ws, event); err != nil { return } } @@ -64,7 +64,7 @@ func (api *RestAPI) streamWriter(ws *websocket.Conn, w http.ResponseWriter, r *h session.I.Events.Clear() - api.Debug("Listening for events and streaming to ws endpoint ...") + mod.Debug("Listening for events and streaming to ws endpoint ...") pingTicker := time.NewTicker(pingPeriod) listener := session.I.Events.Listen() @@ -73,21 +73,21 @@ func (api *RestAPI) streamWriter(ws *websocket.Conn, w http.ResponseWriter, r *h for { select { case <-pingTicker.C: - if err := api.sendPing(ws); err != nil { + if err := mod.sendPing(ws); err != nil { return } case event := <-listener: - if err := api.streamEvent(ws, event); err != nil { + if err := mod.streamEvent(ws, event); err != nil { return } - case <-api.quit: - api.Info("Stopping websocket events streamer ...") + case <-mod.quit: + mod.Info("Stopping websocket events streamer ...") return } } } -func (api *RestAPI) streamReader(ws *websocket.Conn) { +func (mod *RestAPI) streamReader(ws *websocket.Conn) { defer ws.Close() ws.SetReadLimit(512) ws.SetReadDeadline(time.Now().Add(pongWait)) @@ -95,23 +95,23 @@ func (api *RestAPI) streamReader(ws *websocket.Conn) { for { _, _, err := ws.ReadMessage() if err != nil { - api.Debug("Closing websocket reader.") + mod.Debug("Closing websocket reader.") break } } } -func (api *RestAPI) startStreamingEvents(w http.ResponseWriter, r *http.Request) { - ws, err := api.upgrader.Upgrade(w, r, nil) +func (mod *RestAPI) startStreamingEvents(w http.ResponseWriter, r *http.Request) { + ws, err := mod.upgrader.Upgrade(w, r, nil) if err != nil { if _, ok := err.(websocket.HandshakeError); !ok { - api.Error("Error while updating api.rest connection to websocket: %s", err) + mod.Error("Error while updating api.rest connection to websocket: %s", err) } return } - api.Debug("Websocket streaming started for %s", r.RemoteAddr) + mod.Debug("Websocket streaming started for %s", r.RemoteAddr) - go api.streamWriter(ws, w, r) - api.streamReader(ws) + go mod.streamWriter(ws, w, r) + mod.streamReader(ws) } diff --git a/modules/arp_spoof/arp_spoof.go b/modules/arp_spoof/arp_spoof.go index d851b4ef..100e0f44 100644 --- a/modules/arp_spoof/arp_spoof.go +++ b/modules/arp_spoof/arp_spoof.go @@ -26,7 +26,7 @@ type ArpSpoofer struct { } func NewArpSpoofer(s *session.Session) *ArpSpoofer { - p := &ArpSpoofer{ + mod := &ArpSpoofer{ SessionModule: session.NewSessionModule("arp.spoof", s), addresses: make([]net.IP, 0), macs: make([]net.HardwareAddr, 0), @@ -38,123 +38,123 @@ func NewArpSpoofer(s *session.Session) *ArpSpoofer { waitGroup: &sync.WaitGroup{}, } - p.AddParam(session.NewStringParameter("arp.spoof.targets", session.ParamSubnet, "", "Comma separated list of IP addresses, MAC addresses or aliases to spoof, also supports nmap style IP ranges.")) + mod.AddParam(session.NewStringParameter("arp.spoof.targets", session.ParamSubnet, "", "Comma separated list of IP addresses, MAC addresses or aliases to spoof, also supports nmap style IP ranges.")) - p.AddParam(session.NewStringParameter("arp.spoof.whitelist", "", "", "Comma separated list of IP addresses, MAC addresses or aliases to skip while spoofing.")) + mod.AddParam(session.NewStringParameter("arp.spoof.whitelist", "", "", "Comma separated list of IP addresses, MAC addresses or aliases to skip while spoofing.")) - p.AddParam(session.NewBoolParameter("arp.spoof.internal", + mod.AddParam(session.NewBoolParameter("arp.spoof.internal", "false", "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", + mod.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", "", + mod.AddHandler(session.NewModuleHandler("arp.spoof on", "", "Start ARP spoofer.", func(args []string) error { - return p.Start() + return mod.Start() })) - p.AddHandler(session.NewModuleHandler("arp.ban on", "", + mod.AddHandler(session.NewModuleHandler("arp.ban on", "", "Start ARP spoofer in ban mode, meaning the target(s) connectivity will not work.", func(args []string) error { - p.ban = true - return p.Start() + mod.ban = true + return mod.Start() })) - p.AddHandler(session.NewModuleHandler("arp.spoof off", "", + mod.AddHandler(session.NewModuleHandler("arp.spoof off", "", "Stop ARP spoofer.", func(args []string) error { - return p.Stop() + return mod.Stop() })) - p.AddHandler(session.NewModuleHandler("arp.ban off", "", + mod.AddHandler(session.NewModuleHandler("arp.ban off", "", "Stop ARP spoofer.", func(args []string) error { - return p.Stop() + return mod.Stop() })) - return p + return mod } -func (p ArpSpoofer) Name() string { +func (mod ArpSpoofer) Name() string { return "arp.spoof" } -func (p ArpSpoofer) Description() string { +func (mod ArpSpoofer) Description() string { return "Keep spoofing selected hosts on the network." } -func (p ArpSpoofer) Author() string { +func (mod ArpSpoofer) Author() string { return "Simone Margaritelli " } -func (p *ArpSpoofer) Configure() error { +func (mod *ArpSpoofer) Configure() error { var err error var targets string var whitelist string - if err, p.fullDuplex = p.BoolParam("arp.spoof.fullduplex"); err != nil { + if err, mod.fullDuplex = mod.BoolParam("arp.spoof.fullduplex"); err != nil { return err - } else if err, p.internal = p.BoolParam("arp.spoof.internal"); err != nil { + } else if err, mod.internal = mod.BoolParam("arp.spoof.internal"); err != nil { return err - } else if err, targets = p.StringParam("arp.spoof.targets"); err != nil { + } else if err, targets = mod.StringParam("arp.spoof.targets"); err != nil { return err - } else if err, whitelist = p.StringParam("arp.spoof.whitelist"); err != nil { + } else if err, whitelist = mod.StringParam("arp.spoof.whitelist"); err != nil { return err - } else if p.addresses, p.macs, err = network.ParseTargets(targets, p.Session.Lan.Aliases()); err != nil { + } else if mod.addresses, mod.macs, err = network.ParseTargets(targets, mod.Session.Lan.Aliases()); err != nil { return err - } else if p.wAddresses, p.wMacs, err = network.ParseTargets(whitelist, p.Session.Lan.Aliases()); err != nil { + } else if mod.wAddresses, mod.wMacs, err = network.ParseTargets(whitelist, mod.Session.Lan.Aliases()); err != nil { return err } - p.Debug(" addresses=%v macs=%v whitelisted-addresses=%v whitelisted-macs=%v", p.addresses, p.macs, p.wAddresses, p.wMacs) + mod.Debug(" addresses=%v macs=%v whitelisted-addresses=%v whitelisted-macs=%v", mod.addresses, mod.macs, mod.wAddresses, mod.wMacs) - if p.ban { - p.Warning("running in ban mode, forwarding not enabled!") - p.Session.Firewall.EnableForwarding(false) - } else if !p.Session.Firewall.IsForwardingEnabled() { - p.Info("enabling forwarding") - p.Session.Firewall.EnableForwarding(true) + if mod.ban { + mod.Warning("running in ban mode, forwarding not enabled!") + mod.Session.Firewall.EnableForwarding(false) + } else if !mod.Session.Firewall.IsForwardingEnabled() { + mod.Info("enabling forwarding") + mod.Session.Firewall.EnableForwarding(true) } return nil } -func (p *ArpSpoofer) Start() error { - if err := p.Configure(); err != nil { +func (mod *ArpSpoofer) Start() error { + if err := mod.Configure(); err != nil { return err } - return p.SetRunning(true, func() { + return mod.SetRunning(true, func() { neighbours := []net.IP{} - nTargets := len(p.addresses) + len(p.macs) + nTargets := len(mod.addresses) + len(mod.macs) - if p.internal { - list, _ := iprange.ParseList(p.Session.Interface.CIDR()) + if mod.internal { + list, _ := iprange.ParseList(mod.Session.Interface.CIDR()) neighbours = list.Expand() nNeigh := len(neighbours) - 2 - p.Warning("arp spoofer started targeting %d possible network neighbours of %d targets.", nNeigh, nTargets) + mod.Warning("arp spoofer started targeting %d possible network neighbours of %d targets.", nNeigh, nTargets) } else { - p.Info("arp spoofer started, probing %d targets.", nTargets) + mod.Info("arp spoofer started, probing %d targets.", nTargets) } - if p.fullDuplex { - p.Warning("full duplex spoofing enabled, if the router has ARP spoofing mechanisms, the attack will fail.") + if mod.fullDuplex { + mod.Warning("full duplex spoofing enabled, if the router has ARP spoofing mechanisms, the attack will fail.") } - p.waitGroup.Add(1) - defer p.waitGroup.Done() + mod.waitGroup.Add(1) + defer mod.waitGroup.Done() - gwIP := p.Session.Gateway.IP - myMAC := p.Session.Interface.HW - for p.Running() { - p.arpSpoofTargets(gwIP, myMAC, true, false) + gwIP := mod.Session.Gateway.IP + myMAC := mod.Session.Interface.HW + for mod.Running() { + mod.arpSpoofTargets(gwIP, myMAC, true, false) for _, address := range neighbours { - if !p.Session.Skip(address) { - p.arpSpoofTargets(address, myMAC, true, false) + if !mod.Session.Skip(address) { + mod.arpSpoofTargets(address, myMAC, true, false) } } @@ -163,18 +163,18 @@ func (p *ArpSpoofer) Start() error { }) } -func (p *ArpSpoofer) unSpoof() error { - nTargets := len(p.addresses) + len(p.macs) - p.Info("restoring ARP cache of %d targets.", nTargets) - p.arpSpoofTargets(p.Session.Gateway.IP, p.Session.Gateway.HW, false, false) +func (mod *ArpSpoofer) unSpoof() error { + nTargets := len(mod.addresses) + len(mod.macs) + mod.Info("restoring ARP cache of %d targets.", nTargets) + mod.arpSpoofTargets(mod.Session.Gateway.IP, mod.Session.Gateway.HW, false, false) - if p.internal { - list, _ := iprange.ParseList(p.Session.Interface.CIDR()) + if mod.internal { + list, _ := iprange.ParseList(mod.Session.Interface.CIDR()) neighbours := list.Expand() for _, address := range neighbours { - if !p.Session.Skip(address) { - if realMAC, err := p.Session.FindMAC(address, false); err == nil { - p.arpSpoofTargets(address, realMAC, false, false) + if !mod.Session.Skip(address) { + if realMAC, err := mod.Session.FindMAC(address, false); err == nil { + mod.arpSpoofTargets(address, realMAC, false, false) } } } @@ -183,23 +183,23 @@ func (p *ArpSpoofer) unSpoof() error { return nil } -func (p *ArpSpoofer) Stop() error { - return p.SetRunning(false, func() { - p.Info("waiting for ARP spoofer to stop ...") - p.unSpoof() - p.ban = false - p.waitGroup.Wait() +func (mod *ArpSpoofer) Stop() error { + return mod.SetRunning(false, func() { + mod.Info("waiting for ARP spoofer to stop ...") + mod.unSpoof() + mod.ban = false + mod.waitGroup.Wait() }) } -func (p *ArpSpoofer) isWhitelisted(ip string, mac net.HardwareAddr) bool { - for _, addr := range p.wAddresses { +func (mod *ArpSpoofer) isWhitelisted(ip string, mac net.HardwareAddr) bool { + for _, addr := range mod.wAddresses { if ip == addr.String() { return true } } - for _, hw := range p.wMacs { + for _, hw := range mod.wMacs { if bytes.Equal(hw, mac) { return true } @@ -208,28 +208,28 @@ func (p *ArpSpoofer) isWhitelisted(ip string, mac net.HardwareAddr) bool { return false } -func (p *ArpSpoofer) getTargets(probe bool) map[string]net.HardwareAddr { +func (mod *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) { - p.Debug("skipping IP %s from arp spoofing.", ip) + for _, ip := range mod.addresses { + if mod.Session.Skip(ip) { + mod.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 { - p.Debug("could not find hardware address for %s", ip.String()) + if hw, err := mod.Session.FindMAC(ip, probe); err != nil { + mod.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 { - p.Warning("could not find IP address for %s", hw.String()) - } else if p.Session.Skip(net.ParseIP(ip)) { - p.Debug("skipping address %s from arp spoofing.", ip) + for _, hw := range mod.macs { + if ip, err := network.ArpInverseLookup(mod.Session.Interface.Name(), hw.String(), false); err != nil { + mod.Warning("could not find IP address for %s", hw.String()) + } else if mod.Session.Skip(net.ParseIP(ip)) { + mod.Debug("skipping address %s from arp spoofing.", ip) } else { targets[ip] = hw } @@ -238,13 +238,13 @@ func (p *ArpSpoofer) getTargets(probe bool) map[string]net.HardwareAddr { return targets } -func (p *ArpSpoofer) arpSpoofTargets(saddr net.IP, smac net.HardwareAddr, check_running bool, probe bool) { - p.waitGroup.Add(1) - defer p.waitGroup.Done() +func (mod *ArpSpoofer) arpSpoofTargets(saddr net.IP, smac net.HardwareAddr, check_running bool, probe bool) { + mod.waitGroup.Add(1) + defer mod.waitGroup.Done() - gwIP := p.Session.Gateway.IP - gwHW := p.Session.Gateway.HW - ourHW := p.Session.Interface.HW + gwIP := mod.Session.Gateway.IP + gwHW := mod.Session.Gateway.HW + ourHW := mod.Session.Interface.HW isGW := false isSpoofing := false @@ -257,11 +257,11 @@ func (p *ArpSpoofer) arpSpoofTargets(saddr net.IP, smac net.HardwareAddr, check_ } } - for ip, mac := range p.getTargets(probe) { - if check_running && !p.Running() { + for ip, mac := range mod.getTargets(probe) { + if check_running && !mod.Running() { return - } else if p.isWhitelisted(ip, mac) { - p.Debug("%s (%s) is whitelisted, skipping from spoofing loop.", ip, mac) + } else if mod.isWhitelisted(ip, mac) { + mod.Debug("%s (%s) is whitelisted, skipping from spoofing loop.", ip, mac) continue } else if saddr.String() == ip { continue @@ -269,34 +269,34 @@ func (p *ArpSpoofer) arpSpoofTargets(saddr net.IP, smac net.HardwareAddr, check_ rawIP := net.ParseIP(ip) if err, pkt := packets.NewARPReply(saddr, smac, rawIP, mac); err != nil { - p.Error("error while creating ARP spoof packet for %s: %s", ip, err) + mod.Error("error while creating ARP spoof packet for %s: %s", ip, err) } else { - p.Debug("sending %d bytes of ARP packet to %s:%s.", len(pkt), ip, mac.String()) - p.Session.Queue.Send(pkt) + mod.Debug("sending %d bytes of ARP packet to %s:%s.", len(pkt), ip, mac.String()) + mod.Session.Queue.Send(pkt) } - if p.fullDuplex && isGW { + if mod.fullDuplex && isGW { err := error(nil) gwPacket := []byte(nil) if isSpoofing { - p.Debug("telling the gw we are %s", ip) + mod.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 { - p.Error("error while creating ARP spoof packet: %s", err) + mod.Error("error while creating ARP spoof packet: %s", err) } } else { - p.Debug("telling the gw %s is %s", ip, mac) + mod.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 { - p.Error("error while creating ARP spoof packet: %s", err) + mod.Error("error while creating ARP spoof packet: %s", err) } } if gwPacket != nil { - if err = p.Session.Queue.Send(gwPacket); err != nil { - p.Error("error while sending packet: %v", err) + if err = mod.Session.Queue.Send(gwPacket); err != nil { + mod.Error("error while sending packet: %v", err) } } } diff --git a/modules/ble/ble_recon.go b/modules/ble/ble_recon.go index 89d3e885..9527b9a9 100644 --- a/modules/ble/ble_recon.go +++ b/modules/ble/ble_recon.go @@ -29,7 +29,7 @@ type BLERecon struct { } func NewBLERecon(s *session.Session) *BLERecon { - d := &BLERecon{ + mod := &BLERecon{ SessionModule: session.NewSessionModule("ble.recon", s), gattDevice: nil, quit: make(chan bool), @@ -39,38 +39,38 @@ func NewBLERecon(s *session.Session) *BLERecon { connected: false, } - d.AddHandler(session.NewModuleHandler("ble.recon on", "", + mod.AddHandler(session.NewModuleHandler("ble.recon on", "", "Start Bluetooth Low Energy devices discovery.", func(args []string) error { - return d.Start() + return mod.Start() })) - d.AddHandler(session.NewModuleHandler("ble.recon off", "", + mod.AddHandler(session.NewModuleHandler("ble.recon off", "", "Stop Bluetooth Low Energy devices discovery.", func(args []string) error { - return d.Stop() + return mod.Stop() })) - d.AddHandler(session.NewModuleHandler("ble.show", "", + mod.AddHandler(session.NewModuleHandler("ble.show", "", "Show discovered Bluetooth Low Energy devices.", func(args []string) error { - return d.Show() + return mod.Show() })) - d.AddHandler(session.NewModuleHandler("ble.enum MAC", "ble.enum "+network.BLEMacValidator, + mod.AddHandler(session.NewModuleHandler("ble.enum MAC", "ble.enum "+network.BLEMacValidator, "Enumerate services and characteristics for the given BLE device.", func(args []string) error { - if d.isEnumerating() { - return fmt.Errorf("An enumeration for %s is already running, please wait.", d.currDevice.Device.ID()) + if mod.isEnumerating() { + return fmt.Errorf("An enumeration for %s is already running, please wait.", mod.currDevice.Device.ID()) } - d.writeData = nil - d.writeUUID = nil + mod.writeData = nil + mod.writeUUID = nil - return d.enumAllTheThings(network.NormalizeMac(args[0])) + return mod.enumAllTheThings(network.NormalizeMac(args[0])) })) - d.AddHandler(session.NewModuleHandler("ble.write MAC UUID HEX_DATA", "ble.write "+network.BLEMacValidator+" ([a-fA-F0-9]+) ([a-fA-F0-9]+)", + mod.AddHandler(session.NewModuleHandler("ble.write MAC UUID HEX_DATA", "ble.write "+network.BLEMacValidator+" ([a-fA-F0-9]+) ([a-fA-F0-9]+)", "Write the HEX_DATA buffer to the BLE device with the specified MAC address, to the characteristics with the given UUID.", func(args []string) error { mac := network.NormalizeMac(args[0]) @@ -83,84 +83,84 @@ func NewBLERecon(s *session.Session) *BLERecon { return fmt.Errorf("Error parsing %s: %s", args[2], err) } - return d.writeBuffer(mac, uuid, data) + return mod.writeBuffer(mac, uuid, data) })) - return d + return mod } -func (d BLERecon) Name() string { +func (mod BLERecon) Name() string { return "ble.recon" } -func (d BLERecon) Description() string { +func (mod BLERecon) Description() string { return "Bluetooth Low Energy devices discovery." } -func (d BLERecon) Author() string { +func (mod BLERecon) Author() string { return "Simone Margaritelli " } -func (d *BLERecon) isEnumerating() bool { - return d.currDevice != nil +func (mod *BLERecon) isEnumerating() bool { + return mod.currDevice != nil } -func (d *BLERecon) Configure() (err error) { - if d.Running() { +func (mod *BLERecon) Configure() (err error) { + if mod.Running() { return session.ErrAlreadyStarted - } else if d.gattDevice == nil { - d.Info("Initializing BLE device ...") + } else if mod.gattDevice == nil { + mod.Info("Initializing BLE device ...") // hey Paypal GATT library, could you please just STFU?! golog.SetOutput(ioutil.Discard) - if d.gattDevice, err = gatt.NewDevice(defaultBLEClientOptions...); err != nil { + if mod.gattDevice, err = gatt.NewDevice(defaultBLEClientOptions...); err != nil { return err } - d.gattDevice.Handle( - gatt.PeripheralDiscovered(d.onPeriphDiscovered), - gatt.PeripheralConnected(d.onPeriphConnected), - gatt.PeripheralDisconnected(d.onPeriphDisconnected), + mod.gattDevice.Handle( + gatt.PeripheralDiscovered(mod.onPeriphDiscovered), + gatt.PeripheralConnected(mod.onPeriphConnected), + gatt.PeripheralDisconnected(mod.onPeriphDisconnected), ) - d.gattDevice.Init(d.onStateChanged) + mod.gattDevice.Init(mod.onStateChanged) } return nil } -func (d *BLERecon) Start() error { - if err := d.Configure(); err != nil { +func (mod *BLERecon) Start() error { + if err := mod.Configure(); err != nil { return err } - return d.SetRunning(true, func() { - go d.pruner() + return mod.SetRunning(true, func() { + go mod.pruner() - <-d.quit + <-mod.quit - d.Info("Stopping BLE scan ...") + mod.Info("Stopping BLE scan ...") - d.gattDevice.StopScanning() + mod.gattDevice.StopScanning() - d.done <- true + mod.done <- true }) } -func (d *BLERecon) Stop() error { - return d.SetRunning(false, func() { - d.quit <- true - <-d.done +func (mod *BLERecon) Stop() error { + return mod.SetRunning(false, func() { + mod.quit <- true + <-mod.done }) } -func (d *BLERecon) pruner() { - d.Debug("Started BLE devices pruner ...") +func (mod *BLERecon) pruner() { + mod.Debug("Started BLE devices pruner ...") - for d.Running() { - for _, dev := range d.Session.BLE.Devices() { + for mod.Running() { + for _, dev := range mod.Session.BLE.Devices() { if time.Since(dev.LastSeen) > blePresentInterval { - d.Session.BLE.Remove(dev.Device.ID()) + mod.Session.BLE.Remove(dev.Device.ID()) } } @@ -168,41 +168,41 @@ func (d *BLERecon) pruner() { } } -func (d *BLERecon) setCurrentDevice(dev *network.BLEDevice) { - d.connected = false - d.currDevice = dev +func (mod *BLERecon) setCurrentDevice(dev *network.BLEDevice) { + mod.connected = false + mod.currDevice = dev } -func (d *BLERecon) writeBuffer(mac string, uuid gatt.UUID, data []byte) error { - d.writeUUID = &uuid - d.writeData = data - return d.enumAllTheThings(mac) +func (mod *BLERecon) writeBuffer(mac string, uuid gatt.UUID, data []byte) error { + mod.writeUUID = &uuid + mod.writeData = data + return mod.enumAllTheThings(mac) } -func (d *BLERecon) enumAllTheThings(mac string) error { - dev, found := d.Session.BLE.Get(mac) +func (mod *BLERecon) enumAllTheThings(mac string) error { + dev, found := mod.Session.BLE.Get(mac) if !found || dev == nil { return fmt.Errorf("BLE device with address %s not found.", mac) - } else if d.Running() { - d.gattDevice.StopScanning() + } else if mod.Running() { + mod.gattDevice.StopScanning() } - d.setCurrentDevice(dev) - if err := d.Configure(); err != nil && err != session.ErrAlreadyStarted { + mod.setCurrentDevice(dev) + if err := mod.Configure(); err != nil && err != session.ErrAlreadyStarted { return err } - d.Info("Connecting to %s ...", mac) + mod.Info("Connecting to %s ...", mac) go func() { - time.Sleep(d.connTimeout) - if d.isEnumerating() && !d.connected { - d.Session.Events.Add("ble.connection.timeout", d.currDevice) - d.onPeriphDisconnected(nil, nil) + time.Sleep(mod.connTimeout) + if mod.isEnumerating() && !mod.connected { + mod.Session.Events.Add("ble.connection.timeout", mod.currDevice) + mod.onPeriphDisconnected(nil, nil) } }() - d.gattDevice.Connect(dev.Device) + mod.gattDevice.Connect(dev.Device) return nil } diff --git a/modules/ble/ble_recon_events.go b/modules/ble/ble_recon_events.go index e9ade95f..441da193 100644 --- a/modules/ble/ble_recon_events.go +++ b/modules/ble/ble_recon_events.go @@ -7,65 +7,65 @@ import ( "github.com/bettercap/gatt" ) -func (d *BLERecon) onStateChanged(dev gatt.Device, s gatt.State) { - d.Info("BLE state changed to %v", s) +func (mod *BLERecon) onStateChanged(dev gatt.Device, s gatt.State) { + mod.Info("BLE state changed to %v", s) switch s { case gatt.StatePoweredOn: - if d.currDevice == nil { - d.Info("Starting BLE discovery ...") + if mod.currDevice == nil { + mod.Info("Starting BLE discovery ...") dev.Scan([]gatt.UUID{}, true) } case gatt.StatePoweredOff: - d.gattDevice = nil + mod.gattDevice = nil default: - d.Warning("Unexpected BLE state: %v", s) + mod.Warning("Unexpected BLE state: %v", s) } } -func (d *BLERecon) onPeriphDiscovered(p gatt.Peripheral, a *gatt.Advertisement, rssi int) { - d.Session.BLE.AddIfNew(p.ID(), p, a, rssi) +func (mod *BLERecon) onPeriphDiscovered(p gatt.Peripheral, a *gatt.Advertisement, rssi int) { + mod.Session.BLE.AddIfNew(p.ID(), p, a, rssi) } -func (d *BLERecon) onPeriphDisconnected(p gatt.Peripheral, err error) { - if d.Running() { +func (mod *BLERecon) onPeriphDisconnected(p gatt.Peripheral, err error) { + if mod.Running() { // restore scanning - d.Info("Device disconnected, restoring BLE discovery.") - d.setCurrentDevice(nil) - d.gattDevice.Scan([]gatt.UUID{}, true) + mod.Info("Device disconnected, restoring BLE discovery.") + mod.setCurrentDevice(nil) + mod.gattDevice.Scan([]gatt.UUID{}, true) } } -func (d *BLERecon) onPeriphConnected(p gatt.Peripheral, err error) { +func (mod *BLERecon) onPeriphConnected(p gatt.Peripheral, err error) { if err != nil { - d.Warning("Connected to %s but with error: %s", p.ID(), err) + mod.Warning("Connected to %s but with error: %s", p.ID(), err) return - } else if d.currDevice == nil { + } else if mod.currDevice == nil { // timed out - d.Warning("Connected to %s but after the timeout :(", p.ID()) + mod.Warning("Connected to %s but after the timeout :(", p.ID()) return } - d.connected = true + mod.connected = true defer func(per gatt.Peripheral) { - d.Info("Disconnecting from %s ...", per.ID()) + mod.Info("Disconnecting from %s ...", per.ID()) per.Device().CancelConnection(per) }(p) - d.Session.Events.Add("ble.device.connected", d.currDevice) + mod.Session.Events.Add("ble.device.connected", mod.currDevice) if err := p.SetMTU(500); err != nil { - d.Warning("Failed to set MTU: %s", err) + mod.Warning("Failed to set MTU: %s", err) } - d.Info("Connected, enumerating all the things for %s!", p.ID()) + mod.Info("Connected, enumerating all the things for %s!", p.ID()) services, err := p.DiscoverServices(nil) if err != nil { - d.Error("Error discovering services: %s", err) + mod.Error("Error discovering services: %s", err) return } - d.showServices(p, services) + mod.showServices(p, services) } diff --git a/modules/ble/ble_recon_view.go b/modules/ble/ble_recon_view.go index c749d49c..020cd855 100644 --- a/modules/ble/ble_recon_view.go +++ b/modules/ble/ble_recon_view.go @@ -23,7 +23,7 @@ var ( blePresentInterval = time.Duration(30) * time.Second ) -func (d *BLERecon) getRow(dev *network.BLEDevice) []string { +func (mod *BLERecon) getRow(dev *network.BLEDevice) []string { address := network.NormalizeMac(dev.Device.ID()) vendor := dev.Vendor sinceSeen := time.Since(dev.LastSeen) @@ -51,14 +51,14 @@ func (d *BLERecon) getRow(dev *network.BLEDevice) []string { } } -func (d *BLERecon) Show() error { - devices := d.Session.BLE.Devices() +func (mod *BLERecon) Show() error { + devices := mod.Session.BLE.Devices() sort.Sort(ByBLERSSISorter(devices)) rows := make([][]string, 0) for _, dev := range devices { - rows = append(rows, d.getRow(dev)) + rows = append(rows, mod.getRow(dev)) } nrows := len(rows) @@ -68,7 +68,7 @@ func (d *BLERecon) Show() error { tui.Table(os.Stdout, columns, rows) } - d.Session.Refresh() + mod.Session.Refresh() return nil } @@ -124,15 +124,15 @@ func parseRawData(raw []byte) string { return tui.Yellow(s) } -func (d *BLERecon) showServices(p gatt.Peripheral, services []*gatt.Service) { +func (mod *BLERecon) showServices(p gatt.Peripheral, services []*gatt.Service) { columns := []string{"Handles", "Service > Characteristics", "Properties", "Data"} rows := make([][]string, 0) - wantsToWrite := d.writeUUID != nil + wantsToWrite := mod.writeUUID != nil foundToWrite := false for _, svc := range services { - d.Session.Events.Add("ble.device.service.discovered", svc) + mod.Session.Events.Add("ble.device.service.discovered", svc) name := svc.Name() if name == "" { @@ -152,12 +152,12 @@ func (d *BLERecon) showServices(p gatt.Peripheral, services []*gatt.Service) { chars, err := p.DiscoverCharacteristics(nil, svc) if err != nil { - d.Error("Error while enumerating chars for service %s: %s", svc.UUID(), err) + mod.Error("Error while enumerating chars for service %s: %s", svc.UUID(), err) continue } for _, ch := range chars { - d.Session.Events.Add("ble.device.characteristic.discovered", ch) + mod.Session.Events.Add("ble.device.characteristic.discovered", ch) name = ch.Name() if name == "" { @@ -168,17 +168,17 @@ func (d *BLERecon) showServices(p gatt.Peripheral, services []*gatt.Service) { props, isReadable, isWritable, withResponse := parseProperties(ch) - if wantsToWrite && d.writeUUID.Equal(ch.UUID()) { + if wantsToWrite && mod.writeUUID.Equal(ch.UUID()) { foundToWrite = true if isWritable { - d.Info("Writing %d bytes to characteristics %s ...", len(d.writeData), d.writeUUID) + mod.Info("Writing %d bytes to characteristics %s ...", len(mod.writeData), mod.writeUUID) } else { - d.Warning("Attempt to write %d bytes to non writable characteristics %s ...", len(d.writeData), d.writeUUID) + mod.Warning("Attempt to write %d bytes to non writable characteristics %s ...", len(mod.writeData), mod.writeUUID) } - err := p.WriteCharacteristic(ch, d.writeData, !withResponse) + err := p.WriteCharacteristic(ch, mod.writeData, !withResponse) if err != nil { - d.Error("Error while writing: %s", err) + mod.Error("Error while writing: %s", err) } } @@ -204,9 +204,9 @@ func (d *BLERecon) showServices(p gatt.Peripheral, services []*gatt.Service) { } if wantsToWrite && !foundToWrite { - d.Error("Writable characteristics %s not found.", d.writeUUID) + mod.Error("Writable characteristics %s not found.", mod.writeUUID) } else { tui.Table(os.Stdout, columns, rows) - d.Session.Refresh() + mod.Session.Refresh() } } diff --git a/modules/ble/ble_unsupported.go b/modules/ble/ble_unsupported.go index dd14d3ed..f8016a41 100644 --- a/modules/ble/ble_unsupported.go +++ b/modules/ble/ble_unsupported.go @@ -22,45 +22,45 @@ var defaultBLEServerOptions = []gatt.Option{ } */ func NewBLERecon(s *session.Session) *BLERecon { - d := &BLERecon{ + mod := &BLERecon{ SessionModule: session.NewSessionModule("ble.recon", s), } - d.AddHandler(session.NewModuleHandler("ble.recon on", "", + mod.AddHandler(session.NewModuleHandler("ble.recon on", "", "Start Bluetooth Low Energy devices discovery.", func(args []string) error { return session.ErrNotSupported })) - d.AddHandler(session.NewModuleHandler("ble.recon off", "", + mod.AddHandler(session.NewModuleHandler("ble.recon off", "", "Stop Bluetooth Low Energy devices discovery.", func(args []string) error { return session.ErrNotSupported })) - return d + return mod } -func (d BLERecon) Name() string { +func (mod BLERecon) Name() string { return "ble.recon" } -func (d BLERecon) Description() string { +func (mod BLERecon) Description() string { return "Bluetooth Low Energy devices discovery." } -func (d BLERecon) Author() string { +func (mod BLERecon) Author() string { return "Simone Margaritelli " } -func (d *BLERecon) Configure() (err error) { +func (mod *BLERecon) Configure() (err error) { return session.ErrNotSupported } -func (d *BLERecon) Start() error { +func (mod *BLERecon) Start() error { return session.ErrNotSupported } -func (d *BLERecon) Stop() error { +func (mod *BLERecon) Stop() error { return session.ErrNotSupported } diff --git a/modules/caplets/caplets.go b/modules/caplets/caplets.go index d64aa970..61b5589a 100644 --- a/modules/caplets/caplets.go +++ b/modules/caplets/caplets.go @@ -21,56 +21,56 @@ type CapletsModule struct { } func NewCapletsModule(s *session.Session) *CapletsModule { - c := &CapletsModule{ + mod := &CapletsModule{ SessionModule: session.NewSessionModule("caplets", s), } - c.AddHandler(session.NewModuleHandler("caplets.show", "", + mod.AddHandler(session.NewModuleHandler("caplets.show", "", "Show a list of installed caplets.", func(args []string) error { - return c.Show() + return mod.Show() })) - c.AddHandler(session.NewModuleHandler("caplets.paths", "", + mod.AddHandler(session.NewModuleHandler("caplets.paths", "", "Show a list caplet search paths.", func(args []string) error { - return c.Paths() + return mod.Paths() })) - c.AddHandler(session.NewModuleHandler("caplets.update", "", + mod.AddHandler(session.NewModuleHandler("caplets.update", "", "Install/updates the caplets.", func(args []string) error { - return c.Update() + return mod.Update() })) - return c + return mod } -func (c *CapletsModule) Name() string { +func (mod *CapletsModule) Name() string { return "caplets" } -func (c *CapletsModule) Description() string { +func (mod *CapletsModule) Description() string { return "A module to list and update caplets." } -func (c *CapletsModule) Author() string { +func (mod *CapletsModule) Author() string { return "Simone Margaritelli " } -func (c *CapletsModule) Configure() error { +func (mod *CapletsModule) Configure() error { return nil } -func (c *CapletsModule) Stop() error { +func (mod *CapletsModule) Stop() error { return nil } -func (c *CapletsModule) Start() error { +func (mod *CapletsModule) Start() error { return nil } -func (c *CapletsModule) Show() error { +func (mod *CapletsModule) Show() error { caplets := caplets.List() if len(caplets) == 0 { return fmt.Errorf("no installed caplets on this system, use the caplets.update command to download them") @@ -96,7 +96,7 @@ func (c *CapletsModule) Show() error { return nil } -func (c *CapletsModule) Paths() error { +func (mod *CapletsModule) Paths() error { colNames := []string{ "Path", } @@ -112,9 +112,9 @@ func (c *CapletsModule) Paths() error { return nil } -func (c *CapletsModule) Update() error { +func (mod *CapletsModule) Update() error { if !fs.Exists(caplets.InstallBase) { - c.Info("creating caplets install path %s ...", caplets.InstallBase) + mod.Info("creating caplets install path %s ...", caplets.InstallBase) if err := os.MkdirAll(caplets.InstallBase, os.ModePerm); err != nil { return err } @@ -126,7 +126,7 @@ func (c *CapletsModule) Update() error { } defer out.Close() - c.Info("downloading caplets from %s ...", caplets.InstallArchive) + mod.Info("downloading caplets from %s ...", caplets.InstallArchive) resp, err := http.Get(caplets.InstallArchive) if err != nil { @@ -138,7 +138,7 @@ func (c *CapletsModule) Update() error { return err } - c.Info("installing caplets to %s ...", caplets.InstallPath) + mod.Info("installing caplets to %s ...", caplets.InstallPath) if _, err = zip.Unzip("/tmp/caplets.zip", caplets.InstallBase); err != nil { return err diff --git a/modules/dhcp6_spoof/dhcp6_spoof.go b/modules/dhcp6_spoof/dhcp6_spoof.go index a7bafb6c..f7a7a325 100644 --- a/modules/dhcp6_spoof/dhcp6_spoof.go +++ b/modules/dhcp6_spoof/dhcp6_spoof.go @@ -36,93 +36,93 @@ type DHCP6Spoofer struct { } func NewDHCP6Spoofer(s *session.Session) *DHCP6Spoofer { - spoof := &DHCP6Spoofer{ + mod := &DHCP6Spoofer{ SessionModule: session.NewSessionModule("dhcp6.spoof", s), Handle: nil, waitGroup: &sync.WaitGroup{}, } - spoof.AddParam(session.NewStringParameter("dhcp6.spoof.domains", + mod.AddParam(session.NewStringParameter("dhcp6.spoof.domains", "microsoft.com, google.com, facebook.com, apple.com, twitter.com", ``, "Comma separated values of domain names to spoof.")) - spoof.AddHandler(session.NewModuleHandler("dhcp6.spoof on", "", + mod.AddHandler(session.NewModuleHandler("dhcp6.spoof on", "", "Start the DHCPv6 spoofer in the background.", func(args []string) error { - return spoof.Start() + return mod.Start() })) - spoof.AddHandler(session.NewModuleHandler("dhcp6.spoof off", "", + mod.AddHandler(session.NewModuleHandler("dhcp6.spoof off", "", "Stop the DHCPv6 spoofer in the background.", func(args []string) error { - return spoof.Stop() + return mod.Stop() })) - return spoof + return mod } -func (s DHCP6Spoofer) Name() string { +func (mod DHCP6Spoofer) Name() string { return "dhcp6.spoof" } -func (s DHCP6Spoofer) Description() string { +func (mod DHCP6Spoofer) Description() string { return "Replies to DHCPv6 messages, providing victims with a link-local IPv6 address and setting the attackers host as default DNS server (https://github.com/fox-it/mitm6/)." } -func (s DHCP6Spoofer) Author() string { +func (mod DHCP6Spoofer) Author() string { return "Simone Margaritelli " } -func (s *DHCP6Spoofer) Configure() error { +func (mod *DHCP6Spoofer) Configure() error { var err error - if s.Running() { + if mod.Running() { return session.ErrAlreadyStarted } - if s.Handle, err = pcap.OpenLive(s.Session.Interface.Name(), 65536, true, pcap.BlockForever); err != nil { + if mod.Handle, err = pcap.OpenLive(mod.Session.Interface.Name(), 65536, true, pcap.BlockForever); err != nil { return err } - err = s.Handle.SetBPFFilter("ip6 and udp") + err = mod.Handle.SetBPFFilter("ip6 and udp") if err != nil { return err } - if err, s.Domains = s.ListParam("dhcp6.spoof.domains"); err != nil { + if err, mod.Domains = mod.ListParam("dhcp6.spoof.domains"); err != nil { return err } - s.RawDomains = packets.DHCP6EncodeList(s.Domains) + mod.RawDomains = packets.DHCP6EncodeList(mod.Domains) - if s.DUID, err = dhcp6opts.NewDUIDLLT(1, time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC), s.Session.Interface.HW); err != nil { + if mod.DUID, err = dhcp6opts.NewDUIDLLT(1, time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC), mod.Session.Interface.HW); err != nil { return err - } else if s.DUIDRaw, err = s.DUID.MarshalBinary(); err != nil { + } else if mod.DUIDRaw, err = mod.DUID.MarshalBinary(); err != nil { return err } - if !s.Session.Firewall.IsForwardingEnabled() { - s.Info("Enabling forwarding.") - s.Session.Firewall.EnableForwarding(true) + if !mod.Session.Firewall.IsForwardingEnabled() { + mod.Info("Enabling forwarding.") + mod.Session.Firewall.EnableForwarding(true) } return nil } -func (s *DHCP6Spoofer) dhcp6For(what dhcp6.MessageType, to dhcp6.Packet) (err error, p dhcp6.Packet) { - err, p = packets.DHCP6For(what, to, s.DUIDRaw) +func (mod *DHCP6Spoofer) dhcp6For(what dhcp6.MessageType, to dhcp6.Packet) (err error, p dhcp6.Packet) { + err, p = packets.DHCP6For(what, to, mod.DUIDRaw) if err != nil { return } - p.Options.AddRaw(packets.DHCP6OptDNSServers, s.Session.Interface.IPv6) - p.Options.AddRaw(packets.DHCP6OptDNSDomains, s.RawDomains) + p.Options.AddRaw(packets.DHCP6OptDNSServers, mod.Session.Interface.IPv6) + p.Options.AddRaw(packets.DHCP6OptDNSDomains, mod.RawDomains) return nil, p } -func (s *DHCP6Spoofer) dhcpAdvertise(pkt gopacket.Packet, solicit dhcp6.Packet, target net.HardwareAddr) { +func (mod *DHCP6Spoofer) dhcpAdvertise(pkt gopacket.Packet, solicit dhcp6.Packet, target net.HardwareAddr) { pip6 := pkt.Layer(layers.LayerTypeIPv6).(*layers.IPv6) fqdn := target.String() @@ -130,29 +130,29 @@ func (s *DHCP6Spoofer) dhcpAdvertise(pkt gopacket.Packet, solicit dhcp6.Packet, fqdn = string(raw[0]) } - s.Info("Got DHCPv6 Solicit request from %s (%s), sending spoofed advertisement for %d domains.", tui.Bold(fqdn), target, len(s.Domains)) + mod.Info("Got DHCPv6 Solicit request from %s (%s), sending spoofed advertisement for %d domains.", tui.Bold(fqdn), target, len(mod.Domains)) - err, adv := s.dhcp6For(dhcp6.MessageTypeAdvertise, solicit) + err, adv := mod.dhcp6For(dhcp6.MessageTypeAdvertise, solicit) if err != nil { - s.Error("%s", err) + mod.Error("%s", err) return } var solIANA dhcp6opts.IANA if raw, found := solicit.Options[dhcp6.OptionIANA]; !found || len(raw) < 1 { - s.Error("Unexpected DHCPv6 packet, could not find IANA.") + mod.Error("Unexpected DHCPv6 packet, could not find IANA.") return } else if err := solIANA.UnmarshalBinary(raw[0]); err != nil { - s.Error("Unexpected DHCPv6 packet, could not deserialize IANA.") + mod.Error("Unexpected DHCPv6 packet, could not deserialize IANA.") return } var ip net.IP - if h, found := s.Session.Lan.Get(target.String()); found { + if h, found := mod.Session.Lan.Get(target.String()); found { ip = h.IP } else { - s.Warning("Address %s not known, using random identity association address.", target.String()) + mod.Warning("Address %s not known, using random identity association address.", target.String()) rand.Read(ip) } @@ -160,13 +160,13 @@ func (s *DHCP6Spoofer) dhcpAdvertise(pkt gopacket.Packet, solicit dhcp6.Packet, iaaddr, err := dhcp6opts.NewIAAddr(net.ParseIP(addr), 300*time.Second, 300*time.Second, nil) if err != nil { - s.Error("Error creating IAAddr: %s", err) + mod.Error("Error creating IAAddr: %s", err) return } iaaddrRaw, err := iaaddr.MarshalBinary() if err != nil { - s.Error("Error serializing IAAddr: %s", err) + mod.Error("Error serializing IAAddr: %s", err) return } @@ -174,7 +174,7 @@ func (s *DHCP6Spoofer) dhcpAdvertise(pkt gopacket.Packet, solicit dhcp6.Packet, iana := dhcp6opts.NewIANA(solIANA.IAID, 200*time.Second, 250*time.Second, opts) ianaRaw, err := iana.MarshalBinary() if err != nil { - s.Error("Error serializing IANA: %s", err) + mod.Error("Error serializing IANA: %s", err) return } @@ -182,12 +182,12 @@ func (s *DHCP6Spoofer) dhcpAdvertise(pkt gopacket.Packet, solicit dhcp6.Packet, rawAdv, err := adv.MarshalBinary() if err != nil { - s.Error("Error serializing advertisement packet: %s.", err) + mod.Error("Error serializing advertisement packet: %s.", err) return } eth := layers.Ethernet{ - SrcMAC: s.Session.Interface.HW, + SrcMAC: mod.Session.Interface.HW, DstMAC: target, EthernetType: layers.EthernetTypeIPv6, } @@ -196,7 +196,7 @@ func (s *DHCP6Spoofer) dhcpAdvertise(pkt gopacket.Packet, solicit dhcp6.Packet, Version: 6, NextHeader: layers.IPProtocolUDP, HopLimit: 64, - SrcIP: s.Session.Interface.IPv6, + SrcIP: mod.Session.Interface.IPv6, DstIP: pip6.SrcIP, } @@ -213,31 +213,31 @@ func (s *DHCP6Spoofer) dhcpAdvertise(pkt gopacket.Packet, solicit dhcp6.Packet, err, raw := packets.Serialize(ð, &ip6, &udp, &dhcp) if err != nil { - s.Error("Error serializing packet: %s.", err) + mod.Error("Error serializing packet: %s.", err) return } - s.Debug("Sending %d bytes of packet ...", len(raw)) - if err := s.Session.Queue.Send(raw); err != nil { - s.Error("Error sending packet: %s", err) + mod.Debug("Sending %d bytes of packet ...", len(raw)) + if err := mod.Session.Queue.Send(raw); err != nil { + mod.Error("Error sending packet: %s", err) } } -func (s *DHCP6Spoofer) dhcpReply(toType string, pkt gopacket.Packet, req dhcp6.Packet, target net.HardwareAddr) { - s.Debug("Sending spoofed DHCPv6 reply to %s after its %s packet.", tui.Bold(target.String()), toType) +func (mod *DHCP6Spoofer) dhcpReply(toType string, pkt gopacket.Packet, req dhcp6.Packet, target net.HardwareAddr) { + mod.Debug("Sending spoofed DHCPv6 reply to %s after its %s packet.", tui.Bold(target.String()), toType) - err, reply := s.dhcp6For(dhcp6.MessageTypeReply, req) + err, reply := mod.dhcp6For(dhcp6.MessageTypeReply, req) if err != nil { - s.Error("%s", err) + mod.Error("%s", err) return } var reqIANA dhcp6opts.IANA if raw, found := req.Options[dhcp6.OptionIANA]; !found || len(raw) < 1 { - s.Error("Unexpected DHCPv6 packet, could not find IANA.") + mod.Error("Unexpected DHCPv6 packet, could not find IANA.") return } else if err := reqIANA.UnmarshalBinary(raw[0]); err != nil { - s.Error("Unexpected DHCPv6 packet, could not deserialize IANA.") + mod.Error("Unexpected DHCPv6 packet, could not deserialize IANA.") return } @@ -245,7 +245,7 @@ func (s *DHCP6Spoofer) dhcpReply(toType string, pkt gopacket.Packet, req dhcp6.P if raw, found := reqIANA.Options[dhcp6.OptionIAAddr]; found { reqIAddr = raw[0] } else { - s.Error("Unexpected DHCPv6 packet, could not deserialize request IANA IAAddr.") + mod.Error("Unexpected DHCPv6 packet, could not deserialize request IANA IAAddr.") return } @@ -253,20 +253,20 @@ func (s *DHCP6Spoofer) dhcpReply(toType string, pkt gopacket.Packet, req dhcp6.P iana := dhcp6opts.NewIANA(reqIANA.IAID, 200*time.Second, 250*time.Second, opts) ianaRaw, err := iana.MarshalBinary() if err != nil { - s.Error("Error serializing IANA: %s", err) + mod.Error("Error serializing IANA: %s", err) return } reply.Options.AddRaw(dhcp6.OptionIANA, ianaRaw) rawAdv, err := reply.MarshalBinary() if err != nil { - s.Error("Error serializing advertisement packet: %s.", err) + mod.Error("Error serializing advertisement packet: %s.", err) return } pip6 := pkt.Layer(layers.LayerTypeIPv6).(*layers.IPv6) eth := layers.Ethernet{ - SrcMAC: s.Session.Interface.HW, + SrcMAC: mod.Session.Interface.HW, DstMAC: target, EthernetType: layers.EthernetTypeIPv6, } @@ -275,7 +275,7 @@ func (s *DHCP6Spoofer) dhcpReply(toType string, pkt gopacket.Packet, req dhcp6.P Version: 6, NextHeader: layers.IPProtocolUDP, HopLimit: 64, - SrcIP: s.Session.Interface.IPv6, + SrcIP: mod.Session.Interface.IPv6, DstIP: pip6.SrcIP, } @@ -292,13 +292,13 @@ func (s *DHCP6Spoofer) dhcpReply(toType string, pkt gopacket.Packet, req dhcp6.P err, raw := packets.Serialize(ð, &ip6, &udp, &dhcp) if err != nil { - s.Error("Error serializing packet: %s.", err) + mod.Error("Error serializing packet: %s.", err) return } - s.Debug("Sending %d bytes of packet ...", len(raw)) - if err := s.Session.Queue.Send(raw); err != nil { - s.Error("Error sending packet: %s", err) + mod.Debug("Sending %d bytes of packet ...", len(raw)) + if err := mod.Session.Queue.Send(raw); err != nil { + mod.Error("Error sending packet: %s", err) } if toType == "request" { @@ -307,26 +307,26 @@ func (s *DHCP6Spoofer) dhcpReply(toType string, pkt gopacket.Packet, req dhcp6.P addr = net.IP(raw[0]) } - if h, found := s.Session.Lan.Get(target.String()); found { - s.Info("IPv6 address %s is now assigned to %s", addr.String(), h) + if h, found := mod.Session.Lan.Get(target.String()); found { + mod.Info("IPv6 address %s is now assigned to %s", addr.String(), h) } else { - s.Info("IPv6 address %s is now assigned to %s", addr.String(), target) + mod.Info("IPv6 address %s is now assigned to %s", addr.String(), target) } } else { - s.Debug("DHCPv6 renew sent to %s", target) + mod.Debug("DHCPv6 renew sent to %s", target) } } -func (s *DHCP6Spoofer) duidMatches(dhcp dhcp6.Packet) bool { +func (mod *DHCP6Spoofer) duidMatches(dhcp dhcp6.Packet) bool { if raw, found := dhcp.Options[dhcp6.OptionServerID]; found && len(raw) >= 1 { - if bytes.Equal(raw[0], s.DUIDRaw) { + if bytes.Equal(raw[0], mod.DUIDRaw) { return true } } return false } -func (s *DHCP6Spoofer) onPacket(pkt gopacket.Packet) { +func (mod *DHCP6Spoofer) onPacket(pkt gopacket.Packet) { var dhcp dhcp6.Packet var err error @@ -341,46 +341,46 @@ func (s *DHCP6Spoofer) onPacket(pkt gopacket.Packet) { switch dhcp.MessageType { case dhcp6.MessageTypeSolicit: - s.dhcpAdvertise(pkt, dhcp, eth.SrcMAC) + mod.dhcpAdvertise(pkt, dhcp, eth.SrcMAC) case dhcp6.MessageTypeRequest: - if s.duidMatches(dhcp) { - s.dhcpReply("request", pkt, dhcp, eth.SrcMAC) + if mod.duidMatches(dhcp) { + mod.dhcpReply("request", pkt, dhcp, eth.SrcMAC) } case dhcp6.MessageTypeRenew: - if s.duidMatches(dhcp) { - s.dhcpReply("renew", pkt, dhcp, eth.SrcMAC) + if mod.duidMatches(dhcp) { + mod.dhcpReply("renew", pkt, dhcp, eth.SrcMAC) } } } } -func (s *DHCP6Spoofer) Start() error { - if err := s.Configure(); err != nil { +func (mod *DHCP6Spoofer) Start() error { + if err := mod.Configure(); err != nil { return err } - return s.SetRunning(true, func() { - s.waitGroup.Add(1) - defer s.waitGroup.Done() + return mod.SetRunning(true, func() { + mod.waitGroup.Add(1) + defer mod.waitGroup.Done() - src := gopacket.NewPacketSource(s.Handle, s.Handle.LinkType()) - s.pktSourceChan = src.Packets() - for packet := range s.pktSourceChan { - if !s.Running() { + src := gopacket.NewPacketSource(mod.Handle, mod.Handle.LinkType()) + mod.pktSourceChan = src.Packets() + for packet := range mod.pktSourceChan { + if !mod.Running() { break } - s.onPacket(packet) + mod.onPacket(packet) } }) } -func (s *DHCP6Spoofer) Stop() error { - return s.SetRunning(false, func() { - s.pktSourceChan <- nil - s.Handle.Close() - s.waitGroup.Wait() +func (mod *DHCP6Spoofer) Stop() error { + return mod.SetRunning(false, func() { + mod.pktSourceChan <- nil + mod.Handle.Close() + mod.waitGroup.Wait() }) } diff --git a/modules/dns_spoof/dns_spoof.go b/modules/dns_spoof/dns_spoof.go index ce242885..7c197274 100644 --- a/modules/dns_spoof/dns_spoof.go +++ b/modules/dns_spoof/dns_spoof.go @@ -26,7 +26,7 @@ type DNSSpoofer struct { } func NewDNSSpoofer(s *session.Session) *DNSSpoofer { - spoof := &DNSSpoofer{ + mod := &DNSSpoofer{ SessionModule: session.NewSessionModule("dns.spoof", s), Handle: nil, All: false, @@ -34,120 +34,120 @@ func NewDNSSpoofer(s *session.Session) *DNSSpoofer { waitGroup: &sync.WaitGroup{}, } - spoof.AddParam(session.NewStringParameter("dns.spoof.hosts", + mod.AddParam(session.NewStringParameter("dns.spoof.hosts", "", "", "If not empty, this hosts file will be used to map domains to IP addresses.")) - spoof.AddParam(session.NewStringParameter("dns.spoof.domains", + mod.AddParam(session.NewStringParameter("dns.spoof.domains", "", "", "Comma separated values of domain names to spoof.")) - spoof.AddParam(session.NewStringParameter("dns.spoof.address", + mod.AddParam(session.NewStringParameter("dns.spoof.address", session.ParamIfaceAddress, session.IPv4Validator, "IP address to map the domains to.")) - spoof.AddParam(session.NewBoolParameter("dns.spoof.all", + mod.AddParam(session.NewBoolParameter("dns.spoof.all", "false", "If true the module will reply to every DNS request, otherwise it will only reply to the one targeting the local pc.")) - spoof.AddHandler(session.NewModuleHandler("dns.spoof on", "", + mod.AddHandler(session.NewModuleHandler("dns.spoof on", "", "Start the DNS spoofer in the background.", func(args []string) error { - return spoof.Start() + return mod.Start() })) - spoof.AddHandler(session.NewModuleHandler("dns.spoof off", "", + mod.AddHandler(session.NewModuleHandler("dns.spoof off", "", "Stop the DNS spoofer in the background.", func(args []string) error { - return spoof.Stop() + return mod.Stop() })) - return spoof + return mod } -func (s DNSSpoofer) Name() string { +func (mod DNSSpoofer) Name() string { return "dns.spoof" } -func (s DNSSpoofer) Description() string { +func (mod DNSSpoofer) Description() string { return "Replies to DNS messages with spoofed responses." } -func (s DNSSpoofer) Author() string { +func (mod DNSSpoofer) Author() string { return "Simone Margaritelli " } -func (s *DNSSpoofer) Configure() error { +func (mod *DNSSpoofer) Configure() error { var err error var hostsFile string var domains []string var address net.IP - if s.Running() { + if mod.Running() { return session.ErrAlreadyStarted - } else if s.Handle, err = pcap.OpenLive(s.Session.Interface.Name(), 65536, true, pcap.BlockForever); err != nil { + } else if mod.Handle, err = pcap.OpenLive(mod.Session.Interface.Name(), 65536, true, pcap.BlockForever); err != nil { return err - } else if err = s.Handle.SetBPFFilter("udp"); err != nil { + } else if err = mod.Handle.SetBPFFilter("udp"); err != nil { return err - } else if err, s.All = s.BoolParam("dns.spoof.all"); err != nil { + } else if err, mod.All = mod.BoolParam("dns.spoof.all"); err != nil { return err - } else if err, address = s.IPParam("dns.spoof.address"); err != nil { + } else if err, address = mod.IPParam("dns.spoof.address"); err != nil { return err - } else if err, domains = s.ListParam("dns.spoof.domains"); err != nil { + } else if err, domains = mod.ListParam("dns.spoof.domains"); err != nil { return err - } else if err, hostsFile = s.StringParam("dns.spoof.hosts"); err != nil { + } else if err, hostsFile = mod.StringParam("dns.spoof.hosts"); err != nil { return err } - s.Hosts = Hosts{} + mod.Hosts = Hosts{} for _, domain := range domains { - s.Hosts = append(s.Hosts, NewHostEntry(domain, address)) + mod.Hosts = append(mod.Hosts, NewHostEntry(domain, address)) } if hostsFile != "" { - s.Info("loading hosts from file %s ...", hostsFile) + mod.Info("loading hosts from file %s ...", hostsFile) if err, hosts := HostsFromFile(hostsFile); err != nil { return fmt.Errorf("error reading hosts from file %s: %v", hostsFile, err) } else { - s.Hosts = append(s.Hosts, hosts...) + mod.Hosts = append(mod.Hosts, hosts...) } } - if len(s.Hosts) == 0 { + if len(mod.Hosts) == 0 { return fmt.Errorf("at least dns.spoof.hosts or dns.spoof.domains must be filled") } - for _, entry := range s.Hosts { - s.Info("%s -> %s", entry.Host, entry.Address) + for _, entry := range mod.Hosts { + mod.Info("%s -> %s", entry.Host, entry.Address) } - if !s.Session.Firewall.IsForwardingEnabled() { - s.Info("enabling forwarding.") - s.Session.Firewall.EnableForwarding(true) + if !mod.Session.Firewall.IsForwardingEnabled() { + mod.Info("enabling forwarding.") + mod.Session.Firewall.EnableForwarding(true) } return nil } -func (s *DNSSpoofer) dnsReply(pkt gopacket.Packet, peth *layers.Ethernet, pudp *layers.UDP, domain string, address net.IP, req *layers.DNS, target net.HardwareAddr) { +func (mod *DNSSpoofer) dnsReply(pkt gopacket.Packet, peth *layers.Ethernet, pudp *layers.UDP, domain string, address net.IP, req *layers.DNS, target net.HardwareAddr) { redir := fmt.Sprintf("(->%s)", address.String()) who := target.String() - if t, found := s.Session.Lan.Get(target.String()); found { + if t, found := mod.Session.Lan.Get(target.String()); found { who = t.String() } - s.Info("sending spoofed DNS reply for %s %s to %s.", tui.Red(domain), tui.Dim(redir), tui.Bold(who)) + mod.Info("sending spoofed DNS reply for %s %s to %s.", tui.Red(domain), tui.Dim(redir), tui.Bold(who)) var err error var src, dst net.IP nlayer := pkt.NetworkLayer() if nlayer == nil { - s.Debug("missing network layer skipping packet.") + mod.Debug("missing network layer skipping packet.") return } @@ -216,7 +216,7 @@ func (s *DNSSpoofer) dnsReply(pkt gopacket.Packet, peth *layers.Ethernet, pudp * err, raw = packets.Serialize(ð, &ip6, &udp, &dns) if err != nil { - s.Error("error serializing packet: %s.", err) + mod.Error("error serializing packet: %s.", err) return } } else { @@ -237,18 +237,18 @@ func (s *DNSSpoofer) dnsReply(pkt gopacket.Packet, peth *layers.Ethernet, pudp * err, raw = packets.Serialize(ð, &ip4, &udp, &dns) if err != nil { - s.Error("error serializing packet: %s.", err) + mod.Error("error serializing packet: %s.", err) return } } - s.Debug("sending %d bytes of packet ...", len(raw)) - if err := s.Session.Queue.Send(raw); err != nil { - s.Error("error sending packet: %s", err) + mod.Debug("sending %d bytes of packet ...", len(raw)) + if err := mod.Session.Queue.Send(raw); err != nil { + mod.Error("error sending packet: %s", err) } } -func (s *DNSSpoofer) onPacket(pkt gopacket.Packet) { +func (mod *DNSSpoofer) onPacket(pkt gopacket.Packet) { typeEth := pkt.Layer(layers.LayerTypeEthernet) typeUDP := pkt.Layer(layers.LayerTypeUDP) if typeEth == nil || typeUDP == nil { @@ -256,48 +256,48 @@ func (s *DNSSpoofer) onPacket(pkt gopacket.Packet) { } eth := typeEth.(*layers.Ethernet) - if s.All || bytes.Equal(eth.DstMAC, s.Session.Interface.HW) { + if mod.All || bytes.Equal(eth.DstMAC, mod.Session.Interface.HW) { dns, parsed := pkt.Layer(layers.LayerTypeDNS).(*layers.DNS) if parsed && dns.OpCode == layers.DNSOpCodeQuery && len(dns.Questions) > 0 && len(dns.Answers) == 0 { udp := typeUDP.(*layers.UDP) for _, q := range dns.Questions { qName := string(q.Name) - if address := s.Hosts.Resolve(qName); address != nil { - s.dnsReply(pkt, eth, udp, qName, address, dns, eth.SrcMAC) + if address := mod.Hosts.Resolve(qName); address != nil { + mod.dnsReply(pkt, eth, udp, qName, address, dns, eth.SrcMAC) break } else { - s.Debug("skipping domain %s", qName) + mod.Debug("skipping domain %s", qName) } } } } } -func (s *DNSSpoofer) Start() error { - if err := s.Configure(); err != nil { +func (mod *DNSSpoofer) Start() error { + if err := mod.Configure(); err != nil { return err } - return s.SetRunning(true, func() { - s.waitGroup.Add(1) - defer s.waitGroup.Done() + return mod.SetRunning(true, func() { + mod.waitGroup.Add(1) + defer mod.waitGroup.Done() - src := gopacket.NewPacketSource(s.Handle, s.Handle.LinkType()) - s.pktSourceChan = src.Packets() - for packet := range s.pktSourceChan { - if !s.Running() { + src := gopacket.NewPacketSource(mod.Handle, mod.Handle.LinkType()) + mod.pktSourceChan = src.Packets() + for packet := range mod.pktSourceChan { + if !mod.Running() { break } - s.onPacket(packet) + mod.onPacket(packet) } }) } -func (s *DNSSpoofer) Stop() error { - return s.SetRunning(false, func() { - s.pktSourceChan <- nil - s.Handle.Close() - s.waitGroup.Wait() +func (mod *DNSSpoofer) Stop() error { + return mod.SetRunning(false, func() { + mod.pktSourceChan <- nil + mod.Handle.Close() + mod.waitGroup.Wait() }) } diff --git a/modules/events_stream/events_stream.go b/modules/events_stream/events_stream.go index 4b208a0a..69274618 100644 --- a/modules/events_stream/events_stream.go +++ b/modules/events_stream/events_stream.go @@ -38,7 +38,7 @@ type EventsStream struct { } func NewEventsStream(s *session.Session) *EventsStream { - stream := &EventsStream{ + mod := &EventsStream{ SessionModule: session.NewSessionModule("events.stream", s), output: os.Stdout, quit: make(chan bool), @@ -47,19 +47,19 @@ func NewEventsStream(s *session.Session) *EventsStream { ignoreList: NewIgnoreList(), } - stream.AddHandler(session.NewModuleHandler("events.stream on", "", + mod.AddHandler(session.NewModuleHandler("events.stream on", "", "Start events stream.", func(args []string) error { - return stream.Start() + return mod.Start() })) - stream.AddHandler(session.NewModuleHandler("events.stream off", "", + mod.AddHandler(session.NewModuleHandler("events.stream off", "", "Stop events stream.", func(args []string) error { - return stream.Stop() + return mod.Stop() })) - stream.AddHandler(session.NewModuleHandler("events.show LIMIT?", "events.show(\\s\\d+)?", + mod.AddHandler(session.NewModuleHandler("events.show LIMIT?", "events.show(\\s\\d+)?", "Show events stream.", func(args []string) error { limit := -1 @@ -67,10 +67,10 @@ func NewEventsStream(s *session.Session) *EventsStream { arg := str.Trim(args[0]) limit, _ = strconv.Atoi(arg) } - return stream.Show(limit) + return mod.Show(limit) })) - stream.AddHandler(session.NewModuleHandler("events.waitfor TAG TIMEOUT?", `events.waitfor ([^\s]+)([\s\d]*)`, + mod.AddHandler(session.NewModuleHandler("events.waitfor TAG TIMEOUT?", `events.waitfor ([^\s]+)([\s\d]*)`, "Wait for an event with the given tag either forever or for a timeout in seconds.", func(args []string) error { tag := args[0] @@ -85,163 +85,163 @@ func NewEventsStream(s *session.Session) *EventsStream { timeout = n } } - return stream.startWaitingFor(tag, timeout) + return mod.startWaitingFor(tag, timeout) })) - stream.AddHandler(session.NewModuleHandler("events.ignore FILTER", "events.ignore ([^\\s]+)", + mod.AddHandler(session.NewModuleHandler("events.ignore FILTER", "events.ignore ([^\\s]+)", "Events with an identifier matching this filter will not be shown (use multiple times to add more filters).", func(args []string) error { - return stream.ignoreList.Add(args[0]) + return mod.ignoreList.Add(args[0]) })) - stream.AddHandler(session.NewModuleHandler("events.include FILTER", "events.include ([^\\s]+)", + mod.AddHandler(session.NewModuleHandler("events.include FILTER", "events.include ([^\\s]+)", "Used to remove filters passed with the events.ignore command.", func(args []string) error { - return stream.ignoreList.Remove(args[0]) + return mod.ignoreList.Remove(args[0]) })) - stream.AddHandler(session.NewModuleHandler("events.filters", "", + mod.AddHandler(session.NewModuleHandler("events.filters", "", "Print the list of filters used to ignore events.", func(args []string) error { - if stream.ignoreList.Empty() { + if mod.ignoreList.Empty() { fmt.Printf("Ignore filters list is empty.\n") } else { - stream.ignoreList.RLock() - defer stream.ignoreList.RUnlock() + mod.ignoreList.RLock() + defer mod.ignoreList.RUnlock() - for _, filter := range stream.ignoreList.Filters() { + for _, filter := range mod.ignoreList.Filters() { fmt.Printf(" '%s'\n", string(filter)) } } return nil })) - stream.AddHandler(session.NewModuleHandler("events.clear", "", + mod.AddHandler(session.NewModuleHandler("events.clear", "", "Clear events stream.", func(args []string) error { - stream.Session.Events.Clear() + mod.Session.Events.Clear() return nil })) - stream.AddParam(session.NewStringParameter("events.stream.output", + mod.AddParam(session.NewStringParameter("events.stream.output", "", "", "If not empty, events will be written to this file instead of the standard output.")) - stream.AddParam(session.NewBoolParameter("events.stream.output.rotate", + mod.AddParam(session.NewBoolParameter("events.stream.output.rotate", "true", "If true will enable log rotation.")) - stream.AddParam(session.NewBoolParameter("events.stream.output.rotate.compress", + mod.AddParam(session.NewBoolParameter("events.stream.output.rotate.compress", "true", "If true will enable log rotation compression.")) - stream.AddParam(session.NewStringParameter("events.stream.output.rotate.how", + mod.AddParam(session.NewStringParameter("events.stream.output.rotate.how", "size", "(size|time)", "Rotate by 'size' or 'time'.")) - stream.AddParam(session.NewStringParameter("events.stream.output.rotate.format", + mod.AddParam(session.NewStringParameter("events.stream.output.rotate.format", "2006-01-02 15:04:05", "", "Datetime format to use for log rotation file names.")) - stream.AddParam(session.NewDecimalParameter("events.stream.output.rotate.when", + mod.AddParam(session.NewDecimalParameter("events.stream.output.rotate.when", "10", "File size (in MB) or time duration (in seconds) for log rotation.")) - stream.AddParam(session.NewBoolParameter("events.stream.http.request.dump", + mod.AddParam(session.NewBoolParameter("events.stream.http.request.dump", "false", "If true all HTTP requests will be dumped.")) - stream.AddParam(session.NewBoolParameter("events.stream.http.response.dump", + mod.AddParam(session.NewBoolParameter("events.stream.http.response.dump", "false", "If true all HTTP responses will be dumped.")) - return stream + return mod } -func (s EventsStream) Name() string { +func (mod EventsStream) Name() string { return "events.stream" } -func (s EventsStream) Description() string { +func (mod EventsStream) Description() string { return "Print events as a continuous stream." } -func (s EventsStream) Author() string { +func (mod EventsStream) Author() string { return "Simone Margaritelli " } -func (s *EventsStream) Configure() (err error) { +func (mod *EventsStream) Configure() (err error) { var output string - if err, output = s.StringParam("events.stream.output"); err == nil { + if err, output = mod.StringParam("events.stream.output"); err == nil { if output == "" { - s.output = os.Stdout - } else if s.outputName, err = fs.Expand(output); err == nil { - s.output, err = os.OpenFile(s.outputName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + mod.output = os.Stdout + } else if mod.outputName, err = fs.Expand(output); err == nil { + mod.output, err = os.OpenFile(mod.outputName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) } } - if err, s.rotation.Enabled = s.BoolParam("events.stream.output.rotate"); err != nil { + if err, mod.rotation.Enabled = mod.BoolParam("events.stream.output.rotate"); err != nil { return err - } else if err, s.rotation.Compress = s.BoolParam("events.stream.output.rotate.compress"); err != nil { + } else if err, mod.rotation.Compress = mod.BoolParam("events.stream.output.rotate.compress"); err != nil { return err - } else if err, s.rotation.Format = s.StringParam("events.stream.output.rotate.format"); err != nil { + } else if err, mod.rotation.Format = mod.StringParam("events.stream.output.rotate.format"); err != nil { return err - } else if err, s.rotation.How = s.StringParam("events.stream.output.rotate.how"); err != nil { + } else if err, mod.rotation.How = mod.StringParam("events.stream.output.rotate.how"); err != nil { return err - } else if err, s.rotation.Period = s.DecParam("events.stream.output.rotate.when"); err != nil { + } else if err, mod.rotation.Period = mod.DecParam("events.stream.output.rotate.when"); err != nil { return err } - if err, s.dumpHttpReqs = s.BoolParam("events.stream.http.request.dump"); err != nil { + if err, mod.dumpHttpReqs = mod.BoolParam("events.stream.http.request.dump"); err != nil { return err - } else if err, s.dumpHttpResp = s.BoolParam("events.stream.http.response.dump"); err != nil { + } else if err, mod.dumpHttpResp = mod.BoolParam("events.stream.http.response.dump"); err != nil { return err } return err } -func (s *EventsStream) Start() error { - if err := s.Configure(); err != nil { +func (mod *EventsStream) Start() error { + if err := mod.Configure(); err != nil { return err } - return s.SetRunning(true, func() { - s.eventListener = s.Session.Events.Listen() - defer s.Session.Events.Unlisten(s.eventListener) + return mod.SetRunning(true, func() { + mod.eventListener = mod.Session.Events.Listen() + defer mod.Session.Events.Unlisten(mod.eventListener) for { var e session.Event select { - case e = <-s.eventListener: - if e.Tag == s.waitFor { - s.waitFor = "" - s.waitChan <- &e + case e = <-mod.eventListener: + if e.Tag == mod.waitFor { + mod.waitFor = "" + mod.waitChan <- &e } - if !s.ignoreList.Ignored(e) { - s.View(e, true) + if !mod.ignoreList.Ignored(e) { + mod.View(e, true) } - case <-s.quit: + case <-mod.quit: return } } }) } -func (s *EventsStream) Show(limit int) error { - events := s.Session.Events.Sorted() +func (mod *EventsStream) Show(limit int) error { + events := mod.Session.Events.Sorted() num := len(events) selected := []session.Event{} for i := range events { e := events[num-1-i] - if !s.ignoreList.Ignored(e) { + if !mod.ignoreList.Ignored(e) { selected = append(selected, e) if len(selected) == limit { break @@ -252,43 +252,43 @@ func (s *EventsStream) Show(limit int) error { if numSelected := len(selected); numSelected > 0 { fmt.Println() for i := range selected { - s.View(selected[numSelected-1-i], false) + mod.View(selected[numSelected-1-i], false) } - s.Session.Refresh() + mod.Session.Refresh() } return nil } -func (s *EventsStream) startWaitingFor(tag string, timeout int) error { +func (mod *EventsStream) startWaitingFor(tag string, timeout int) error { if timeout == 0 { - s.Info("waiting for event %s ...", tui.Green(tag)) + mod.Info("waiting for event %s ...", tui.Green(tag)) } else { - s.Info("waiting for event %s for %d seconds ...", tui.Green(tag), timeout) + mod.Info("waiting for event %s for %d seconds ...", tui.Green(tag), timeout) go func() { time.Sleep(time.Duration(timeout) * time.Second) - s.waitFor = "" - s.waitChan <- nil + mod.waitFor = "" + mod.waitChan <- nil }() } - s.waitFor = tag - event := <-s.waitChan + mod.waitFor = tag + event := <-mod.waitChan if event == nil { return fmt.Errorf("'events.waitFor %s %d' timed out.", tag, timeout) } else { - s.Debug("got event: %v", event) + mod.Debug("got event: %v", event) } return nil } -func (s *EventsStream) Stop() error { - return s.SetRunning(false, func() { - s.quit <- true - if s.output != os.Stdout { - s.output.Close() +func (mod *EventsStream) Stop() error { + return mod.SetRunning(false, func() { + mod.quit <- true + if mod.output != os.Stdout { + mod.output.Close() } }) } diff --git a/modules/events_stream/events_view.go b/modules/events_stream/events_view.go index 2d44e3c9..8d13312e 100644 --- a/modules/events_stream/events_view.go +++ b/modules/events_stream/events_view.go @@ -20,15 +20,15 @@ import ( const eventTimeFormat = "15:04:05" -func (s *EventsStream) viewLogEvent(e session.Event) { - fmt.Fprintf(s.output, "[%s] [%s] [%s] %s\n", +func (mod *EventsStream) viewLogEvent(e session.Event) { + fmt.Fprintf(mod.output, "[%s] [%s] [%s] %s\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), e.Label(), e.Data.(session.LogMessage).Message) } -func (s *EventsStream) viewEndpointEvent(e session.Event) { +func (mod *EventsStream) viewEndpointEvent(e session.Event) { t := e.Data.(*network.Endpoint) vend := "" name := "" @@ -44,7 +44,7 @@ func (s *EventsStream) viewEndpointEvent(e session.Event) { } if e.Tag == "endpoint.new" { - fmt.Fprintf(s.output, "[%s] [%s] endpoint %s%s detected as %s%s.\n", + fmt.Fprintf(mod.output, "[%s] [%s] endpoint %s%s detected as %s%s.\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), tui.Bold(t.IpAddress), @@ -52,7 +52,7 @@ func (s *EventsStream) viewEndpointEvent(e session.Event) { tui.Green(t.HwAddress), tui.Dim(vend)) } else if e.Tag == "endpoint.lost" { - fmt.Fprintf(s.output, "[%s] [%s] endpoint %s%s %s%s lost.\n", + fmt.Fprintf(mod.output, "[%s] [%s] endpoint %s%s %s%s lost.\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), tui.Red(t.IpAddress), @@ -60,82 +60,82 @@ func (s *EventsStream) viewEndpointEvent(e session.Event) { tui.Green(t.HwAddress), tui.Dim(vend)) } else { - fmt.Fprintf(s.output, "[%s] [%s] %s\n", + fmt.Fprintf(mod.output, "[%s] [%s] %s\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), t.String()) } } -func (s *EventsStream) viewModuleEvent(e session.Event) { - fmt.Fprintf(s.output, "[%s] [%s] %s\n", +func (mod *EventsStream) viewModuleEvent(e session.Event) { + fmt.Fprintf(mod.output, "[%s] [%s] %s\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), e.Data) } -func (s *EventsStream) viewSnifferEvent(e session.Event) { +func (mod *EventsStream) viewSnifferEvent(e session.Event) { if strings.HasPrefix(e.Tag, "net.sniff.http.") { - s.viewHttpEvent(e) + mod.viewHttpEvent(e) } else { - fmt.Fprintf(s.output, "[%s] [%s] %s\n", + fmt.Fprintf(mod.output, "[%s] [%s] %s\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), e.Data.(net_sniff.SnifferEvent).Message) } } -func (s *EventsStream) viewSynScanEvent(e session.Event) { +func (mod *EventsStream) viewSynScanEvent(e session.Event) { se := e.Data.(syn_scan.SynScanEvent) - fmt.Fprintf(s.output, "[%s] [%s] found open port %d for %s\n", + fmt.Fprintf(mod.output, "[%s] [%s] found open port %d for %s\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), se.Port, tui.Bold(se.Address)) } -func (s *EventsStream) viewUpdateEvent(e session.Event) { +func (mod *EventsStream) viewUpdateEvent(e session.Event) { update := e.Data.(*github.RepositoryRelease) - fmt.Fprintf(s.output, "[%s] [%s] an update to version %s is available at %s\n", + fmt.Fprintf(mod.output, "[%s] [%s] an update to version %s is available at %s\n", e.Time.Format(eventTimeFormat), tui.Bold(tui.Yellow(e.Tag)), tui.Bold(*update.TagName), *update.HTMLURL) } -func (s *EventsStream) doRotation() { - if s.output == os.Stdout { +func (mod *EventsStream) doRotation() { + if mod.output == os.Stdout { return - } else if !s.rotation.Enabled { + } else if !mod.rotation.Enabled { return } - s.rotation.Lock() - defer s.rotation.Unlock() + mod.rotation.Lock() + defer mod.rotation.Unlock() doRotate := false - if info, err := s.output.Stat(); err == nil { - if s.rotation.How == "size" { - doRotate = float64(info.Size()) >= float64(s.rotation.Period*1024*1024) - } else if s.rotation.How == "time" { - doRotate = info.ModTime().Unix()%int64(s.rotation.Period) == 0 + if info, err := mod.output.Stat(); err == nil { + if mod.rotation.How == "size" { + doRotate = float64(info.Size()) >= float64(mod.rotation.Period*1024*1024) + } else if mod.rotation.How == "time" { + doRotate = info.ModTime().Unix()%int64(mod.rotation.Period) == 0 } } if doRotate { var err error - name := fmt.Sprintf("%s-%s", s.outputName, time.Now().Format(s.rotation.Format)) + name := fmt.Sprintf("%s-%s", mod.outputName, time.Now().Format(mod.rotation.Format)) - if err := s.output.Close(); err != nil { + if err := mod.output.Close(); err != nil { fmt.Printf("could not close log for rotation: %s\n", err) return } - if err := os.Rename(s.outputName, name); err != nil { - fmt.Printf("could not rename %s to %s: %s\n", s.outputName, name, err) - } else if s.rotation.Compress { + if err := os.Rename(mod.outputName, name); err != nil { + fmt.Printf("could not rename %s to %s: %s\n", mod.outputName, name, err) + } else if mod.rotation.Compress { zipName := fmt.Sprintf("%s.zip", name) if err = zip.Files(zipName, []string{name}); err != nil { fmt.Printf("error creating %s: %s", zipName, err) @@ -144,37 +144,37 @@ func (s *EventsStream) doRotation() { } } - s.output, err = os.OpenFile(s.outputName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + mod.output, err = os.OpenFile(mod.outputName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { - fmt.Printf("could not open %s: %s", s.outputName, err) + fmt.Printf("could not open %s: %s", mod.outputName, err) } } } -func (s *EventsStream) View(e session.Event, refresh bool) { +func (mod *EventsStream) View(e session.Event, refresh bool) { if e.Tag == "sys.log" { - s.viewLogEvent(e) + mod.viewLogEvent(e) } else if strings.HasPrefix(e.Tag, "endpoint.") { - s.viewEndpointEvent(e) + mod.viewEndpointEvent(e) } else if strings.HasPrefix(e.Tag, "wifi.") { - s.viewWiFiEvent(e) + mod.viewWiFiEvent(e) } else if strings.HasPrefix(e.Tag, "ble.") { - s.viewBLEEvent(e) + mod.viewBLEEvent(e) } else if strings.HasPrefix(e.Tag, "mod.") { - s.viewModuleEvent(e) + mod.viewModuleEvent(e) } else if strings.HasPrefix(e.Tag, "net.sniff.") { - s.viewSnifferEvent(e) + mod.viewSnifferEvent(e) } else if e.Tag == "syn.scan" { - s.viewSynScanEvent(e) + mod.viewSynScanEvent(e) } else if e.Tag == "update.available" { - s.viewUpdateEvent(e) + mod.viewUpdateEvent(e) } else { - fmt.Fprintf(s.output, "[%s] [%s] %v\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), e) + fmt.Fprintf(mod.output, "[%s] [%s] %v\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), e) } - if refresh && s.output == os.Stdout { - s.Session.Refresh() + if refresh && mod.output == os.Stdout { + mod.Session.Refresh() } - s.doRotation() + mod.doRotation() } diff --git a/modules/events_stream/events_view_ble.go b/modules/events_stream/events_view_ble.go index d630549d..e59a49a4 100644 --- a/modules/events_stream/events_view_ble.go +++ b/modules/events_stream/events_view_ble.go @@ -12,7 +12,7 @@ import ( "github.com/evilsocket/islazy/tui" ) -func (s *EventsStream) viewBLEEvent(e session.Event) { +func (mod *EventsStream) viewBLEEvent(e session.Event) { if e.Tag == "ble.device.new" { dev := e.Data.(*network.BLEDevice) name := dev.Device.Name() @@ -24,7 +24,7 @@ func (s *EventsStream) viewBLEEvent(e session.Event) { vend = fmt.Sprintf(" (%s)", tui.Yellow(vend)) } - fmt.Fprintf(s.output, "[%s] [%s] new BLE device%s detected as %s%s %s.\n", + fmt.Fprintf(mod.output, "[%s] [%s] new BLE device%s detected as %s%s %s.\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), name, @@ -42,7 +42,7 @@ func (s *EventsStream) viewBLEEvent(e session.Event) { vend = fmt.Sprintf(" (%s)", tui.Yellow(vend)) } - fmt.Fprintf(s.output, "[%s] [%s] BLE device%s %s%s lost.\n", + fmt.Fprintf(mod.output, "[%s] [%s] BLE device%s %s%s lost.\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), name, diff --git a/modules/events_stream/events_view_ble_unsupported.go b/modules/events_stream/events_view_ble_unsupported.go index e4329d03..f2a72ffb 100644 --- a/modules/events_stream/events_view_ble_unsupported.go +++ b/modules/events_stream/events_view_ble_unsupported.go @@ -6,6 +6,6 @@ import ( "github.com/bettercap/bettercap/session" ) -func (s *EventsStream) viewBLEEvent(e session.Event) { +func (mod *EventsStream) viewBLEEvent(e session.Event) { } diff --git a/modules/events_stream/events_view_http.go b/modules/events_stream/events_view_http.go index dc529202..a421fe6a 100644 --- a/modules/events_stream/events_view_http.go +++ b/modules/events_stream/events_view_http.go @@ -20,8 +20,8 @@ var ( reJsonKey = regexp.MustCompile(`("[^"]+"):`) ) -func (s *EventsStream) shouldDumpHttpRequest(req net_sniff.HTTPRequest) bool { - if s.dumpHttpReqs { +func (mod *EventsStream) shouldDumpHttpRequest(req net_sniff.HTTPRequest) bool { + if mod.dumpHttpReqs { // dump all return true } else if req.Method != "GET" { @@ -38,8 +38,8 @@ func (s *EventsStream) shouldDumpHttpRequest(req net_sniff.HTTPRequest) bool { return false } -func (s *EventsStream) shouldDumpHttpResponse(res net_sniff.HTTPResponse) bool { - if s.dumpHttpResp { +func (mod *EventsStream) shouldDumpHttpResponse(res net_sniff.HTTPResponse) bool { + if mod.dumpHttpResp { return true } else if strings.Contains(res.ContentType, "text/plain") { return true @@ -58,7 +58,7 @@ func (s *EventsStream) shouldDumpHttpResponse(res net_sniff.HTTPResponse) bool { return false } -func (s *EventsStream) dumpForm(body []byte) string { +func (mod *EventsStream) dumpForm(body []byte) string { form := []string{} for _, v := range strings.Split(string(body), "&") { if strings.Contains(v, "=") { @@ -81,23 +81,23 @@ func (s *EventsStream) dumpForm(body []byte) string { return "\n" + strings.Join(form, "&") + "\n" } -func (s *EventsStream) dumpText(body []byte) string { +func (mod *EventsStream) dumpText(body []byte) string { return "\n" + tui.Bold(tui.Red(string(body))) + "\n" } -func (s *EventsStream) dumpGZIP(body []byte) string { +func (mod *EventsStream) dumpGZIP(body []byte) string { buffer := bytes.NewBuffer(body) uncompressed := bytes.Buffer{} reader, err := gzip.NewReader(buffer) if err != nil { - return s.dumpRaw(body) + return mod.dumpRaw(body) } else if _, err = uncompressed.ReadFrom(reader); err != nil { - return s.dumpRaw(body) + return mod.dumpRaw(body) } - return s.dumpRaw(uncompressed.Bytes()) + return mod.dumpRaw(uncompressed.Bytes()) } -func (s *EventsStream) dumpJSON(body []byte) string { +func (mod *EventsStream) dumpJSON(body []byte) string { var buf bytes.Buffer var pretty string @@ -110,25 +110,25 @@ func (s *EventsStream) dumpJSON(body []byte) string { return "\n" + reJsonKey.ReplaceAllString(pretty, tui.Green(`$1:`)) + "\n" } -func (s *EventsStream) dumpXML(body []byte) string { +func (mod *EventsStream) dumpXML(body []byte) string { // TODO: indent xml return "\n" + string(body) + "\n" } -func (s *EventsStream) dumpRaw(body []byte) string { +func (mod *EventsStream) dumpRaw(body []byte) string { return "\n" + hex.Dump(body) + "\n" } -func (s *EventsStream) viewHttpRequest(e session.Event) { +func (mod *EventsStream) viewHttpRequest(e session.Event) { se := e.Data.(net_sniff.SnifferEvent) req := se.Data.(net_sniff.HTTPRequest) - fmt.Fprintf(s.output, "[%s] [%s] %s\n", + fmt.Fprintf(mod.output, "[%s] [%s] %s\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), se.Message) - if s.shouldDumpHttpRequest(req) { + if mod.shouldDumpHttpRequest(req) { dump := fmt.Sprintf("%s %s %s\n", tui.Bold(req.Method), req.URL, tui.Dim(req.Proto)) dump += fmt.Sprintf("%s: %s\n", tui.Blue("Host"), tui.Yellow(req.Host)) for name, values := range req.Headers { @@ -139,34 +139,34 @@ func (s *EventsStream) viewHttpRequest(e session.Event) { if req.Body != nil { if req.IsType("application/x-www-form-urlencoded") { - dump += s.dumpForm(req.Body) + dump += mod.dumpForm(req.Body) } else if req.IsType("text/plain") { - dump += s.dumpText(req.Body) + dump += mod.dumpText(req.Body) } else if req.IsType("text/xml") { - dump += s.dumpXML(req.Body) + dump += mod.dumpXML(req.Body) } else if req.IsType("gzip") { - dump += s.dumpGZIP(req.Body) + dump += mod.dumpGZIP(req.Body) } else if req.IsType("application/json") { - dump += s.dumpJSON(req.Body) + dump += mod.dumpJSON(req.Body) } else { - dump += s.dumpRaw(req.Body) + dump += mod.dumpRaw(req.Body) } } - fmt.Fprintf(s.output, "\n%s\n", dump) + fmt.Fprintf(mod.output, "\n%s\n", dump) } } -func (s *EventsStream) viewHttpResponse(e session.Event) { +func (mod *EventsStream) viewHttpResponse(e session.Event) { se := e.Data.(net_sniff.SnifferEvent) res := se.Data.(net_sniff.HTTPResponse) - fmt.Fprintf(s.output, "[%s] [%s] %s\n", + fmt.Fprintf(mod.output, "[%s] [%s] %s\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), se.Message) - if s.shouldDumpHttpResponse(res) { + if mod.shouldDumpHttpResponse(res) { dump := fmt.Sprintf("%s %s\n", tui.Dim(res.Protocol), res.Status) for name, values := range res.Headers { for _, value := range values { @@ -177,22 +177,22 @@ func (s *EventsStream) viewHttpResponse(e session.Event) { if res.Body != nil { // TODO: add more interesting response types if res.IsType("text/plain") { - dump += s.dumpText(res.Body) + dump += mod.dumpText(res.Body) } else if res.IsType("application/json") { - dump += s.dumpJSON(res.Body) + dump += mod.dumpJSON(res.Body) } else if res.IsType("text/xml") { - dump += s.dumpXML(res.Body) + dump += mod.dumpXML(res.Body) } } - fmt.Fprintf(s.output, "\n%s\n", dump) + fmt.Fprintf(mod.output, "\n%s\n", dump) } } -func (s *EventsStream) viewHttpEvent(e session.Event) { +func (mod *EventsStream) viewHttpEvent(e session.Event) { if e.Tag == "net.sniff.http.request" { - s.viewHttpRequest(e) + mod.viewHttpRequest(e) } else if e.Tag == "net.sniff.http.response" { - s.viewHttpResponse(e) + mod.viewHttpResponse(e) } } diff --git a/modules/events_stream/events_view_wifi.go b/modules/events_stream/events_view_wifi.go index 6cab951d..1e2c0013 100644 --- a/modules/events_stream/events_view_wifi.go +++ b/modules/events_stream/events_view_wifi.go @@ -11,7 +11,7 @@ import ( "github.com/evilsocket/islazy/tui" ) -func (s *EventsStream) viewWiFiApEvent(e session.Event) { +func (mod *EventsStream) viewWiFiApEvent(e session.Event) { ap := e.Data.(*network.AccessPoint) vend := "" if ap.Vendor != "" { @@ -23,7 +23,7 @@ func (s *EventsStream) viewWiFiApEvent(e session.Event) { } if e.Tag == "wifi.ap.new" { - fmt.Fprintf(s.output, "[%s] [%s] wifi access point %s%s detected as %s%s.\n", + fmt.Fprintf(mod.output, "[%s] [%s] wifi access point %s%s detected as %s%s.\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), tui.Bold(ap.ESSID()), @@ -31,21 +31,21 @@ func (s *EventsStream) viewWiFiApEvent(e session.Event) { tui.Green(ap.BSSID()), tui.Dim(vend)) } else if e.Tag == "wifi.ap.lost" { - fmt.Fprintf(s.output, "[%s] [%s] wifi access point %s (%s) lost.\n", + fmt.Fprintf(mod.output, "[%s] [%s] wifi access point %s (%s) lost.\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), tui.Red(ap.ESSID()), ap.BSSID()) } else { - fmt.Fprintf(s.output, "[%s] [%s] %s\n", + fmt.Fprintf(mod.output, "[%s] [%s] %s\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), ap.String()) } } -func (s *EventsStream) viewWiFiClientProbeEvent(e session.Event) { - probe := e.Data.(wifi.WiFiProbeEvent) +func (mod *EventsStream) viewWiFiClientProbeEvent(e session.Event) { + probe := e.Data.(wifi.ProbeEvent) desc := "" if probe.FromAlias != "" { desc = fmt.Sprintf(" (%s)", probe.FromAlias) @@ -57,7 +57,7 @@ func (s *EventsStream) viewWiFiClientProbeEvent(e session.Event) { rssi = fmt.Sprintf(" (%d dBm)", probe.RSSI) } - fmt.Fprintf(s.output, "[%s] [%s] station %s%s is probing for SSID %s%s\n", + fmt.Fprintf(mod.output, "[%s] [%s] station %s%s is probing for SSID %s%s\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), probe.FromAddr.String(), @@ -66,14 +66,14 @@ func (s *EventsStream) viewWiFiClientProbeEvent(e session.Event) { tui.Yellow(rssi)) } -func (s *EventsStream) viewWiFiHandshakeEvent(e session.Event) { - hand := e.Data.(wifi.WiFiHandshakeEvent) +func (mod *EventsStream) viewWiFiHandshakeEvent(e session.Event) { + hand := e.Data.(wifi.HandshakeEvent) from := hand.Station.String() to := hand.AP.String() what := "handshake" - if ap, found := s.Session.WiFi.Get(hand.AP.String()); found { + if ap, found := mod.Session.WiFi.Get(hand.AP.String()); found { to = fmt.Sprintf("%s (%s)", tui.Bold(ap.ESSID()), tui.Dim(ap.BSSID())) what = fmt.Sprintf("%s handshake", ap.Encryption) } @@ -82,7 +82,7 @@ func (s *EventsStream) viewWiFiHandshakeEvent(e session.Event) { what = "RSN PMKID" } - fmt.Fprintf(s.output, "[%s] [%s] captured %s -> %s %s to %s\n", + fmt.Fprintf(mod.output, "[%s] [%s] captured %s -> %s %s to %s\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), from, @@ -91,20 +91,20 @@ func (s *EventsStream) viewWiFiHandshakeEvent(e session.Event) { hand.File) } -func (s *EventsStream) viewWiFiClientEvent(e session.Event) { - ce := e.Data.(wifi.WiFiClientEvent) +func (mod *EventsStream) viewWiFiClientEvent(e session.Event) { + ce := e.Data.(wifi.ClientEvent) - ce.Client.Alias = s.Session.Lan.GetAlias(ce.Client.BSSID()) + ce.Client.Alias = mod.Session.Lan.GetAlias(ce.Client.BSSID()) if e.Tag == "wifi.client.new" { - fmt.Fprintf(s.output, "[%s] [%s] new station %s detected for %s (%s)\n", + fmt.Fprintf(mod.output, "[%s] [%s] new station %s detected for %s (%s)\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), ce.Client.String(), tui.Bold(ce.AP.ESSID()), tui.Dim(ce.AP.BSSID())) } else if e.Tag == "wifi.client.lost" { - fmt.Fprintf(s.output, "[%s] [%s] station %s disconnected from %s (%s)\n", + fmt.Fprintf(mod.output, "[%s] [%s] station %s disconnected from %s (%s)\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), ce.Client.String(), @@ -113,16 +113,16 @@ func (s *EventsStream) viewWiFiClientEvent(e session.Event) { } } -func (s *EventsStream) viewWiFiEvent(e session.Event) { +func (mod *EventsStream) viewWiFiEvent(e session.Event) { if strings.HasPrefix(e.Tag, "wifi.ap.") { - s.viewWiFiApEvent(e) + mod.viewWiFiApEvent(e) } else if e.Tag == "wifi.client.probe" { - s.viewWiFiClientProbeEvent(e) + mod.viewWiFiClientProbeEvent(e) } else if e.Tag == "wifi.client.handshake" { - s.viewWiFiHandshakeEvent(e) + mod.viewWiFiHandshakeEvent(e) } else if e.Tag == "wifi.client.new" || e.Tag == "wifi.client.lost" { - s.viewWiFiClientEvent(e) + mod.viewWiFiClientEvent(e) } else { - fmt.Fprintf(s.output, "[%s] [%s] %v\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), e) + fmt.Fprintf(mod.output, "[%s] [%s] %v\n", e.Time.Format(eventTimeFormat), tui.Green(e.Tag), e) } } diff --git a/modules/gps/gps.go b/modules/gps/gps.go index e468c042..35a8eff6 100644 --- a/modules/gps/gps.go +++ b/modules/gps/gps.go @@ -22,78 +22,78 @@ type GPS struct { } func NewGPS(s *session.Session) *GPS { - gps := &GPS{ + mod := &GPS{ SessionModule: session.NewSessionModule("gps", s), serialPort: "/dev/ttyUSB0", baudRate: 19200, } - gps.AddParam(session.NewStringParameter("gps.device", - gps.serialPort, + mod.AddParam(session.NewStringParameter("gps.device", + mod.serialPort, "", "Serial device of the GPS hardware.")) - gps.AddParam(session.NewIntParameter("gps.baudrate", - fmt.Sprintf("%d", gps.baudRate), + mod.AddParam(session.NewIntParameter("gps.baudrate", + fmt.Sprintf("%d", mod.baudRate), "Baud rate of the GPS serial device.")) - gps.AddHandler(session.NewModuleHandler("gps on", "", + mod.AddHandler(session.NewModuleHandler("gps on", "", "Start acquiring from the GPS hardware.", func(args []string) error { - return gps.Start() + return mod.Start() })) - gps.AddHandler(session.NewModuleHandler("gps off", "", + mod.AddHandler(session.NewModuleHandler("gps off", "", "Stop acquiring from the GPS hardware.", func(args []string) error { - return gps.Stop() + return mod.Stop() })) - gps.AddHandler(session.NewModuleHandler("gps.show", "", + mod.AddHandler(session.NewModuleHandler("gps.show", "", "Show the last coordinates returned by the GPS hardware.", func(args []string) error { - return gps.Show() + return mod.Show() })) - return gps + return mod } -func (gps *GPS) Name() string { +func (mod *GPS) Name() string { return "gps" } -func (gps *GPS) Description() string { +func (mod *GPS) Description() string { return "A module talking with GPS hardware on a serial interface." } -func (gps *GPS) Author() string { +func (mod *GPS) Author() string { return "Simone Margaritelli " } -func (gps *GPS) Configure() (err error) { - if gps.Running() { +func (mod *GPS) Configure() (err error) { + if mod.Running() { return session.ErrAlreadyStarted - } else if err, gps.serialPort = gps.StringParam("gps.device"); err != nil { + } else if err, mod.serialPort = mod.StringParam("gps.device"); err != nil { return err - } else if err, gps.baudRate = gps.IntParam("gps.baudrate"); err != nil { + } else if err, mod.baudRate = mod.IntParam("gps.baudrate"); err != nil { return err } - gps.serial, err = serial.OpenPort(&serial.Config{ - Name: gps.serialPort, - Baud: gps.baudRate, + mod.serial, err = serial.OpenPort(&serial.Config{ + Name: mod.serialPort, + Baud: mod.baudRate, ReadTimeout: time.Second * 1, }) return } -func (gps *GPS) readLine() (line string, err error) { +func (mod *GPS) readLine() (line string, err error) { var n int b := make([]byte, 1) for { - if n, err = gps.serial.Read(b); err != nil { + if n, err = mod.serial.Read(b); err != nil { return } else if n == 1 { if b[0] == '\n' { @@ -105,48 +105,48 @@ func (gps *GPS) readLine() (line string, err error) { } } -func (gps *GPS) Show() error { +func (mod *GPS) Show() error { fmt.Printf("latitude:%f longitude:%f quality:%s satellites:%d altitude:%f\n", - gps.Session.GPS.Latitude, - gps.Session.GPS.Longitude, - gps.Session.GPS.FixQuality, - gps.Session.GPS.NumSatellites, - gps.Session.GPS.Altitude) + mod.Session.GPS.Latitude, + mod.Session.GPS.Longitude, + mod.Session.GPS.FixQuality, + mod.Session.GPS.NumSatellites, + mod.Session.GPS.Altitude) - gps.Session.Refresh() + mod.Session.Refresh() return nil } -func (gps *GPS) Start() error { - if err := gps.Configure(); err != nil { +func (mod *GPS) Start() error { + if err := mod.Configure(); err != nil { return err } - return gps.SetRunning(true, func() { + return mod.SetRunning(true, func() { - defer gps.serial.Close() + defer mod.serial.Close() - for gps.Running() { - if line, err := gps.readLine(); err == nil { + for mod.Running() { + if line, err := mod.readLine(); err == nil { if s, err := nmea.Parse(line); err == nil { // http://aprs.gids.nl/nmea/#gga if m, ok := s.(nmea.GNGGA); ok { - gps.Session.GPS = m + mod.Session.GPS = m } } else { - gps.Debug("error parsing line '%s': %s", line, err) + mod.Debug("error parsing line '%s': %s", line, err) } } else if err != io.EOF { - gps.Warning("error while reading serial port: %s", err) + mod.Warning("error while reading serial port: %s", err) } } }) } -func (gps *GPS) Stop() error { - return gps.SetRunning(false, func() { +func (mod *GPS) Stop() error { + return mod.SetRunning(false, func() { // let the read fail and exit - gps.serial.Close() + mod.serial.Close() }) } diff --git a/modules/http_proxy/http_proxy.go b/modules/http_proxy/http_proxy.go index a6cd4803..90007b9f 100644 --- a/modules/http_proxy/http_proxy.go +++ b/modules/http_proxy/http_proxy.go @@ -10,66 +10,66 @@ type HttpProxy struct { } func NewHttpProxy(s *session.Session) *HttpProxy { - p := &HttpProxy{ + mod := &HttpProxy{ SessionModule: session.NewSessionModule("http.proxy", s), proxy: NewHTTPProxy(s), } - p.AddParam(session.NewIntParameter("http.port", + mod.AddParam(session.NewIntParameter("http.port", "80", "HTTP port to redirect when the proxy is activated.")) - p.AddParam(session.NewStringParameter("http.proxy.address", + mod.AddParam(session.NewStringParameter("http.proxy.address", session.ParamIfaceAddress, session.IPv4Validator, "Address to bind the HTTP proxy to.")) - p.AddParam(session.NewIntParameter("http.proxy.port", + mod.AddParam(session.NewIntParameter("http.proxy.port", "8080", "Port to bind the HTTP proxy to.")) - p.AddParam(session.NewStringParameter("http.proxy.script", + mod.AddParam(session.NewStringParameter("http.proxy.script", "", "", "Path of a proxy JS script.")) - p.AddParam(session.NewStringParameter("http.proxy.injectjs", + mod.AddParam(session.NewStringParameter("http.proxy.injectjs", "", "", "URL, path or javascript code to inject into every HTML page.")) - p.AddParam(session.NewBoolParameter("http.proxy.sslstrip", + mod.AddParam(session.NewBoolParameter("http.proxy.sslstrip", "false", "Enable or disable SSL stripping.")) - p.AddHandler(session.NewModuleHandler("http.proxy on", "", + mod.AddHandler(session.NewModuleHandler("http.proxy on", "", "Start HTTP proxy.", func(args []string) error { - return p.Start() + return mod.Start() })) - p.AddHandler(session.NewModuleHandler("http.proxy off", "", + mod.AddHandler(session.NewModuleHandler("http.proxy off", "", "Stop HTTP proxy.", func(args []string) error { - return p.Stop() + return mod.Stop() })) - return p + return mod } -func (p *HttpProxy) Name() string { +func (mod *HttpProxy) Name() string { return "http.proxy" } -func (p *HttpProxy) Description() string { +func (mod *HttpProxy) Description() string { return "A full featured HTTP proxy that can be used to inject malicious contents into webpages, all HTTP traffic will be redirected to it." } -func (p *HttpProxy) Author() string { +func (mod *HttpProxy) Author() string { return "Simone Margaritelli " } -func (p *HttpProxy) Configure() error { +func (mod *HttpProxy) Configure() error { var err error var address string var proxyPort int @@ -78,37 +78,37 @@ func (p *HttpProxy) Configure() error { var stripSSL bool var jsToInject string - if p.Running() { + if mod.Running() { return session.ErrAlreadyStarted - } else if err, address = p.StringParam("http.proxy.address"); err != nil { + } else if err, address = mod.StringParam("http.proxy.address"); err != nil { return err - } else if err, proxyPort = p.IntParam("http.proxy.port"); err != nil { + } else if err, proxyPort = mod.IntParam("http.proxy.port"); err != nil { return err - } else if err, httpPort = p.IntParam("http.port"); err != nil { + } else if err, httpPort = mod.IntParam("http.port"); err != nil { return err - } else if err, scriptPath = p.StringParam("http.proxy.script"); err != nil { + } else if err, scriptPath = mod.StringParam("http.proxy.script"); err != nil { return err - } else if err, stripSSL = p.BoolParam("http.proxy.sslstrip"); err != nil { + } else if err, stripSSL = mod.BoolParam("http.proxy.sslstrip"); err != nil { return err - } else if err, jsToInject = p.StringParam("http.proxy.injectjs"); err != nil { + } else if err, jsToInject = mod.StringParam("http.proxy.injectjs"); err != nil { return err } - return p.proxy.Configure(address, proxyPort, httpPort, scriptPath, jsToInject, stripSSL) + return mod.proxy.Configure(address, proxyPort, httpPort, scriptPath, jsToInject, stripSSL) } -func (p *HttpProxy) Start() error { - if err := p.Configure(); err != nil { +func (mod *HttpProxy) Start() error { + if err := mod.Configure(); err != nil { return err } - return p.SetRunning(true, func() { - p.proxy.Start() + return mod.SetRunning(true, func() { + mod.proxy.Start() }) } -func (p *HttpProxy) Stop() error { - return p.SetRunning(false, func() { - p.proxy.Stop() +func (mod *HttpProxy) Stop() error { + return mod.SetRunning(false, func() { + mod.proxy.Stop() }) } diff --git a/modules/http_server/http_server.go b/modules/http_server/http_server.go index 2bb7fea5..f03aff73 100644 --- a/modules/http_server/http_server.go +++ b/modules/http_server/http_server.go @@ -18,63 +18,63 @@ type HttpServer struct { } func NewHttpServer(s *session.Session) *HttpServer { - httpd := &HttpServer{ + mod := &HttpServer{ SessionModule: session.NewSessionModule("http.server", s), server: &http.Server{}, } - httpd.AddParam(session.NewStringParameter("http.server.path", + mod.AddParam(session.NewStringParameter("http.server.path", ".", "", "Server folder.")) - httpd.AddParam(session.NewStringParameter("http.server.address", + mod.AddParam(session.NewStringParameter("http.server.address", session.ParamIfaceAddress, session.IPv4Validator, "Address to bind the http server to.")) - httpd.AddParam(session.NewIntParameter("http.server.port", + mod.AddParam(session.NewIntParameter("http.server.port", "80", "Port to bind the http server to.")) - httpd.AddHandler(session.NewModuleHandler("http.server on", "", + mod.AddHandler(session.NewModuleHandler("http.server on", "", "Start httpd server.", func(args []string) error { - return httpd.Start() + return mod.Start() })) - httpd.AddHandler(session.NewModuleHandler("http.server off", "", + mod.AddHandler(session.NewModuleHandler("http.server off", "", "Stop httpd server.", func(args []string) error { - return httpd.Stop() + return mod.Stop() })) - return httpd + return mod } -func (httpd *HttpServer) Name() string { +func (mod *HttpServer) Name() string { return "http.server" } -func (httpd *HttpServer) Description() string { +func (mod *HttpServer) Description() string { return "A simple HTTP server, to be used to serve files and scripts across the network." } -func (httpd *HttpServer) Author() string { +func (mod *HttpServer) Author() string { return "Simone Margaritelli " } -func (httpd *HttpServer) Configure() error { +func (mod *HttpServer) Configure() error { var err error var path string var address string var port int - if httpd.Running() { + if mod.Running() { return session.ErrAlreadyStarted } - if err, path = httpd.StringParam("http.server.path"); err != nil { + if err, path = mod.StringParam("http.server.path"); err != nil { return err } @@ -82,43 +82,43 @@ func (httpd *HttpServer) Configure() error { fileServer := http.FileServer(http.Dir(path)) router.HandleFunc("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - httpd.Info("%s %s %s%s", tui.Bold(strings.Split(r.RemoteAddr, ":")[0]), r.Method, r.Host, r.URL.Path) + mod.Info("%s %s %s%s", tui.Bold(strings.Split(r.RemoteAddr, ":")[0]), r.Method, r.Host, r.URL.Path) fileServer.ServeHTTP(w, r) })) - httpd.server.Handler = router + mod.server.Handler = router - if err, address = httpd.StringParam("http.server.address"); err != nil { + if err, address = mod.StringParam("http.server.address"); err != nil { return err } - if err, port = httpd.IntParam("http.server.port"); err != nil { + if err, port = mod.IntParam("http.server.port"); err != nil { return err } - httpd.server.Addr = fmt.Sprintf("%s:%d", address, port) + mod.server.Addr = fmt.Sprintf("%s:%d", address, port) return nil } -func (httpd *HttpServer) Start() error { - if err := httpd.Configure(); err != nil { +func (mod *HttpServer) Start() error { + if err := mod.Configure(); err != nil { return err } - return httpd.SetRunning(true, func() { + return mod.SetRunning(true, func() { var err error - httpd.Info("starting on http://%s", httpd.server.Addr) - if err = httpd.server.ListenAndServe(); err != nil && err != http.ErrServerClosed { + mod.Info("starting on http://%s", mod.server.Addr) + if err = mod.server.ListenAndServe(); err != nil && err != http.ErrServerClosed { panic(err) } }) } -func (httpd *HttpServer) Stop() error { - return httpd.SetRunning(false, func() { +func (mod *HttpServer) Stop() error { + return mod.SetRunning(false, func() { ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() - httpd.server.Shutdown(ctx) + mod.server.Shutdown(ctx) }) } diff --git a/modules/https_proxy/https_proxy.go b/modules/https_proxy/https_proxy.go index eaa1c97a..25a74d08 100644 --- a/modules/https_proxy/https_proxy.go +++ b/modules/https_proxy/https_proxy.go @@ -14,78 +14,78 @@ type HttpsProxy struct { } func NewHttpsProxy(s *session.Session) *HttpsProxy { - p := &HttpsProxy{ + mod := &HttpsProxy{ SessionModule: session.NewSessionModule("https.proxy", s), proxy: http_proxy.NewHTTPProxy(s), } - p.AddParam(session.NewIntParameter("https.port", + mod.AddParam(session.NewIntParameter("https.port", "443", "HTTPS port to redirect when the proxy is activated.")) - p.AddParam(session.NewStringParameter("https.proxy.address", + mod.AddParam(session.NewStringParameter("https.proxy.address", session.ParamIfaceAddress, session.IPv4Validator, "Address to bind the HTTPS proxy to.")) - p.AddParam(session.NewIntParameter("https.proxy.port", + mod.AddParam(session.NewIntParameter("https.proxy.port", "8083", "Port to bind the HTTPS proxy to.")) - p.AddParam(session.NewBoolParameter("https.proxy.sslstrip", + mod.AddParam(session.NewBoolParameter("https.proxy.sslstrip", "false", "Enable or disable SSL stripping.")) - p.AddParam(session.NewStringParameter("https.proxy.injectjs", + mod.AddParam(session.NewStringParameter("https.proxy.injectjs", "", "", "URL, path or javascript code to inject into every HTML page.")) - p.AddParam(session.NewStringParameter("https.proxy.certificate", + mod.AddParam(session.NewStringParameter("https.proxy.certificate", "~/.bettercap-ca.cert.pem", "", "HTTPS proxy certification authority TLS certificate file.")) - p.AddParam(session.NewStringParameter("https.proxy.key", + mod.AddParam(session.NewStringParameter("https.proxy.key", "~/.bettercap-ca.key.pem", "", "HTTPS proxy certification authority TLS key file.")) - tls.CertConfigToModule("https.proxy", &p.SessionModule, tls.DefaultSpoofConfig) + tls.CertConfigToModule("https.proxy", &mod.SessionModule, tls.DefaultSpoofConfig) - p.AddParam(session.NewStringParameter("https.proxy.script", + mod.AddParam(session.NewStringParameter("https.proxy.script", "", "", "Path of a proxy JS script.")) - p.AddHandler(session.NewModuleHandler("https.proxy on", "", + mod.AddHandler(session.NewModuleHandler("https.proxy on", "", "Start HTTPS proxy.", func(args []string) error { - return p.Start() + return mod.Start() })) - p.AddHandler(session.NewModuleHandler("https.proxy off", "", + mod.AddHandler(session.NewModuleHandler("https.proxy off", "", "Stop HTTPS proxy.", func(args []string) error { - return p.Stop() + return mod.Stop() })) - return p + return mod } -func (p *HttpsProxy) Name() string { +func (mod *HttpsProxy) Name() string { return "https.proxy" } -func (p *HttpsProxy) Description() string { +func (mod *HttpsProxy) Description() string { return "A full featured HTTPS proxy that can be used to inject malicious contents into webpages, all HTTPS traffic will be redirected to it." } -func (p *HttpsProxy) Author() string { +func (mod *HttpsProxy) Author() string { return "Simone Margaritelli " } -func (p *HttpsProxy) Configure() error { +func (mod *HttpsProxy) Configure() error { var err error var address string var proxyPort int @@ -96,62 +96,62 @@ func (p *HttpsProxy) Configure() error { var stripSSL bool var jsToInject string - if p.Running() { + if mod.Running() { return session.ErrAlreadyStarted - } else if err, address = p.StringParam("https.proxy.address"); err != nil { + } else if err, address = mod.StringParam("https.proxy.address"); err != nil { return err - } else if err, proxyPort = p.IntParam("https.proxy.port"); err != nil { + } else if err, proxyPort = mod.IntParam("https.proxy.port"); err != nil { return err - } else if err, httpPort = p.IntParam("https.port"); err != nil { + } else if err, httpPort = mod.IntParam("https.port"); err != nil { return err - } else if err, stripSSL = p.BoolParam("https.proxy.sslstrip"); err != nil { + } else if err, stripSSL = mod.BoolParam("https.proxy.sslstrip"); err != nil { return err - } else if err, certFile = p.StringParam("https.proxy.certificate"); err != nil { + } else if err, certFile = mod.StringParam("https.proxy.certificate"); err != nil { return err } else if certFile, err = fs.Expand(certFile); err != nil { return err - } else if err, keyFile = p.StringParam("https.proxy.key"); err != nil { + } else if err, keyFile = mod.StringParam("https.proxy.key"); err != nil { return err } else if keyFile, err = fs.Expand(keyFile); err != nil { return err - } else if err, scriptPath = p.StringParam("https.proxy.script"); err != nil { + } else if err, scriptPath = mod.StringParam("https.proxy.script"); err != nil { return err - } else if err, jsToInject = p.StringParam("https.proxy.injectjs"); err != nil { + } else if err, jsToInject = mod.StringParam("https.proxy.injectjs"); err != nil { return err } if !fs.Exists(certFile) || !fs.Exists(keyFile) { - err, cfg := tls.CertConfigFromModule("https.proxy", p.SessionModule) + err, cfg := tls.CertConfigFromModule("https.proxy", mod.SessionModule) if err != nil { return err } - p.Debug("%+v", cfg) - p.Info("generating proxy certification authority TLS key to %s", keyFile) - p.Info("generating proxy certification authority TLS certificate to %s", certFile) + mod.Debug("%+v", cfg) + mod.Info("generating proxy certification authority TLS key to %s", keyFile) + mod.Info("generating proxy certification authority TLS certificate to %s", certFile) if err := tls.Generate(cfg, certFile, keyFile); err != nil { return err } } else { - p.Info("loading proxy certification authority TLS key from %s", keyFile) - p.Info("loading proxy certification authority TLS certificate from %s", certFile) + mod.Info("loading proxy certification authority TLS key from %s", keyFile) + mod.Info("loading proxy certification authority TLS certificate from %s", certFile) } - return p.proxy.ConfigureTLS(address, proxyPort, httpPort, scriptPath, certFile, keyFile, jsToInject, stripSSL) + return mod.proxy.ConfigureTLS(address, proxyPort, httpPort, scriptPath, certFile, keyFile, jsToInject, stripSSL) } -func (p *HttpsProxy) Start() error { - if err := p.Configure(); err != nil { +func (mod *HttpsProxy) Start() error { + if err := mod.Configure(); err != nil { return err } - return p.SetRunning(true, func() { - p.proxy.Start() + return mod.SetRunning(true, func() { + mod.proxy.Start() }) } -func (p *HttpsProxy) Stop() error { - return p.SetRunning(false, func() { - p.proxy.Stop() +func (mod *HttpsProxy) Stop() error { + return mod.SetRunning(false, func() { + mod.proxy.Stop() }) } diff --git a/modules/https_server/https_server.go b/modules/https_server/https_server.go index d4dc479f..0ed5e96a 100644 --- a/modules/https_server/https_server.go +++ b/modules/https_server/https_server.go @@ -22,65 +22,65 @@ type HttpsServer struct { } func NewHttpsServer(s *session.Session) *HttpsServer { - httpd := &HttpsServer{ + mod := &HttpsServer{ SessionModule: session.NewSessionModule("https.server", s), server: &http.Server{}, } - httpd.AddParam(session.NewStringParameter("https.server.path", + mod.AddParam(session.NewStringParameter("https.server.path", ".", "", "Server folder.")) - httpd.AddParam(session.NewStringParameter("https.server.address", + mod.AddParam(session.NewStringParameter("https.server.address", session.ParamIfaceAddress, session.IPv4Validator, "Address to bind the http server to.")) - httpd.AddParam(session.NewIntParameter("https.server.port", + mod.AddParam(session.NewIntParameter("https.server.port", "443", "Port to bind the http server to.")) - httpd.AddParam(session.NewStringParameter("https.server.certificate", + mod.AddParam(session.NewStringParameter("https.server.certificate", "~/.bettercap-https.cert.pem", "", "TLS certificate file (will be auto generated if filled but not existing).")) - httpd.AddParam(session.NewStringParameter("https.server.key", + mod.AddParam(session.NewStringParameter("https.server.key", "~/.bettercap-https.key.pem", "", "TLS key file (will be auto generated if filled but not existing).")) - tls.CertConfigToModule("https.server", &httpd.SessionModule, tls.DefaultLegitConfig) + tls.CertConfigToModule("https.server", &mod.SessionModule, tls.DefaultLegitConfig) - httpd.AddHandler(session.NewModuleHandler("https.server on", "", + mod.AddHandler(session.NewModuleHandler("https.server on", "", "Start https server.", func(args []string) error { - return httpd.Start() + return mod.Start() })) - httpd.AddHandler(session.NewModuleHandler("https.server off", "", + mod.AddHandler(session.NewModuleHandler("https.server off", "", "Stop https server.", func(args []string) error { - return httpd.Stop() + return mod.Stop() })) - return httpd + return mod } -func (httpd *HttpsServer) Name() string { +func (mod *HttpsServer) Name() string { return "https.server" } -func (httpd *HttpsServer) Description() string { +func (mod *HttpsServer) Description() string { return "A simple HTTPS server, to be used to serve files and scripts across the network." } -func (httpd *HttpsServer) Author() string { +func (mod *HttpsServer) Author() string { return "Simone Margaritelli " } -func (httpd *HttpsServer) Configure() error { +func (mod *HttpsServer) Configure() error { var err error var path string var address string @@ -88,11 +88,11 @@ func (httpd *HttpsServer) Configure() error { var certFile string var keyFile string - if httpd.Running() { + if mod.Running() { return session.ErrAlreadyStarted } - if err, path = httpd.StringParam("https.server.path"); err != nil { + if err, path = mod.StringParam("https.server.path"); err != nil { return err } @@ -100,74 +100,74 @@ func (httpd *HttpsServer) Configure() error { fileServer := http.FileServer(http.Dir(path)) router.HandleFunc("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - httpd.Info("%s %s %s%s", tui.Bold(strings.Split(r.RemoteAddr, ":")[0]), r.Method, r.Host, r.URL.Path) + mod.Info("%s %s %s%s", tui.Bold(strings.Split(r.RemoteAddr, ":")[0]), r.Method, r.Host, r.URL.Path) fileServer.ServeHTTP(w, r) })) - httpd.server.Handler = router + mod.server.Handler = router - if err, address = httpd.StringParam("https.server.address"); err != nil { + if err, address = mod.StringParam("https.server.address"); err != nil { return err } - if err, port = httpd.IntParam("https.server.port"); err != nil { + if err, port = mod.IntParam("https.server.port"); err != nil { return err } - httpd.server.Addr = fmt.Sprintf("%s:%d", address, port) + mod.server.Addr = fmt.Sprintf("%s:%d", address, port) - if err, certFile = httpd.StringParam("https.server.certificate"); err != nil { + if err, certFile = mod.StringParam("https.server.certificate"); err != nil { return err } else if certFile, err = fs.Expand(certFile); err != nil { return err } - if err, keyFile = httpd.StringParam("https.server.key"); err != nil { + if err, keyFile = mod.StringParam("https.server.key"); err != nil { return err } else if keyFile, err = fs.Expand(keyFile); err != nil { return err } if !fs.Exists(certFile) || !fs.Exists(keyFile) { - err, cfg := tls.CertConfigFromModule("https.server", httpd.SessionModule) + err, cfg := tls.CertConfigFromModule("https.server", mod.SessionModule) if err != nil { return err } - httpd.Debug("%+v", cfg) - httpd.Info("generating server TLS key to %s", keyFile) - httpd.Info("generating server TLS certificate to %s", certFile) + mod.Debug("%+v", cfg) + mod.Info("generating server TLS key to %s", keyFile) + mod.Info("generating server TLS certificate to %s", certFile) if err := tls.Generate(cfg, certFile, keyFile); err != nil { return err } } else { - httpd.Info("loading server TLS key from %s", keyFile) - httpd.Info("loading server TLS certificate from %s", certFile) + mod.Info("loading server TLS key from %s", keyFile) + mod.Info("loading server TLS certificate from %s", certFile) } - httpd.certFile = certFile - httpd.keyFile = keyFile + mod.certFile = certFile + mod.keyFile = keyFile return nil } -func (httpd *HttpsServer) Start() error { - if err := httpd.Configure(); err != nil { +func (mod *HttpsServer) Start() error { + if err := mod.Configure(); err != nil { return err } - return httpd.SetRunning(true, func() { - httpd.Info("starting on https://%s", httpd.server.Addr) - if err := httpd.server.ListenAndServeTLS(httpd.certFile, httpd.keyFile); err != nil && err != http.ErrServerClosed { + return mod.SetRunning(true, func() { + mod.Info("starting on https://%s", mod.server.Addr) + if err := mod.server.ListenAndServeTLS(mod.certFile, mod.keyFile); err != nil && err != http.ErrServerClosed { panic(err) } }) } -func (httpd *HttpsServer) Stop() error { - return httpd.SetRunning(false, func() { +func (mod *HttpsServer) Stop() error { + return mod.SetRunning(false, func() { ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() - httpd.server.Shutdown(ctx) + mod.server.Shutdown(ctx) }) } diff --git a/modules/mac_changer/mac_changer.go b/modules/mac_changer/mac_changer.go index 3fafdbbd..b0a80acf 100644 --- a/modules/mac_changer/mac_changer.go +++ b/modules/mac_changer/mac_changer.go @@ -21,106 +21,106 @@ type MacChanger struct { } func NewMacChanger(s *session.Session) *MacChanger { - mc := &MacChanger{ + mod := &MacChanger{ SessionModule: session.NewSessionModule("mac.changer", s), } - mc.AddParam(session.NewStringParameter("mac.changer.iface", + mod.AddParam(session.NewStringParameter("mac.changer.iface", session.ParamIfaceName, "", "Name of the interface to use.")) - mc.AddParam(session.NewStringParameter("mac.changer.address", + mod.AddParam(session.NewStringParameter("mac.changer.address", session.ParamRandomMAC, "[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}", "Hardware address to apply to the interface.")) - mc.AddHandler(session.NewModuleHandler("mac.changer on", "", + mod.AddHandler(session.NewModuleHandler("mac.changer on", "", "Start mac changer module.", func(args []string) error { - return mc.Start() + return mod.Start() })) - mc.AddHandler(session.NewModuleHandler("mac.changer off", "", + mod.AddHandler(session.NewModuleHandler("mac.changer off", "", "Stop mac changer module and restore original mac address.", func(args []string) error { - return mc.Stop() + return mod.Stop() })) - return mc + return mod } -func (mc *MacChanger) Name() string { +func (mod *MacChanger) Name() string { return "mac.changer" } -func (mc *MacChanger) Description() string { +func (mod *MacChanger) Description() string { return "Change active interface mac address." } -func (mc *MacChanger) Author() string { +func (mod *MacChanger) Author() string { return "Simone Margaritelli " } -func (mc *MacChanger) Configure() (err error) { +func (mod *MacChanger) Configure() (err error) { var changeTo string - if err, mc.iface = mc.StringParam("mac.changer.iface"); err != nil { + if err, mod.iface = mod.StringParam("mac.changer.iface"); err != nil { return err - } else if err, changeTo = mc.StringParam("mac.changer.address"); err != nil { + } else if err, changeTo = mod.StringParam("mac.changer.address"); err != nil { return err } changeTo = network.NormalizeMac(changeTo) - if mc.fakeMac, err = net.ParseMAC(changeTo); err != nil { + if mod.fakeMac, err = net.ParseMAC(changeTo); err != nil { return err } - mc.originalMac = mc.Session.Interface.HW + mod.originalMac = mod.Session.Interface.HW return nil } -func (mc *MacChanger) setMac(mac net.HardwareAddr) error { +func (mod *MacChanger) setMac(mac net.HardwareAddr) error { var args []string os := runtime.GOOS if strings.Contains(os, "bsd") || os == "darwin" { - args = []string{mc.iface, "ether", mac.String()} + args = []string{mod.iface, "ether", mac.String()} } else if os == "linux" || os == "android" { - args = []string{mc.iface, "hw", "ether", mac.String()} + args = []string{mod.iface, "hw", "ether", mac.String()} } else { return fmt.Errorf("OS %s is not supported by mac.changer module.", os) } _, err := core.Exec("ifconfig", args) if err == nil { - mc.Session.Interface.HW = mac + mod.Session.Interface.HW = mac } return err } -func (mc *MacChanger) Start() error { - if mc.Running() { +func (mod *MacChanger) Start() error { + if mod.Running() { return session.ErrAlreadyStarted - } else if err := mc.Configure(); err != nil { + } else if err := mod.Configure(); err != nil { return err - } else if err := mc.setMac(mc.fakeMac); err != nil { + } else if err := mod.setMac(mod.fakeMac); err != nil { return err } - return mc.SetRunning(true, func() { - mc.Info("interface mac address set to %s", tui.Bold(mc.fakeMac.String())) + return mod.SetRunning(true, func() { + mod.Info("interface mac address set to %s", tui.Bold(mod.fakeMac.String())) }) } -func (mc *MacChanger) Stop() error { - return mc.SetRunning(false, func() { - if err := mc.setMac(mc.originalMac); err == nil { - mc.Info("interface mac address restored to %s", tui.Bold(mc.originalMac.String())) +func (mod *MacChanger) Stop() error { + return mod.SetRunning(false, func() { + if err := mod.setMac(mod.originalMac); err == nil { + mod.Info("interface mac address restored to %s", tui.Bold(mod.originalMac.String())) } else { - mc.Error("error while restoring mac address: %s", err) + mod.Error("error while restoring mac address: %s", err) } }) } diff --git a/modules/modules.go b/modules/modules.go index 858f1b3c..5f61b462 100644 --- a/modules/modules.go +++ b/modules/modules.go @@ -7,7 +7,7 @@ import ( "github.com/bettercap/bettercap/modules/ble" "github.com/bettercap/bettercap/modules/caplets" "github.com/bettercap/bettercap/modules/dhcp6_spoof" - "github.com/bettercap/bettercap/modules/discovery" + "github.com/bettercap/bettercap/modules/net_recon" "github.com/bettercap/bettercap/modules/dns_spoof" "github.com/bettercap/bettercap/modules/events_stream" "github.com/bettercap/bettercap/modules/gps" @@ -19,7 +19,7 @@ import ( "github.com/bettercap/bettercap/modules/mysql_server" "github.com/bettercap/bettercap/modules/net_sniff" "github.com/bettercap/bettercap/modules/packet_proxy" - "github.com/bettercap/bettercap/modules/prober" + "github.com/bettercap/bettercap/modules/net_probe" "github.com/bettercap/bettercap/modules/syn_scan" "github.com/bettercap/bettercap/modules/tcp_proxy" "github.com/bettercap/bettercap/modules/ticker" @@ -37,7 +37,7 @@ func LoadModules(sess *session.Session) { sess.Register(ble.NewBLERecon(sess)) sess.Register(caplets.NewCapletsModule(sess)) sess.Register(dhcp6_spoof.NewDHCP6Spoofer(sess)) - sess.Register(discovery.NewDiscovery(sess)) + sess.Register(net_recon.NewDiscovery(sess)) sess.Register(dns_spoof.NewDNSSpoofer(sess)) sess.Register(events_stream.NewEventsStream(sess)) sess.Register(gps.NewGPS(sess)) @@ -49,7 +49,7 @@ func LoadModules(sess *session.Session) { sess.Register(mysql_server.NewMySQLServer(sess)) sess.Register(net_sniff.NewSniffer(sess)) sess.Register(packet_proxy.NewPacketProxy(sess)) - sess.Register(prober.NewProber(sess)) + sess.Register(net_probe.NewProber(sess)) sess.Register(syn_scan.NewSynScanner(sess)) sess.Register(tcp_proxy.NewTcpProxy(sess)) sess.Register(ticker.NewTicker(sess)) diff --git a/modules/mysql_server/mysql_server.go b/modules/mysql_server/mysql_server.go index bf94d811..eb145c9b 100644 --- a/modules/mysql_server/mysql_server.go +++ b/modules/mysql_server/mysql_server.go @@ -23,90 +23,89 @@ type MySQLServer struct { } func NewMySQLServer(s *session.Session) *MySQLServer { - - mysql := &MySQLServer{ + mod := &MySQLServer{ SessionModule: session.NewSessionModule("mysql.server", s), } - mysql.AddParam(session.NewStringParameter("mysql.server.infile", + mod.AddParam(session.NewStringParameter("mysql.server.infile", "/etc/passwd", "", "File you want to read. UNC paths are also supported.")) - mysql.AddParam(session.NewStringParameter("mysql.server.outfile", + mod.AddParam(session.NewStringParameter("mysql.server.outfile", "", "", "If filled, the INFILE buffer will be saved to this path instead of being logged.")) - mysql.AddParam(session.NewStringParameter("mysql.server.address", + mod.AddParam(session.NewStringParameter("mysql.server.address", session.ParamIfaceAddress, session.IPv4Validator, "Address to bind the mysql server to.")) - mysql.AddParam(session.NewIntParameter("mysql.server.port", + mod.AddParam(session.NewIntParameter("mysql.server.port", "3306", "Port to bind the mysql server to.")) - mysql.AddHandler(session.NewModuleHandler("mysql.server on", "", + mod.AddHandler(session.NewModuleHandler("mysql.server on", "", "Start mysql server.", func(args []string) error { - return mysql.Start() + return mod.Start() })) - mysql.AddHandler(session.NewModuleHandler("mysql.server off", "", + mod.AddHandler(session.NewModuleHandler("mysql.server off", "", "Stop mysql server.", func(args []string) error { - return mysql.Stop() + return mod.Stop() })) - return mysql + return mod } -func (mysql *MySQLServer) Name() string { +func (mod *MySQLServer) Name() string { return "mysql.server" } -func (mysql *MySQLServer) Description() string { +func (mod *MySQLServer) Description() string { return "A simple Rogue MySQL server, to be used to exploit LOCAL INFILE and read arbitrary files from the client." } -func (mysql *MySQLServer) Author() string { +func (mod *MySQLServer) Author() string { return "Bernardo Rodrigues (https://twitter.com/bernardomr)" } -func (mysql *MySQLServer) Configure() error { +func (mod *MySQLServer) Configure() error { var err error var address string var port int - if mysql.Running() { + if mod.Running() { return session.ErrAlreadyStarted - } else if err, mysql.infile = mysql.StringParam("mysql.server.infile"); err != nil { + } else if err, mod.infile = mod.StringParam("mysql.server.infile"); err != nil { return err - } else if err, mysql.outfile = mysql.StringParam("mysql.server.outfile"); err != nil { + } else if err, mod.outfile = mod.StringParam("mysql.server.outfile"); err != nil { return err - } else if err, address = mysql.StringParam("mysql.server.address"); err != nil { + } else if err, address = mod.StringParam("mysql.server.address"); err != nil { return err - } else if err, port = mysql.IntParam("mysql.server.port"); err != nil { + } else if err, port = mod.IntParam("mysql.server.port"); err != nil { return err - } else if mysql.address, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", address, port)); err != nil { + } else if mod.address, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", address, port)); err != nil { return err - } else if mysql.listener, err = net.ListenTCP("tcp", mysql.address); err != nil { + } else if mod.listener, err = net.ListenTCP("tcp", mod.address); err != nil { return err } return nil } -func (mysql *MySQLServer) Start() error { - if err := mysql.Configure(); err != nil { +func (mod *MySQLServer) Start() error { + if err := mod.Configure(); err != nil { return err } - return mysql.SetRunning(true, func() { - mysql.Info("server starting on address %s", mysql.address) - for mysql.Running() { - if conn, err := mysql.listener.AcceptTCP(); err != nil { - mysql.Warning("error while accepting tcp connection: %s", err) + return mod.SetRunning(true, func() { + mod.Info("server starting on address %s", mod.address) + for mod.Running() { + if conn, err := mod.listener.AcceptTCP(); err != nil { + mod.Warning("error while accepting tcp connection: %s", err) continue } else { defer conn.Close() @@ -117,13 +116,13 @@ func (mysql *MySQLServer) Start() error { reader := bufio.NewReader(conn) read := 0 - mysql.Info("connection from %s", clientAddress) + mod.Info("connection from %s", clientAddress) if _, err := conn.Write(packets.MySQLGreeting); err != nil { - mysql.Warning("error while writing server greeting: %s", err) + mod.Warning("error while writing server greeting: %s", err) continue } else if read, err = reader.Read(readBuffer); err != nil { - mysql.Warning("error while reading client message: %s", err) + mod.Warning("error while reading client message: %s", err) continue } @@ -134,38 +133,38 @@ func (mysql *MySQLServer) Start() error { loadData := string(capabilities[8]) username := string(bytes.Split(readBuffer[36:], []byte{0})[0]) - mysql.Info("can use LOAD DATA LOCAL: %s", loadData) - mysql.Info("login request username: %s", tui.Bold(username)) + mod.Info("can use LOAD DATA LOCAL: %s", loadData) + mod.Info("login request username: %s", tui.Bold(username)) if _, err := conn.Write(packets.MySQLFirstResponseOK); err != nil { - mysql.Warning("error while writing server first response ok: %s", err) + mod.Warning("error while writing server first response ok: %s", err) continue } else if _, err := reader.Read(readBuffer); err != nil { - mysql.Warning("error while reading client message: %s", err) + mod.Warning("error while reading client message: %s", err) continue - } else if _, err := conn.Write(packets.MySQLGetFile(mysql.infile)); err != nil { - mysql.Warning("error while writing server get file request: %s", err) + } else if _, err := conn.Write(packets.MySQLGetFile(mod.infile)); err != nil { + mod.Warning("error while writing server get file request: %s", err) continue } else if read, err = reader.Read(readBuffer); err != nil { - mysql.Warning("error while readind buffer: %s", err) + mod.Warning("error while readind buffer: %s", err) continue } - if strings.HasPrefix(mysql.infile, "\\") { - mysql.Info("NTLM from '%s' relayed to %s", clientAddress, mysql.infile) + if strings.HasPrefix(mod.infile, "\\") { + mod.Info("NTLM from '%s' relayed to %s", clientAddress, mod.infile) } else if fileSize := read - 9; fileSize < 4 { - mysql.Warning("unpexpected buffer size %d", read) + mod.Warning("unpexpected buffer size %d", read) } else { - mysql.Info("read file ( %s ) is %d bytes", mysql.infile, fileSize) + mod.Info("read file ( %s ) is %d bytes", mod.infile, fileSize) fileData := readBuffer[4 : read-4] - if mysql.outfile == "" { - mysql.Info("\n%s", string(fileData)) + if mod.outfile == "" { + mod.Info("\n%s", string(fileData)) } else { - mysql.Info("saving to %s ...", mysql.outfile) - if err := ioutil.WriteFile(mysql.outfile, fileData, 0755); err != nil { - mysql.Warning("error while saving the file: %s", err) + mod.Info("saving to %s ...", mod.outfile) + if err := ioutil.WriteFile(mod.outfile, fileData, 0755); err != nil { + mod.Warning("error while saving the file: %s", err) } } } @@ -176,8 +175,8 @@ func (mysql *MySQLServer) Start() error { }) } -func (mysql *MySQLServer) Stop() error { - return mysql.SetRunning(false, func() { - defer mysql.listener.Close() +func (mod *MySQLServer) Stop() error { + return mod.SetRunning(false, func() { + defer mod.listener.Close() }) } diff --git a/modules/net_probe/net_probe.go b/modules/net_probe/net_probe.go new file mode 100644 index 00000000..c3df280c --- /dev/null +++ b/modules/net_probe/net_probe.go @@ -0,0 +1,156 @@ +package net_probe + +import ( + "sync" + "time" + + "github.com/bettercap/bettercap/network" + "github.com/bettercap/bettercap/session" + + "github.com/malfunkt/iprange" +) + +type Probes struct { + NBNS bool + MDNS bool + UPNP bool + WSD bool +} + +type Prober struct { + session.SessionModule + throttle int + probes Probes + waitGroup *sync.WaitGroup +} + +func NewProber(s *session.Session) *Prober { + mod := &Prober{ + SessionModule: session.NewSessionModule("net.probe", s), + waitGroup: &sync.WaitGroup{}, + } + + mod.AddParam(session.NewBoolParameter("net.probe.nbns", + "true", + "Enable NetBIOS name service discovery probes.")) + + mod.AddParam(session.NewBoolParameter("net.probe.mdns", + "true", + "Enable mDNS discovery probes.")) + + mod.AddParam(session.NewBoolParameter("net.probe.upnp", + "true", + "Enable UPNP discovery probes.")) + + mod.AddParam(session.NewBoolParameter("net.probe.wsd", + "true", + "Enable WSD discovery probes.")) + + mod.AddParam(session.NewIntParameter("net.probe.throttle", + "10", + "If greater than 0, probe packets will be throttled by this value in milliseconds.")) + + mod.AddHandler(session.NewModuleHandler("net.probe on", "", + "Start network hosts probing in background.", + func(args []string) error { + return mod.Start() + })) + + mod.AddHandler(session.NewModuleHandler("net.probe off", "", + "Stop network hosts probing in background.", + func(args []string) error { + return mod.Stop() + })) + + return mod +} + +func (mod Prober) Name() string { + return "net.probe" +} + +func (mod Prober) Description() string { + return "Keep probing for new hosts on the network by sending dummy UDP packets to every possible IP on the subnet." +} + +func (mod Prober) Author() string { + return "Simone Margaritelli " +} + +func (mod *Prober) Configure() error { + var err error + if err, mod.throttle = mod.IntParam("net.probe.throttle"); err != nil { + return err + } else if err, mod.probes.NBNS = mod.BoolParam("net.probe.nbns"); err != nil { + return err + } else if err, mod.probes.MDNS = mod.BoolParam("net.probe.mdns"); err != nil { + return err + } else if err, mod.probes.UPNP = mod.BoolParam("net.probe.upnp"); err != nil { + return err + } else if err, mod.probes.WSD = mod.BoolParam("net.probe.wsd"); err != nil { + return err + } else { + mod.Debug("Throttling packets of %d ms.", mod.throttle) + } + return nil +} + +func (mod *Prober) Start() error { + if err := mod.Configure(); err != nil { + return err + } + + return mod.SetRunning(true, func() { + mod.waitGroup.Add(1) + defer mod.waitGroup.Done() + + if mod.Session.Interface.IpAddress == network.MonitorModeAddress { + mod.Info("Interface is in monitor mode, skipping net.probe") + return + } + + list, err := iprange.Parse(mod.Session.Interface.CIDR()) + if err != nil { + mod.Fatal("%s", err) + } + + fromIP := mod.Session.Interface.IP + fromHW := mod.Session.Interface.HW + addresses := list.Expand() + throttle := time.Duration(mod.throttle) * time.Millisecond + + for mod.Running() { + if mod.probes.MDNS { + mod.sendProbeMDNS(fromIP, fromHW) + } + + if mod.probes.UPNP { + mod.sendProbeUPNP(fromIP, fromHW) + } + + if mod.probes.WSD { + mod.sendProbeWSD(fromIP, fromHW) + } + + for _, ip := range addresses { + if !mod.Running() { + return + } else if mod.Session.Skip(ip) { + mod.Debug("skipping address %s from probing.", ip) + continue + } else if mod.probes.NBNS { + mod.sendProbeNBNS(fromIP, fromHW, ip) + } + time.Sleep(throttle) + } + + time.Sleep(5 * time.Second) + } + }) +} + +func (mod *Prober) Stop() error { + return mod.SetRunning(false, func() { + mod.waitGroup.Wait() + }) +} diff --git a/modules/net_probe/net_probe_mdns.go b/modules/net_probe/net_probe_mdns.go new file mode 100644 index 00000000..ff330547 --- /dev/null +++ b/modules/net_probe/net_probe_mdns.go @@ -0,0 +1,19 @@ +package net_probe + +import ( + "net" + + "github.com/bettercap/bettercap/packets" +) + +func (mod *Prober) sendProbeMDNS(from net.IP, from_hw net.HardwareAddr) { + err, raw := packets.NewMDNSProbe(from, from_hw) + if err != nil { + mod.Error("error while sending mdns probe: %v", err) + return + } else if err := mod.Session.Queue.Send(raw); err != nil { + mod.Error("error sending mdns packet: %s", err) + } else { + mod.Debug("sent %d bytes of MDNS probe", len(raw)) + } +} diff --git a/modules/prober/net_probe_nbns.go b/modules/net_probe/net_probe_nbns.go similarity index 57% rename from modules/prober/net_probe_nbns.go rename to modules/net_probe/net_probe_nbns.go index f7d8206e..843e97ec 100644 --- a/modules/prober/net_probe_nbns.go +++ b/modules/net_probe/net_probe_nbns.go @@ -1,4 +1,4 @@ -package prober +package net_probe import ( "fmt" @@ -7,18 +7,18 @@ import ( "github.com/bettercap/bettercap/packets" ) -func (p *Prober) sendProbeNBNS(from net.IP, from_hw net.HardwareAddr, ip net.IP) { +func (mod *Prober) sendProbeNBNS(from net.IP, from_hw net.HardwareAddr, ip net.IP) { name := fmt.Sprintf("%s:%d", ip, packets.NBNSPort) if addr, err := net.ResolveUDPAddr("udp", name); err != nil { - p.Debug("could not resolve %s.", name) + mod.Debug("could not resolve %s.", name) } else if con, err := net.DialUDP("udp", nil, addr); err != nil { - p.Debug("could not dial %s.", name) + mod.Debug("could not dial %s.", name) } else { defer con.Close() if wrote, _ := con.Write(packets.NBNSRequest); wrote > 0 { - p.Session.Queue.TrackSent(uint64(wrote)) + mod.Session.Queue.TrackSent(uint64(wrote)) } else { - p.Session.Queue.TrackError() + mod.Session.Queue.TrackError() } } } diff --git a/modules/prober/net_probe_upnp.go b/modules/net_probe/net_probe_upnp.go similarity index 60% rename from modules/prober/net_probe_upnp.go rename to modules/net_probe/net_probe_upnp.go index 397b7422..d5188a4b 100644 --- a/modules/prober/net_probe_upnp.go +++ b/modules/net_probe/net_probe_upnp.go @@ -1,4 +1,4 @@ -package prober +package net_probe import ( "fmt" @@ -7,18 +7,18 @@ import ( "github.com/bettercap/bettercap/packets" ) -func (p *Prober) sendProbeUPNP(from net.IP, from_hw net.HardwareAddr) { +func (mod *Prober) sendProbeUPNP(from net.IP, from_hw net.HardwareAddr) { name := fmt.Sprintf("%s:%d", packets.UPNPDestIP, packets.UPNPPort) if addr, err := net.ResolveUDPAddr("udp", name); err != nil { - p.Debug("could not resolve %s.", name) + mod.Debug("could not resolve %s.", name) } else if con, err := net.DialUDP("udp", nil, addr); err != nil { - p.Debug("could not dial %s.", name) + mod.Debug("could not dial %s.", name) } else { defer con.Close() if wrote, _ := con.Write(packets.UPNPDiscoveryPayload); wrote > 0 { - p.Session.Queue.TrackSent(uint64(wrote)) + mod.Session.Queue.TrackSent(uint64(wrote)) } else { - p.Session.Queue.TrackError() + mod.Session.Queue.TrackError() } } diff --git a/modules/prober/net_probe_wsd.go b/modules/net_probe/net_probe_wsd.go similarity index 60% rename from modules/prober/net_probe_wsd.go rename to modules/net_probe/net_probe_wsd.go index b9fcf99a..bb363037 100644 --- a/modules/prober/net_probe_wsd.go +++ b/modules/net_probe/net_probe_wsd.go @@ -1,4 +1,4 @@ -package prober +package net_probe import ( "fmt" @@ -7,18 +7,18 @@ import ( "github.com/bettercap/bettercap/packets" ) -func (p *Prober) sendProbeWSD(from net.IP, from_hw net.HardwareAddr) { +func (mod *Prober) sendProbeWSD(from net.IP, from_hw net.HardwareAddr) { name := fmt.Sprintf("%s:%d", packets.WSDDestIP, packets.WSDPort) if addr, err := net.ResolveUDPAddr("udp", name); err != nil { - p.Debug("could not resolve %s.", name) + mod.Debug("could not resolve %s.", name) } else if con, err := net.DialUDP("udp", nil, addr); err != nil { - p.Debug("could not dial %s.", name) + mod.Debug("could not dial %s.", name) } else { defer con.Close() if wrote, _ := con.Write(packets.WSDDiscoveryPayload); wrote > 0 { - p.Session.Queue.TrackSent(uint64(wrote)) + mod.Session.Queue.TrackSent(uint64(wrote)) } else { - p.Session.Queue.TrackError() + mod.Session.Queue.TrackError() } } diff --git a/modules/discovery/net_recon.go b/modules/net_recon/net_recon.go similarity index 53% rename from modules/discovery/net_recon.go rename to modules/net_recon/net_recon.go index 3953a1fa..ba76f1af 100644 --- a/modules/discovery/net_recon.go +++ b/modules/net_recon/net_recon.go @@ -1,4 +1,4 @@ -package discovery +package net_recon import ( "github.com/bettercap/bettercap/modules/utils" @@ -14,105 +14,105 @@ type Discovery struct { } func NewDiscovery(s *session.Session) *Discovery { - d := &Discovery{ + mod := &Discovery{ SessionModule: session.NewSessionModule("net.recon", s), } - d.AddHandler(session.NewModuleHandler("net.recon on", "", + mod.AddHandler(session.NewModuleHandler("net.recon on", "", "Start network hosts discovery.", func(args []string) error { - return d.Start() + return mod.Start() })) - d.AddHandler(session.NewModuleHandler("net.recon off", "", + mod.AddHandler(session.NewModuleHandler("net.recon off", "", "Stop network hosts discovery.", func(args []string) error { - return d.Stop() + return mod.Stop() })) - d.AddParam(session.NewBoolParameter("net.show.meta", + mod.AddParam(session.NewBoolParameter("net.show.meta", "false", "If true, the net.show command will show all metadata collected about each endpoint.")) - d.AddHandler(session.NewModuleHandler("net.show", "", + mod.AddHandler(session.NewModuleHandler("net.show", "", "Show cache hosts list (default sorting by ip).", func(args []string) error { - return d.Show("") + return mod.Show("") })) - d.AddHandler(session.NewModuleHandler("net.show ADDRESS1, ADDRESS2", `net.show (.+)`, + mod.AddHandler(session.NewModuleHandler("net.show ADDRESS1, ADDRESS2", `net.show (.+)`, "Show information about a specific list of addresses (by IP or MAC).", func(args []string) error { - return d.Show(args[0]) + return mod.Show(args[0]) })) - d.AddHandler(session.NewModuleHandler("net.show.meta ADDRESS1, ADDRESS2", `net\.show\.meta (.+)`, + mod.AddHandler(session.NewModuleHandler("net.show.meta ADDRESS1, ADDRESS2", `net\.show\.meta (.+)`, "Show meta information about a specific list of addresses (by IP or MAC).", func(args []string) error { - return d.showMeta(args[0]) + return mod.showMeta(args[0]) })) - d.selector = utils.ViewSelectorFor(&d.SessionModule, "net.show", []string{"ip", "mac", "seen", "sent", "rcvd"}, + mod.selector = utils.ViewSelectorFor(&mod.SessionModule, "net.show", []string{"ip", "mac", "seen", "sent", "rcvd"}, "ip asc") - return d + return mod } -func (d Discovery) Name() string { +func (mod Discovery) Name() string { return "net.recon" } -func (d Discovery) Description() string { +func (mod Discovery) Description() string { return "Read periodically the ARP cache in order to monitor for new hosts on the network." } -func (d Discovery) Author() string { +func (mod Discovery) Author() string { return "Simone Margaritelli " } -func (d *Discovery) runDiff(cache network.ArpTable) { +func (mod *Discovery) runDiff(cache network.ArpTable) { // check for endpoints who disappeared var rem network.ArpTable = make(network.ArpTable) - d.Session.Lan.EachHost(func(mac string, e *network.Endpoint) { + mod.Session.Lan.EachHost(func(mac string, e *network.Endpoint) { if _, found := cache[mac]; !found { rem[mac] = e.IpAddress } }) for mac, ip := range rem { - d.Session.Lan.Remove(ip, mac) + mod.Session.Lan.Remove(ip, mac) } // now check for new friends ^_^ for ip, mac := range cache { - d.Session.Lan.AddIfNew(ip, mac) + mod.Session.Lan.AddIfNew(ip, mac) } } -func (d *Discovery) Configure() error { +func (mod *Discovery) Configure() error { return nil } -func (d *Discovery) Start() error { - if err := d.Configure(); err != nil { +func (mod *Discovery) Start() error { + if err := mod.Configure(); err != nil { return err } - return d.SetRunning(true, func() { + return mod.SetRunning(true, func() { every := time.Duration(1) * time.Second - iface := d.Session.Interface.Name() - for d.Running() { + iface := mod.Session.Interface.Name() + for mod.Running() { if table, err := network.ArpUpdate(iface); err != nil { - d.Error("%s", err) + mod.Error("%s", err) } else { - d.runDiff(table) + mod.runDiff(table) } time.Sleep(every) } }) } -func (d *Discovery) Stop() error { - return d.SetRunning(false, nil) +func (mod *Discovery) Stop() error { + return mod.SetRunning(false, nil) } diff --git a/modules/discovery/net_show.go b/modules/net_recon/net_show.go similarity index 63% rename from modules/discovery/net_show.go rename to modules/net_recon/net_show.go index 74d5d9d9..5815916b 100644 --- a/modules/discovery/net_show.go +++ b/modules/net_recon/net_show.go @@ -1,4 +1,4 @@ -package discovery +package net_recon import ( "fmt" @@ -32,13 +32,13 @@ func (p ProtoPairList) Len() int { return len(p) } func (p ProtoPairList) Less(i, j int) bool { return p[i].Hits < p[j].Hits } func (p ProtoPairList) Swap(i, j int) { p[i], p[j] = p[j], p[i] } -func (d *Discovery) getRow(e *network.Endpoint, withMeta bool) [][]string { - sinceStarted := time.Since(d.Session.StartedAt) +func (mod *Discovery) getRow(e *network.Endpoint, withMeta bool) [][]string { + sinceStarted := time.Since(mod.Session.StartedAt) sinceFirstSeen := time.Since(e.FirstSeen) addr := e.IpAddress mac := e.HwAddress - if d.Session.Lan.WasMissed(e.HwAddress) { + if mod.Session.Lan.WasMissed(e.HwAddress) { // if endpoint was not found in ARP at least once addr = tui.Dim(addr) mac = tui.Dim(mac) @@ -49,9 +49,9 @@ func (d *Discovery) getRow(e *network.Endpoint, withMeta bool) [][]string { } name := "" - if e == d.Session.Interface { + if e == mod.Session.Interface { name = e.Name() - } else if e == d.Session.Gateway { + } else if e == mod.Session.Gateway { name = "gateway" } else if e.Alias != "" { name = tui.Green(e.Alias) @@ -61,7 +61,7 @@ func (d *Discovery) getRow(e *network.Endpoint, withMeta bool) [][]string { var traffic *packets.Traffic var found bool - if traffic, found = d.Session.Queue.Traffic[e.IpAddress]; !found { + if traffic, found = mod.Session.Queue.Traffic[e.IpAddress]; !found { traffic = &packets.Traffic{} } @@ -111,40 +111,40 @@ func (d *Discovery) getRow(e *network.Endpoint, withMeta bool) [][]string { return rows } -func (d *Discovery) doFilter(target *network.Endpoint) bool { - if d.selector.Expression == nil { +func (mod *Discovery) doFilter(target *network.Endpoint) bool { + if mod.selector.Expression == nil { return true } - return d.selector.Expression.MatchString(target.IpAddress) || - d.selector.Expression.MatchString(target.Ip6Address) || - d.selector.Expression.MatchString(target.HwAddress) || - d.selector.Expression.MatchString(target.Hostname) || - d.selector.Expression.MatchString(target.Alias) || - d.selector.Expression.MatchString(target.Vendor) + return mod.selector.Expression.MatchString(target.IpAddress) || + mod.selector.Expression.MatchString(target.Ip6Address) || + mod.selector.Expression.MatchString(target.HwAddress) || + mod.selector.Expression.MatchString(target.Hostname) || + mod.selector.Expression.MatchString(target.Alias) || + mod.selector.Expression.MatchString(target.Vendor) } -func (d *Discovery) doSelection(arg string) (err error, targets []*network.Endpoint) { - if err = d.selector.Update(); err != nil { +func (mod *Discovery) doSelection(arg string) (err error, targets []*network.Endpoint) { + if err = mod.selector.Update(); err != nil { return } if arg != "" { - if targets, err = network.ParseEndpoints(arg, d.Session.Lan); err != nil { + if targets, err = network.ParseEndpoints(arg, mod.Session.Lan); err != nil { return } } else { - targets = d.Session.Lan.List() + targets = mod.Session.Lan.List() } filtered := []*network.Endpoint{} for _, target := range targets { - if d.doFilter(target) { + if mod.doFilter(target) { filtered = append(filtered, target) } } targets = filtered - switch d.selector.SortField { + switch mod.selector.SortField { case "ip": sort.Sort(ByIpSorter(targets)) case "mac": @@ -160,7 +160,7 @@ func (d *Discovery) doSelection(arg string) (err error, targets []*network.Endpo } // default is asc - if d.selector.Sort == "desc" { + if mod.selector.Sort == "desc" { // from https://github.com/golang/go/wiki/SliceTricks for i := len(targets)/2 - 1; i >= 0; i-- { opp := len(targets) - 1 - i @@ -168,8 +168,8 @@ func (d *Discovery) doSelection(arg string) (err error, targets []*network.Endpo } } - if d.selector.Limit > 0 { - limit := d.selector.Limit + if mod.selector.Limit > 0 { + limit := mod.selector.Limit max := len(targets) if limit > max { limit = max @@ -180,61 +180,61 @@ func (d *Discovery) doSelection(arg string) (err error, targets []*network.Endpo return } -func (d *Discovery) colNames(hasMeta bool) []string { +func (mod *Discovery) colNames(hasMeta bool) []string { colNames := []string{"IP", "MAC", "Name", "Vendor", "Sent", "Recvd", "Seen"} if hasMeta { colNames = append(colNames, "Meta") } - switch d.selector.SortField { + switch mod.selector.SortField { case "mac": - colNames[1] += " " + d.selector.SortSymbol + colNames[1] += " " + mod.selector.SortSymbol case "sent": - colNames[4] += " " + d.selector.SortSymbol + colNames[4] += " " + mod.selector.SortSymbol case "rcvd": - colNames[5] += " " + d.selector.SortSymbol + colNames[5] += " " + mod.selector.SortSymbol case "seen": - colNames[6] += " " + d.selector.SortSymbol + colNames[6] += " " + mod.selector.SortSymbol case "ip": - colNames[0] += " " + d.selector.SortSymbol + colNames[0] += " " + mod.selector.SortSymbol } return colNames } -func (d *Discovery) showStatusBar() { - d.Session.Queue.Stats.RLock() - defer d.Session.Queue.Stats.RUnlock() +func (mod *Discovery) showStatusBar() { + mod.Session.Queue.Stats.RLock() + defer mod.Session.Queue.Stats.RUnlock() parts := []string{ - fmt.Sprintf("%s %s", tui.Red("↑"), humanize.Bytes(d.Session.Queue.Stats.Sent)), - fmt.Sprintf("%s %s", tui.Green("↓"), humanize.Bytes(d.Session.Queue.Stats.Received)), - fmt.Sprintf("%d pkts", d.Session.Queue.Stats.PktReceived), + fmt.Sprintf("%s %s", tui.Red("↑"), humanize.Bytes(mod.Session.Queue.Stats.Sent)), + fmt.Sprintf("%s %s", tui.Green("↓"), humanize.Bytes(mod.Session.Queue.Stats.Received)), + fmt.Sprintf("%d pkts", mod.Session.Queue.Stats.PktReceived), } - if nErrors := d.Session.Queue.Stats.Errors; nErrors > 0 { + if nErrors := mod.Session.Queue.Stats.Errors; nErrors > 0 { parts = append(parts, fmt.Sprintf("%d errs", nErrors)) } fmt.Printf("\n%s\n\n", strings.Join(parts, " / ")) } -func (d *Discovery) Show(arg string) (err error) { +func (mod *Discovery) Show(arg string) (err error) { var targets []*network.Endpoint - if err, targets = d.doSelection(arg); err != nil { + if err, targets = mod.doSelection(arg); err != nil { return } pad := 1 - if d.Session.Interface.HwAddress == d.Session.Gateway.HwAddress { + if mod.Session.Interface.HwAddress == mod.Session.Gateway.HwAddress { pad = 0 - targets = append([]*network.Endpoint{d.Session.Interface}, targets...) + targets = append([]*network.Endpoint{mod.Session.Interface}, targets...) } else { - targets = append([]*network.Endpoint{d.Session.Interface, d.Session.Gateway}, targets...) + targets = append([]*network.Endpoint{mod.Session.Interface, mod.Session.Gateway}, targets...) } hasMeta := false - if err, showMeta := d.BoolParam("net.show.meta"); err != nil { + if err, showMeta := mod.BoolParam("net.show.meta"); err != nil { return err } else if showMeta { for _, t := range targets { @@ -245,12 +245,12 @@ func (d *Discovery) Show(arg string) (err error) { } } - colNames := d.colNames(hasMeta) + colNames := mod.colNames(hasMeta) padCols := make([]string, len(colNames)) rows := make([][]string, 0) for i, t := range targets { - rows = append(rows, d.getRow(t, hasMeta)...) + rows = append(rows, mod.getRow(t, hasMeta)...) if i == pad { rows = append(rows, padCols) } @@ -258,16 +258,16 @@ func (d *Discovery) Show(arg string) (err error) { tui.Table(os.Stdout, colNames, rows) - d.showStatusBar() + mod.showStatusBar() - d.Session.Refresh() + mod.Session.Refresh() return nil } -func (d *Discovery) showMeta(arg string) (err error) { +func (mod *Discovery) showMeta(arg string) (err error) { var targets []*network.Endpoint - if err, targets = d.doSelection(arg); err != nil { + if err, targets = mod.doSelection(arg); err != nil { return } @@ -303,7 +303,7 @@ func (d *Discovery) showMeta(arg string) (err error) { } if any { - d.Session.Refresh() + mod.Session.Refresh() } return nil diff --git a/modules/discovery/net_show_sort.go b/modules/net_recon/net_show_sort.go similarity index 99% rename from modules/discovery/net_show_sort.go rename to modules/net_recon/net_show_sort.go index 56f7efba..10ad08e5 100644 --- a/modules/discovery/net_show_sort.go +++ b/modules/net_recon/net_show_sort.go @@ -1,4 +1,4 @@ -package discovery +package net_recon import ( "github.com/bettercap/bettercap/network" diff --git a/modules/net_sniff/net_sniff.go b/modules/net_sniff/net_sniff.go index 2ab18c05..cbc4885e 100644 --- a/modules/net_sniff/net_sniff.go +++ b/modules/net_sniff/net_sniff.go @@ -24,133 +24,133 @@ type Sniffer struct { } func NewSniffer(s *session.Session) *Sniffer { - sniff := &Sniffer{ + mod := &Sniffer{ SessionModule: session.NewSessionModule("net.sniff", s), Stats: nil, } - sniff.AddParam(session.NewBoolParameter("net.sniff.verbose", + mod.AddParam(session.NewBoolParameter("net.sniff.verbose", "false", "If true, every captured and parsed packet will be sent to the events.stream for displaying, otherwise only the ones parsed at the application layer (sni, http, etc).")) - sniff.AddParam(session.NewBoolParameter("net.sniff.local", + mod.AddParam(session.NewBoolParameter("net.sniff.local", "false", "If true it will consider packets from/to this computer, otherwise it will skip them.")) - sniff.AddParam(session.NewStringParameter("net.sniff.filter", + mod.AddParam(session.NewStringParameter("net.sniff.filter", "not arp", "", "BPF filter for the sniffer.")) - sniff.AddParam(session.NewStringParameter("net.sniff.regexp", + mod.AddParam(session.NewStringParameter("net.sniff.regexp", "", "", "If set, only packets matching this regular expression will be considered.")) - sniff.AddParam(session.NewStringParameter("net.sniff.output", + mod.AddParam(session.NewStringParameter("net.sniff.output", "", "", "If set, the sniffer will write captured packets to this file.")) - sniff.AddParam(session.NewStringParameter("net.sniff.source", + mod.AddParam(session.NewStringParameter("net.sniff.source", "", "", "If set, the sniffer will read from this pcap file instead of the current interface.")) - sniff.AddHandler(session.NewModuleHandler("net.sniff stats", "", + mod.AddHandler(session.NewModuleHandler("net.sniff stats", "", "Print sniffer session configuration and statistics.", func(args []string) error { - if sniff.Stats == nil { + if mod.Stats == nil { return fmt.Errorf("No stats yet.") } - sniff.Ctx.Log(sniff.Session) + mod.Ctx.Log(mod.Session) - return sniff.Stats.Print() + return mod.Stats.Print() })) - sniff.AddHandler(session.NewModuleHandler("net.sniff on", "", + mod.AddHandler(session.NewModuleHandler("net.sniff on", "", "Start network sniffer in background.", func(args []string) error { - return sniff.Start() + return mod.Start() })) - sniff.AddHandler(session.NewModuleHandler("net.sniff off", "", + mod.AddHandler(session.NewModuleHandler("net.sniff off", "", "Stop network sniffer in background.", func(args []string) error { - return sniff.Stop() + return mod.Stop() })) - sniff.AddHandler(session.NewModuleHandler("net.fuzz on", "", + mod.AddHandler(session.NewModuleHandler("net.fuzz on", "", "Enable fuzzing for every sniffed packet containing the sapecified layers.", func(args []string) error { - return sniff.StartFuzzing() + return mod.StartFuzzing() })) - sniff.AddHandler(session.NewModuleHandler("net.fuzz off", "", + mod.AddHandler(session.NewModuleHandler("net.fuzz off", "", "Disable fuzzing", func(args []string) error { - return sniff.StopFuzzing() + return mod.StopFuzzing() })) - sniff.AddParam(session.NewStringParameter("net.fuzz.layers", + mod.AddParam(session.NewStringParameter("net.fuzz.layers", "Payload", "", "Types of layer to fuzz.")) - sniff.AddParam(session.NewDecimalParameter("net.fuzz.rate", + mod.AddParam(session.NewDecimalParameter("net.fuzz.rate", "1.0", "Rate in the [0.0,1.0] interval of packets to fuzz.")) - sniff.AddParam(session.NewDecimalParameter("net.fuzz.ratio", + mod.AddParam(session.NewDecimalParameter("net.fuzz.ratio", "0.4", "Rate in the [0.0,1.0] interval of bytes to fuzz for each packet.")) - sniff.AddParam(session.NewBoolParameter("net.fuzz.silent", + mod.AddParam(session.NewBoolParameter("net.fuzz.silent", "false", "If true it will not report fuzzed packets.")) - return sniff + return mod } -func (s Sniffer) Name() string { +func (mod Sniffer) Name() string { return "net.sniff" } -func (s Sniffer) Description() string { +func (mod Sniffer) Description() string { return "Sniff packets from the network." } -func (s Sniffer) Author() string { +func (mod Sniffer) Author() string { return "Simone Margaritelli " } -func (s Sniffer) isLocalPacket(packet gopacket.Packet) bool { +func (mod Sniffer) isLocalPacket(packet gopacket.Packet) bool { ipl := packet.Layer(layers.LayerTypeIPv4) if ipl != nil { ip, _ := ipl.(*layers.IPv4) - if ip.SrcIP.Equal(s.Session.Interface.IP) || ip.DstIP.Equal(s.Session.Interface.IP) { + if ip.SrcIP.Equal(mod.Session.Interface.IP) || ip.DstIP.Equal(mod.Session.Interface.IP) { return true } } return false } -func (s *Sniffer) onPacketMatched(pkt gopacket.Packet) { - if mainParser(pkt, s.Ctx.Verbose) { - s.Stats.NumDumped++ +func (mod *Sniffer) onPacketMatched(pkt gopacket.Packet) { + if mainParser(pkt, mod.Ctx.Verbose) { + mod.Stats.NumDumped++ } } -func (s *Sniffer) Configure() error { +func (mod *Sniffer) Configure() error { var err error - if s.Running() { + if mod.Running() { return session.ErrAlreadyStarted - } else if err, s.Ctx = s.GetContext(); err != nil { - if s.Ctx != nil { - s.Ctx.Close() - s.Ctx = nil + } else if err, mod.Ctx = mod.GetContext(); err != nil { + if mod.Ctx != nil { + mod.Ctx.Close() + mod.Ctx = nil } return err } @@ -158,66 +158,66 @@ func (s *Sniffer) Configure() error { return nil } -func (s *Sniffer) Start() error { - if err := s.Configure(); err != nil { +func (mod *Sniffer) Start() error { + if err := mod.Configure(); err != nil { return err } - return s.SetRunning(true, func() { - s.Stats = NewSnifferStats() + return mod.SetRunning(true, func() { + mod.Stats = NewSnifferStats() - src := gopacket.NewPacketSource(s.Ctx.Handle, s.Ctx.Handle.LinkType()) - s.pktSourceChan = src.Packets() - for packet := range s.pktSourceChan { - if !s.Running() { - s.Debug("end pkt loop (pkt=%v filter='%s')", packet, s.Ctx.Filter) + src := gopacket.NewPacketSource(mod.Ctx.Handle, mod.Ctx.Handle.LinkType()) + mod.pktSourceChan = src.Packets() + for packet := range mod.pktSourceChan { + if !mod.Running() { + mod.Debug("end pkt loop (pkt=%v filter='%s')", packet, mod.Ctx.Filter) break } now := time.Now() - if s.Stats.FirstPacket.IsZero() { - s.Stats.FirstPacket = now + if mod.Stats.FirstPacket.IsZero() { + mod.Stats.FirstPacket = now } - s.Stats.LastPacket = now + mod.Stats.LastPacket = now - isLocal := s.isLocalPacket(packet) + isLocal := mod.isLocalPacket(packet) if isLocal { - s.Stats.NumLocal++ + mod.Stats.NumLocal++ } - if s.fuzzActive { - s.doFuzzing(packet) + if mod.fuzzActive { + mod.doFuzzing(packet) } - if s.Ctx.DumpLocal || !isLocal { + if mod.Ctx.DumpLocal || !isLocal { data := packet.Data() - if s.Ctx.Compiled == nil || s.Ctx.Compiled.Match(data) { - s.Stats.NumMatched++ + if mod.Ctx.Compiled == nil || mod.Ctx.Compiled.Match(data) { + mod.Stats.NumMatched++ - s.onPacketMatched(packet) + mod.onPacketMatched(packet) - if s.Ctx.OutputWriter != nil { - s.Ctx.OutputWriter.WritePacket(packet.Metadata().CaptureInfo, data) - s.Stats.NumWrote++ + if mod.Ctx.OutputWriter != nil { + mod.Ctx.OutputWriter.WritePacket(packet.Metadata().CaptureInfo, data) + mod.Stats.NumWrote++ } } } } - s.pktSourceChan = nil + mod.pktSourceChan = nil }) } -func (s *Sniffer) Stop() error { - return s.SetRunning(false, func() { - s.Debug("stopping sniffer") - if s.pktSourceChan != nil { - s.Debug("sending nil") - s.pktSourceChan <- nil - s.Debug("nil sent") +func (mod *Sniffer) Stop() error { + return mod.SetRunning(false, func() { + mod.Debug("stopping sniffer") + if mod.pktSourceChan != nil { + mod.Debug("sending nil") + mod.pktSourceChan <- nil + mod.Debug("nil sent") } - s.Debug("closing ctx") - s.Ctx.Close() - s.Debug("ctx closed") + mod.Debug("closing ctx") + mod.Ctx.Close() + mod.Debug("ctx closed") }) } diff --git a/modules/net_sniff/net_sniff_context.go b/modules/net_sniff/net_sniff_context.go index e7652d49..3ebcd9f1 100644 --- a/modules/net_sniff/net_sniff_context.go +++ b/modules/net_sniff/net_sniff_context.go @@ -27,12 +27,12 @@ type SnifferContext struct { OutputWriter *pcapgo.Writer } -func (s *Sniffer) GetContext() (error, *SnifferContext) { +func (mod *Sniffer) GetContext() (error, *SnifferContext) { var err error ctx := NewSnifferContext() - if err, ctx.Source = s.StringParam("net.sniff.source"); err != nil { + if err, ctx.Source = mod.StringParam("net.sniff.source"); err != nil { return err, ctx } @@ -42,7 +42,7 @@ func (s *Sniffer) GetContext() (error, *SnifferContext) { * could hang waiting for a timeout to expire ... */ readTimeout := 500 * time.Millisecond - if ctx.Handle, err = pcap.OpenLive(s.Session.Interface.Name(), 65536, true, readTimeout); err != nil { + if ctx.Handle, err = pcap.OpenLive(mod.Session.Interface.Name(), 65536, true, readTimeout); err != nil { return err, ctx } } else { @@ -51,15 +51,15 @@ func (s *Sniffer) GetContext() (error, *SnifferContext) { } } - if err, ctx.Verbose = s.BoolParam("net.sniff.verbose"); err != nil { + if err, ctx.Verbose = mod.BoolParam("net.sniff.verbose"); err != nil { return err, ctx } - if err, ctx.DumpLocal = s.BoolParam("net.sniff.local"); err != nil { + if err, ctx.DumpLocal = mod.BoolParam("net.sniff.local"); err != nil { return err, ctx } - if err, ctx.Filter = s.StringParam("net.sniff.filter"); err != nil { + if err, ctx.Filter = mod.StringParam("net.sniff.filter"); err != nil { return err, ctx } else if ctx.Filter != "" { err = ctx.Handle.SetBPFFilter(ctx.Filter) @@ -68,7 +68,7 @@ func (s *Sniffer) GetContext() (error, *SnifferContext) { } } - if err, ctx.Expression = s.StringParam("net.sniff.regexp"); err != nil { + if err, ctx.Expression = mod.StringParam("net.sniff.regexp"); err != nil { return err, ctx } else if ctx.Expression != "" { if ctx.Compiled, err = regexp.Compile(ctx.Expression); err != nil { @@ -76,7 +76,7 @@ func (s *Sniffer) GetContext() (error, *SnifferContext) { } } - if err, ctx.Output = s.StringParam("net.sniff.output"); err != nil { + if err, ctx.Output = mod.StringParam("net.sniff.output"); err != nil { return err, ctx } else if ctx.Output != "" { if ctx.OutputFile, err = os.Create(ctx.Output); err != nil { diff --git a/modules/net_sniff/net_sniff_fuzz.go b/modules/net_sniff/net_sniff_fuzz.go index ef05b9d2..050c1957 100644 --- a/modules/net_sniff/net_sniff_fuzz.go +++ b/modules/net_sniff/net_sniff_fuzz.go @@ -21,10 +21,10 @@ var mutators = []func(byte) byte{ }, } -func (s *Sniffer) fuzz(data []byte) int { +func (mod *Sniffer) fuzz(data []byte) int { changes := 0 for off, b := range data { - if rand.Float64() > s.fuzzRatio { + if rand.Float64() > mod.fuzzRatio { continue } @@ -34,19 +34,19 @@ func (s *Sniffer) fuzz(data []byte) int { return changes } -func (s *Sniffer) doFuzzing(pkt gopacket.Packet) { - if rand.Float64() > s.fuzzRate { +func (mod *Sniffer) doFuzzing(pkt gopacket.Packet) { + if rand.Float64() > mod.fuzzRate { return } layersChanged := 0 bytesChanged := 0 - for _, fuzzLayerType := range s.fuzzLayers { + for _, fuzzLayerType := range mod.fuzzLayers { for _, layer := range pkt.Layers() { if layer.LayerType().String() == fuzzLayerType { fuzzData := layer.LayerContents() - changes := s.fuzz(fuzzData) + changes := mod.fuzz(fuzzData) if changes > 0 { layersChanged++ bytesChanged += changes @@ -57,62 +57,62 @@ func (s *Sniffer) doFuzzing(pkt gopacket.Packet) { } if bytesChanged > 0 { - logFn := s.Info - if s.fuzzSilent { - logFn = s.Debug + logFn := mod.Info + if mod.fuzzSilent { + logFn = mod.Debug } logFn("changed %d bytes in %d layers.", bytesChanged, layersChanged) - if err := s.Session.Queue.Send(pkt.Data()); err != nil { - s.Error("error sending fuzzed packet: %s", err) + if err := mod.Session.Queue.Send(pkt.Data()); err != nil { + mod.Error("error sending fuzzed packet: %s", err) } } } -func (s *Sniffer) configureFuzzing() (err error) { +func (mod *Sniffer) configureFuzzing() (err error) { layers := "" - if err, layers = s.StringParam("net.fuzz.layers"); err != nil { + if err, layers = mod.StringParam("net.fuzz.layers"); err != nil { return } else { - s.fuzzLayers = str.Comma(layers) + mod.fuzzLayers = str.Comma(layers) } - if err, s.fuzzRate = s.DecParam("net.fuzz.rate"); err != nil { + if err, mod.fuzzRate = mod.DecParam("net.fuzz.rate"); err != nil { return } - if err, s.fuzzRatio = s.DecParam("net.fuzz.ratio"); err != nil { + if err, mod.fuzzRatio = mod.DecParam("net.fuzz.ratio"); err != nil { return } - if err, s.fuzzSilent = s.BoolParam("net.fuzz.silent"); err != nil { + if err, mod.fuzzSilent = mod.BoolParam("net.fuzz.silent"); err != nil { return } return } -func (s *Sniffer) StartFuzzing() error { - if s.fuzzActive { +func (mod *Sniffer) StartFuzzing() error { + if mod.fuzzActive { return nil } - if err := s.configureFuzzing(); err != nil { + if err := mod.configureFuzzing(); err != nil { return err - } else if !s.Running() { - if err := s.Start(); err != nil { + } else if !mod.Running() { + if err := mod.Start(); err != nil { return err } } - s.fuzzActive = true + mod.fuzzActive = true - s.Info("active on layer types %s (rate:%f ratio:%f)", strings.Join(s.fuzzLayers, ","), s.fuzzRate, s.fuzzRatio) + mod.Info("active on layer types %s (rate:%f ratio:%f)", strings.Join(mod.fuzzLayers, ","), mod.fuzzRate, mod.fuzzRatio) return nil } -func (s *Sniffer) StopFuzzing() error { - s.fuzzActive = false +func (mod *Sniffer) StopFuzzing() error { + mod.fuzzActive = false return nil } diff --git a/modules/packet_proxy/packet_proxy_darwin.go b/modules/packet_proxy/packet_proxy_darwin.go index 4d50f627..0e464be0 100644 --- a/modules/packet_proxy/packet_proxy_darwin.go +++ b/modules/packet_proxy/packet_proxy_darwin.go @@ -14,26 +14,26 @@ func NewPacketProxy(s *session.Session) *PacketProxy { } } -func (pp PacketProxy) Name() string { +func (mod PacketProxy) Name() string { return "packet.proxy" } -func (pp PacketProxy) Description() string { +func (mod PacketProxy) Description() string { return "Not supported on this OS" } -func (pp PacketProxy) Author() string { +func (mod PacketProxy) Author() string { return "Simone Margaritelli " } -func (pp *PacketProxy) Configure() (err error) { +func (mod *PacketProxy) Configure() (err error) { return session.ErrNotSupported } -func (pp *PacketProxy) Start() error { +func (mod *PacketProxy) Start() error { return session.ErrNotSupported } -func (pp *PacketProxy) Stop() error { +func (mod *PacketProxy) Stop() error { return session.ErrNotSupported } diff --git a/modules/packet_proxy/packet_proxy_linux.go b/modules/packet_proxy/packet_proxy_linux.go index 92c1b948..c1530699 100644 --- a/modules/packet_proxy/packet_proxy_linux.go +++ b/modules/packet_proxy/packet_proxy_linux.go @@ -16,26 +16,26 @@ func NewPacketProxy(s *session.Session) *PacketProxy { } } -func (pp PacketProxy) Name() string { +func (mod PacketProxy) Name() string { return "packet.proxy" } -func (pp PacketProxy) Description() string { +func (mod PacketProxy) Description() string { return "Not supported on this OS" } -func (pp PacketProxy) Author() string { +func (mod PacketProxy) Author() string { return "Simone Margaritelli " } -func (pp *PacketProxy) Configure() (err error) { +func (mod *PacketProxy) Configure() (err error) { return session.ErrNotSupported } -func (pp *PacketProxy) Start() error { +func (mod *PacketProxy) Start() error { return session.ErrNotSupported } -func (pp *PacketProxy) Stop() error { +func (mod *PacketProxy) Stop() error { return session.ErrNotSupported } diff --git a/modules/packet_proxy/packet_proxy_linux_amd64.go b/modules/packet_proxy/packet_proxy_linux_amd64.go index 93f015f1..f934c13b 100644 --- a/modules/packet_proxy/packet_proxy_linux_amd64.go +++ b/modules/packet_proxy/packet_proxy_linux_amd64.go @@ -78,103 +78,103 @@ func NewPacketProxy(s *session.Session) *PacketProxy { return mod } -func (pp PacketProxy) Name() string { +func (mod PacketProxy) Name() string { return "packet.proxy" } -func (pp PacketProxy) Description() string { +func (mod PacketProxy) Description() string { return "A Linux only module that relies on NFQUEUEs in order to filter packets." } -func (pp PacketProxy) Author() string { +func (mod PacketProxy) Author() string { return "Simone Margaritelli " } -func (pp *PacketProxy) destroyQueue() { - if pp.queue == nil { +func (mod *PacketProxy) destroyQueue() { + if mod.queue == nil { return } - pp.queue.DestroyQueue() - pp.queue.Close() - pp.queue = nil + mod.queue.DestroyQueue() + mod.queue.Close() + mod.queue = nil } -func (pp *PacketProxy) runRule(enable bool) (err error) { +func (mod *PacketProxy) runRule(enable bool) (err error) { action := "-A" if !enable { action = "-D" } args := []string{ - action, pp.chainName, + action, mod.chainName, } - if pp.rule != "" { - rule := strings.Split(pp.rule, " ") + if mod.rule != "" { + rule := strings.Split(mod.rule, " ") args = append(args, rule...) } args = append(args, []string{ "-j", "NFQUEUE", - "--queue-num", fmt.Sprintf("%d", pp.queueNum), + "--queue-num", fmt.Sprintf("%d", mod.queueNum), "--queue-bypass", }...) - pp.Debug("iptables %s", args) + mod.Debug("iptables %s", args) _, err = core.Exec("iptables", args) return } -func (pp *PacketProxy) Configure() (err error) { +func (mod *PacketProxy) Configure() (err error) { golog.SetOutput(ioutil.Discard) - pp.destroyQueue() + mod.destroyQueue() - if err, pp.queueNum = pp.IntParam("packet.proxy.queue.num"); err != nil { + if err, mod.queueNum = mod.IntParam("packet.proxy.queue.num"); err != nil { return - } else if err, pp.chainName = pp.StringParam("packet.proxy.chain"); err != nil { + } else if err, mod.chainName = mod.StringParam("packet.proxy.chain"); err != nil { return - } else if err, pp.rule = pp.StringParam("packet.proxy.rule"); err != nil { + } else if err, mod.rule = mod.StringParam("packet.proxy.rule"); err != nil { return - } else if err, pp.pluginPath = pp.StringParam("packet.proxy.plugin"); err != nil { + } else if err, mod.pluginPath = mod.StringParam("packet.proxy.plugin"); err != nil { return } - if pp.pluginPath == "" { + if mod.pluginPath == "" { return fmt.Errorf("The parameter %s can not be empty.", tui.Bold("packet.proxy.plugin")) - } else if !fs.Exists(pp.pluginPath) { - return fmt.Errorf("%s does not exist.", pp.pluginPath) + } else if !fs.Exists(mod.pluginPath) { + return fmt.Errorf("%s does not exist.", mod.pluginPath) } - pp.Info("loading packet proxy plugin from %s ...", pp.pluginPath) + mod.Info("loading packet proxy plugin from %s ...", mod.pluginPath) var ok bool var sym plugin.Symbol - if pp.plugin, err = plugin.Open(pp.pluginPath); err != nil { + if mod.plugin, err = plugin.Open(mod.pluginPath); err != nil { return - } else if sym, err = pp.plugin.Lookup("OnPacket"); err != nil { + } else if sym, err = mod.plugin.Lookup("OnPacket"); err != nil { return - } else if pp.queueCb, ok = sym.(func(*nfqueue.Payload) int); !ok { + } else if mod.queueCb, ok = sym.(func(*nfqueue.Payload) int); !ok { return fmt.Errorf("Symbol OnPacket is not a valid callback function.") } - pp.queue = new(nfqueue.Queue) - if err = pp.queue.SetCallback(dummyCallback); err != nil { + mod.queue = new(nfqueue.Queue) + if err = mod.queue.SetCallback(dummyCallback); err != nil { return - } else if err = pp.queue.Init(); err != nil { + } else if err = mod.queue.Init(); err != nil { return - } else if err = pp.queue.Unbind(syscall.AF_INET); err != nil { + } else if err = mod.queue.Unbind(syscall.AF_INET); err != nil { return - } else if err = pp.queue.Bind(syscall.AF_INET); err != nil { + } else if err = mod.queue.Bind(syscall.AF_INET); err != nil { return - } else if err = pp.queue.CreateQueue(pp.queueNum); err != nil { + } else if err = mod.queue.CreateQueue(mod.queueNum); err != nil { return - } else if err = pp.queue.SetMode(nfqueue.NFQNL_COPY_PACKET); err != nil { + } else if err = mod.queue.SetMode(nfqueue.NFQNL_COPY_PACKET); err != nil { return - } else if err = pp.runRule(true); err != nil { + } else if err = mod.runRule(true); err != nil { return } @@ -188,28 +188,28 @@ func dummyCallback(payload *nfqueue.Payload) int { return mod.queueCb(payload) } -func (pp *PacketProxy) Start() error { - if pp.Running() { +func (mod *PacketProxy) Start() error { + if mod.Running() { return session.ErrAlreadyStarted - } else if err := pp.Configure(); err != nil { + } else if err := mod.Configure(); err != nil { return err } - return pp.SetRunning(true, func() { - pp.Info("started on queue number %d", pp.queueNum) + return mod.SetRunning(true, func() { + mod.Info("started on queue number %d", mod.queueNum) - defer pp.destroyQueue() + defer mod.destroyQueue() - pp.queue.Loop() + mod.queue.Loop() - pp.done <- true + mod.done <- true }) } -func (pp *PacketProxy) Stop() error { - return pp.SetRunning(false, func() { - pp.queue.StopLoop() - pp.runRule(false) - <-pp.done +func (mod *PacketProxy) Stop() error { + return mod.SetRunning(false, func() { + mod.queue.StopLoop() + mod.runRule(false) + <-mod.done }) } diff --git a/modules/packet_proxy/packet_proxy_windows.go b/modules/packet_proxy/packet_proxy_windows.go index 4d50f627..0e464be0 100644 --- a/modules/packet_proxy/packet_proxy_windows.go +++ b/modules/packet_proxy/packet_proxy_windows.go @@ -14,26 +14,26 @@ func NewPacketProxy(s *session.Session) *PacketProxy { } } -func (pp PacketProxy) Name() string { +func (mod PacketProxy) Name() string { return "packet.proxy" } -func (pp PacketProxy) Description() string { +func (mod PacketProxy) Description() string { return "Not supported on this OS" } -func (pp PacketProxy) Author() string { +func (mod PacketProxy) Author() string { return "Simone Margaritelli " } -func (pp *PacketProxy) Configure() (err error) { +func (mod *PacketProxy) Configure() (err error) { return session.ErrNotSupported } -func (pp *PacketProxy) Start() error { +func (mod *PacketProxy) Start() error { return session.ErrNotSupported } -func (pp *PacketProxy) Stop() error { +func (mod *PacketProxy) Stop() error { return session.ErrNotSupported } diff --git a/modules/prober/net_probe.go b/modules/prober/net_probe.go deleted file mode 100644 index 973bc29b..00000000 --- a/modules/prober/net_probe.go +++ /dev/null @@ -1,156 +0,0 @@ -package prober - -import ( - "sync" - "time" - - "github.com/bettercap/bettercap/network" - "github.com/bettercap/bettercap/session" - - "github.com/malfunkt/iprange" -) - -type Probes struct { - NBNS bool - MDNS bool - UPNP bool - WSD bool -} - -type Prober struct { - session.SessionModule - throttle int - probes Probes - waitGroup *sync.WaitGroup -} - -func NewProber(s *session.Session) *Prober { - p := &Prober{ - SessionModule: session.NewSessionModule("net.probe", s), - waitGroup: &sync.WaitGroup{}, - } - - p.AddParam(session.NewBoolParameter("net.probe.nbns", - "true", - "Enable NetBIOS name service discovery probes.")) - - p.AddParam(session.NewBoolParameter("net.probe.mdns", - "true", - "Enable mDNS discovery probes.")) - - p.AddParam(session.NewBoolParameter("net.probe.upnp", - "true", - "Enable UPNP discovery probes.")) - - p.AddParam(session.NewBoolParameter("net.probe.wsd", - "true", - "Enable WSD discovery probes.")) - - p.AddParam(session.NewIntParameter("net.probe.throttle", - "10", - "If greater than 0, probe packets will be throttled by this value in milliseconds.")) - - p.AddHandler(session.NewModuleHandler("net.probe on", "", - "Start network hosts probing in background.", - func(args []string) error { - return p.Start() - })) - - p.AddHandler(session.NewModuleHandler("net.probe off", "", - "Stop network hosts probing in background.", - func(args []string) error { - return p.Stop() - })) - - return p -} - -func (p Prober) Name() string { - return "net.probe" -} - -func (p Prober) Description() string { - return "Keep probing for new hosts on the network by sending dummy UDP packets to every possible IP on the subnet." -} - -func (p Prober) Author() string { - return "Simone Margaritelli " -} - -func (p *Prober) Configure() error { - var err error - if err, p.throttle = p.IntParam("net.probe.throttle"); err != nil { - return err - } else if err, p.probes.NBNS = p.BoolParam("net.probe.nbns"); err != nil { - return err - } else if err, p.probes.MDNS = p.BoolParam("net.probe.mdns"); err != nil { - return err - } else if err, p.probes.UPNP = p.BoolParam("net.probe.upnp"); err != nil { - return err - } else if err, p.probes.WSD = p.BoolParam("net.probe.wsd"); err != nil { - return err - } else { - p.Debug("Throttling packets of %d ms.", p.throttle) - } - return nil -} - -func (p *Prober) Start() error { - if err := p.Configure(); err != nil { - return err - } - - return p.SetRunning(true, func() { - p.waitGroup.Add(1) - defer p.waitGroup.Done() - - if p.Session.Interface.IpAddress == network.MonitorModeAddress { - p.Info("Interface is in monitor mode, skipping net.probe") - return - } - - list, err := iprange.Parse(p.Session.Interface.CIDR()) - if err != nil { - p.Fatal("%s", err) - } - - from := p.Session.Interface.IP - from_hw := p.Session.Interface.HW - addresses := list.Expand() - throttle := time.Duration(p.throttle) * time.Millisecond - - for p.Running() { - if p.probes.MDNS { - p.sendProbeMDNS(from, from_hw) - } - - if p.probes.UPNP { - p.sendProbeUPNP(from, from_hw) - } - - if p.probes.WSD { - p.sendProbeWSD(from, from_hw) - } - - for _, ip := range addresses { - if !p.Running() { - return - } else if p.Session.Skip(ip) { - p.Debug("skipping address %s from probing.", ip) - continue - } else if p.probes.NBNS { - p.sendProbeNBNS(from, from_hw, ip) - } - time.Sleep(throttle) - } - - time.Sleep(5 * time.Second) - } - }) -} - -func (p *Prober) Stop() error { - return p.SetRunning(false, func() { - p.waitGroup.Wait() - }) -} diff --git a/modules/prober/net_probe_mdns.go b/modules/prober/net_probe_mdns.go deleted file mode 100644 index df142085..00000000 --- a/modules/prober/net_probe_mdns.go +++ /dev/null @@ -1,19 +0,0 @@ -package prober - -import ( - "net" - - "github.com/bettercap/bettercap/packets" -) - -func (p *Prober) sendProbeMDNS(from net.IP, from_hw net.HardwareAddr) { - err, raw := packets.NewMDNSProbe(from, from_hw) - if err != nil { - p.Error("error while sending mdns probe: %v", err) - return - } else if err := p.Session.Queue.Send(raw); err != nil { - p.Error("error sending mdns packet: %s", err) - } else { - p.Debug("sent %d bytes of MDNS probe", len(raw)) - } -} diff --git a/modules/syn_scan/syn_scan.go b/modules/syn_scan/syn_scan.go index bc049a40..76d36dda 100644 --- a/modules/syn_scan/syn_scan.go +++ b/modules/syn_scan/syn_scan.go @@ -38,111 +38,111 @@ type SynScanner struct { } func NewSynScanner(s *session.Session) *SynScanner { - ss := &SynScanner{ + mod := &SynScanner{ SessionModule: session.NewSessionModule("syn.scan", s), addresses: make([]net.IP, 0), waitGroup: &sync.WaitGroup{}, progressEvery: time.Duration(1) * time.Second, } - ss.AddParam(session.NewIntParameter("syn.scan.show-progress-every", + mod.AddParam(session.NewIntParameter("syn.scan.show-progress-every", "1", "Period in seconds for the scanning progress reporting.")) - ss.AddHandler(session.NewModuleHandler("syn.scan stop", "syn\\.scan (stop|off)", + mod.AddHandler(session.NewModuleHandler("syn.scan stop", "syn\\.scan (stop|off)", "Stop the current syn scanning session.", func(args []string) error { - if !ss.Running() { + if !mod.Running() { return fmt.Errorf("no syn.scan is running") } - return ss.Stop() + return mod.Stop() })) - ss.AddHandler(session.NewModuleHandler("syn.scan IP-RANGE [START-PORT] [END-PORT]", "syn.scan ([^\\s]+) ?(\\d+)?([\\s\\d]*)?", + mod.AddHandler(session.NewModuleHandler("syn.scan IP-RANGE [START-PORT] [END-PORT]", "syn.scan ([^\\s]+) ?(\\d+)?([\\s\\d]*)?", "Perform a syn port scanning against an IP address within the provided ports range.", func(args []string) error { period := 0 - if ss.Running() { + if mod.Running() { return fmt.Errorf("A scan is already running, wait for it to end before starting a new one.") - } else if err := ss.parseTargets(args[0]); err != nil { + } else if err := mod.parseTargets(args[0]); err != nil { return err - } else if err = ss.parsePorts(args); err != nil { + } else if err = mod.parsePorts(args); err != nil { return err - } else if err, period = ss.IntParam("syn.scan.show-progress-every"); err != nil { + } else if err, period = mod.IntParam("syn.scan.show-progress-every"); err != nil { return err } else { - ss.progressEvery = time.Duration(period) * time.Second + mod.progressEvery = time.Duration(period) * time.Second } - return ss.synScan() + return mod.synScan() })) - ss.AddHandler(session.NewModuleHandler("syn.scan.progress", "syn\\.scan\\.progress", + mod.AddHandler(session.NewModuleHandler("syn.scan.progress", "syn\\.scan\\.progress", "Print progress of the current syn scanning session.", func(args []string) error { - if !ss.Running() { + if !mod.Running() { return fmt.Errorf("no syn.scan is running") } - return ss.showProgress() + return mod.showProgress() })) - return ss + return mod } -func (s *SynScanner) parseTargets(arg string) error { +func (mod *SynScanner) parseTargets(arg string) error { if list, err := iprange.Parse(arg); err != nil { return fmt.Errorf("error while parsing IP range '%s': %s", arg, err) } else { - s.addresses = list.Expand() + mod.addresses = list.Expand() } return nil } -func (s *SynScanner) parsePorts(args []string) (err error) { +func (mod *SynScanner) parsePorts(args []string) (err error) { argc := len(args) - s.stats.totProbes = 0 - s.stats.doneProbes = 0 - s.startPort = 1 - s.endPort = 65535 + mod.stats.totProbes = 0 + mod.stats.doneProbes = 0 + mod.startPort = 1 + mod.endPort = 65535 if argc > 1 && str.Trim(args[1]) != "" { - if s.startPort, err = strconv.Atoi(str.Trim(args[1])); err != nil { + if mod.startPort, err = strconv.Atoi(str.Trim(args[1])); err != nil { return fmt.Errorf("invalid start port %s: %s", args[1], err) - } else if s.startPort > 65535 { - s.startPort = 65535 + } else if mod.startPort > 65535 { + mod.startPort = 65535 } - s.endPort = s.startPort + mod.endPort = mod.startPort } if argc > 2 && str.Trim(args[2]) != "" { - if s.endPort, err = strconv.Atoi(str.Trim(args[2])); err != nil { + if mod.endPort, err = strconv.Atoi(str.Trim(args[2])); err != nil { return fmt.Errorf("invalid end port %s: %s", args[2], err) } } - if s.endPort < s.startPort { - return fmt.Errorf("end port %d is greater than start port %d", s.endPort, s.startPort) + if mod.endPort < mod.startPort { + return fmt.Errorf("end port %d is greater than start port %d", mod.endPort, mod.startPort) } return } -func (s *SynScanner) Name() string { +func (mod *SynScanner) Name() string { return "syn.scan" } -func (s *SynScanner) Description() string { +func (mod *SynScanner) Description() string { return "A module to perform SYN port scanning." } -func (s *SynScanner) Author() string { +func (mod *SynScanner) Author() string { return "Simone Margaritelli " } -func (s *SynScanner) Configure() error { +func (mod *SynScanner) Configure() error { return nil } -func (s *SynScanner) Start() error { +func (mod *SynScanner) Start() error { return nil } @@ -153,62 +153,62 @@ func plural(n uint64) string { return "" } -func (s *SynScanner) showProgress() error { - progress := 100.0 * (float64(s.stats.doneProbes) / float64(s.stats.totProbes)) - s.Info("[%.2f%%] found %d open port%s for %d address%s, sent %d/%d packets in %s", +func (mod *SynScanner) showProgress() error { + progress := 100.0 * (float64(mod.stats.doneProbes) / float64(mod.stats.totProbes)) + mod.Info("[%.2f%%] found %d open port%s for %d address%s, sent %d/%d packets in %s", progress, - s.stats.openPorts, - plural(s.stats.openPorts), - s.stats.numAddresses, - plural(s.stats.numAddresses), - s.stats.doneProbes, - s.stats.totProbes, - time.Since(s.stats.started)) + mod.stats.openPorts, + plural(mod.stats.openPorts), + mod.stats.numAddresses, + plural(mod.stats.numAddresses), + mod.stats.doneProbes, + mod.stats.totProbes, + time.Since(mod.stats.started)) return nil } -func (s *SynScanner) Stop() error { - s.Info("stopping ...") - return s.SetRunning(false, func() { - s.waitGroup.Wait() - s.showProgress() +func (mod *SynScanner) Stop() error { + mod.Info("stopping ...") + return mod.SetRunning(false, func() { + mod.waitGroup.Wait() + mod.showProgress() }) } -func (s *SynScanner) synScan() error { - s.SetRunning(true, func() { - defer s.SetRunning(false, nil) +func (mod *SynScanner) synScan() error { + mod.SetRunning(true, func() { + defer mod.SetRunning(false, nil) - s.waitGroup.Add(1) - defer s.waitGroup.Done() + mod.waitGroup.Add(1) + defer mod.waitGroup.Done() - s.stats.openPorts = 0 - s.stats.numPorts = uint64(s.endPort - s.startPort + 1) - s.stats.started = time.Now() - s.stats.numAddresses = uint64(len(s.addresses)) - s.stats.totProbes = s.stats.numAddresses * s.stats.numPorts - s.stats.doneProbes = 0 + mod.stats.openPorts = 0 + mod.stats.numPorts = uint64(mod.endPort - mod.startPort + 1) + mod.stats.started = time.Now() + mod.stats.numAddresses = uint64(len(mod.addresses)) + mod.stats.totProbes = mod.stats.numAddresses * mod.stats.numPorts + mod.stats.doneProbes = 0 plural := "es" - if s.stats.numAddresses == 1 { + if mod.stats.numAddresses == 1 { plural = "" } - if s.stats.numPorts > 1 { - s.Info("scanning %d address%s from port %d to port %d ...", s.stats.numAddresses, plural, s.startPort, s.endPort) + if mod.stats.numPorts > 1 { + mod.Info("scanning %d address%s from port %d to port %d ...", mod.stats.numAddresses, plural, mod.startPort, mod.endPort) } else { - s.Info("scanning %d address%s on port %d ...", s.stats.numAddresses, plural, s.startPort) + mod.Info("scanning %d address%s on port %d ...", mod.stats.numAddresses, plural, mod.startPort) } // set the collector - s.Session.Queue.OnPacket(s.onPacket) - defer s.Session.Queue.OnPacket(nil) + mod.Session.Queue.OnPacket(mod.onPacket) + defer mod.Session.Queue.OnPacket(nil) // start to show progress every second go func() { for { - time.Sleep(s.progressEvery) - if s.Running() { - s.showProgress() + time.Sleep(mod.progressEvery) + if mod.Running() { + mod.showProgress() } else { break } @@ -216,34 +216,34 @@ func (s *SynScanner) synScan() error { }() // start sending SYN packets and wait - for _, address := range s.addresses { - if !s.Running() { + for _, address := range mod.addresses { + if !mod.Running() { break } - mac, err := s.Session.FindMAC(address, true) + mac, err := mod.Session.FindMAC(address, true) if err != nil { - atomic.AddUint64(&s.stats.doneProbes, s.stats.numPorts) - s.Debug("could not get MAC for %s: %s", address.String(), err) + atomic.AddUint64(&mod.stats.doneProbes, mod.stats.numPorts) + mod.Debug("could not get MAC for %s: %s", address.String(), err) continue } - for dstPort := s.startPort; dstPort < s.endPort+1; dstPort++ { - if !s.Running() { + for dstPort := mod.startPort; dstPort < mod.endPort+1; dstPort++ { + if !mod.Running() { break } - atomic.AddUint64(&s.stats.doneProbes, 1) + atomic.AddUint64(&mod.stats.doneProbes, 1) - err, raw := packets.NewTCPSyn(s.Session.Interface.IP, s.Session.Interface.HW, address, mac, synSourcePort, dstPort) + err, raw := packets.NewTCPSyn(mod.Session.Interface.IP, mod.Session.Interface.HW, address, mac, synSourcePort, dstPort) if err != nil { - s.Error("error creating SYN packet: %s", err) + mod.Error("error creating SYN packet: %s", err) continue } - if err := s.Session.Queue.Send(raw); err != nil { - s.Error("error sending SYN packet: %s", err) + if err := mod.Session.Queue.Send(raw); err != nil { + mod.Error("error sending SYN packet: %s", err) } else { - s.Debug("sent %d bytes of SYN packet to %s for port %d", len(raw), address.String(), dstPort) + mod.Debug("sent %d bytes of SYN packet to %s for port %d", len(raw), address.String(), dstPort) } time.Sleep(time.Duration(10) * time.Millisecond) diff --git a/modules/syn_scan/syn_scan_reader.go b/modules/syn_scan/syn_scan_reader.go index ee8d84b7..d35c166c 100644 --- a/modules/syn_scan/syn_scan_reader.go +++ b/modules/syn_scan/syn_scan_reader.go @@ -10,8 +10,8 @@ import ( "github.com/google/gopacket/layers" ) -func (s *SynScanner) isAddressInRange(ip net.IP) bool { - for _, a := range s.addresses { +func (mod *SynScanner) isAddressInRange(ip net.IP) bool { + for _, a := range mod.addresses { if a.Equal(ip) { return true } @@ -19,7 +19,7 @@ func (s *SynScanner) isAddressInRange(ip net.IP) bool { return false } -func (s *SynScanner) onPacket(pkt gopacket.Packet) { +func (mod *SynScanner) onPacket(pkt gopacket.Packet) { var eth layers.Ethernet var ip layers.IPv4 var tcp layers.TCP @@ -37,19 +37,19 @@ func (s *SynScanner) onPacket(pkt gopacket.Packet) { return } - if s.isAddressInRange(ip.SrcIP) && tcp.DstPort == synSourcePort && tcp.SYN && tcp.ACK { - atomic.AddUint64(&s.stats.openPorts, 1) + if mod.isAddressInRange(ip.SrcIP) && tcp.DstPort == synSourcePort && tcp.SYN && tcp.ACK { + atomic.AddUint64(&mod.stats.openPorts, 1) from := ip.SrcIP.String() port := int(tcp.SrcPort) var host *network.Endpoint - if ip.SrcIP.Equal(s.Session.Interface.IP) { - host = s.Session.Interface - } else if ip.SrcIP.Equal(s.Session.Gateway.IP) { - host = s.Session.Gateway + if ip.SrcIP.Equal(mod.Session.Interface.IP) { + host = mod.Session.Interface + } else if ip.SrcIP.Equal(mod.Session.Gateway.IP) { + host = mod.Session.Gateway } else { - host = s.Session.Lan.GetByIp(from) + host = mod.Session.Lan.GetByIp(from) } if host != nil { diff --git a/modules/tcp_proxy/tcp_proxy.go b/modules/tcp_proxy/tcp_proxy.go index 601c4424..1a13e3bb 100644 --- a/modules/tcp_proxy/tcp_proxy.go +++ b/modules/tcp_proxy/tcp_proxy.go @@ -21,70 +21,70 @@ type TcpProxy struct { } func NewTcpProxy(s *session.Session) *TcpProxy { - p := &TcpProxy{ + mod := &TcpProxy{ SessionModule: session.NewSessionModule("tcp.proxy", s), } - p.AddParam(session.NewIntParameter("tcp.port", + mod.AddParam(session.NewIntParameter("tcp.port", "443", "Remote port to redirect when the TCP proxy is activated.")) - p.AddParam(session.NewStringParameter("tcp.address", + mod.AddParam(session.NewStringParameter("tcp.address", "", session.IPv4Validator, "Remote address of the TCP proxy.")) - p.AddParam(session.NewStringParameter("tcp.proxy.address", + mod.AddParam(session.NewStringParameter("tcp.proxy.address", session.ParamIfaceAddress, session.IPv4Validator, "Address to bind the TCP proxy to.")) - p.AddParam(session.NewIntParameter("tcp.proxy.port", + mod.AddParam(session.NewIntParameter("tcp.proxy.port", "8443", "Port to bind the TCP proxy to.")) - p.AddParam(session.NewStringParameter("tcp.proxy.script", + mod.AddParam(session.NewStringParameter("tcp.proxy.script", "", "", "Path of a TCP proxy JS script.")) - p.AddParam(session.NewStringParameter("tcp.tunnel.address", + mod.AddParam(session.NewStringParameter("tcp.tunnel.address", "", "", "Address to redirect the TCP tunnel to (optional).")) - p.AddParam(session.NewIntParameter("tcp.tunnel.port", + mod.AddParam(session.NewIntParameter("tcp.tunnel.port", "0", "Port to redirect the TCP tunnel to (optional).")) - p.AddHandler(session.NewModuleHandler("tcp.proxy on", "", + mod.AddHandler(session.NewModuleHandler("tcp.proxy on", "", "Start TCP proxy.", func(args []string) error { - return p.Start() + return mod.Start() })) - p.AddHandler(session.NewModuleHandler("tcp.proxy off", "", + mod.AddHandler(session.NewModuleHandler("tcp.proxy off", "", "Stop TCP proxy.", func(args []string) error { - return p.Stop() + return mod.Stop() })) - return p + return mod } -func (p *TcpProxy) Name() string { +func (mod *TcpProxy) Name() string { return "tcp.proxy" } -func (p *TcpProxy) Description() string { +func (mod *TcpProxy) Description() string { return "A full featured TCP proxy and tunnel, all TCP traffic to a given remote address and port will be redirected to it." } -func (p *TcpProxy) Author() string { +func (mod *TcpProxy) Author() string { return "Simone Margaritelli " } -func (p *TcpProxy) Configure() error { +func (mod *TcpProxy) Configure() error { var err error var port int var proxyPort int @@ -94,63 +94,63 @@ func (p *TcpProxy) Configure() error { var tunnelAddress string var tunnelPort int - if p.Running() { + if mod.Running() { return session.ErrAlreadyStarted - } else if err, address = p.StringParam("tcp.address"); err != nil { + } else if err, address = mod.StringParam("tcp.address"); err != nil { return err - } else if err, proxyAddress = p.StringParam("tcp.proxy.address"); err != nil { + } else if err, proxyAddress = mod.StringParam("tcp.proxy.address"); err != nil { return err - } else if err, proxyPort = p.IntParam("tcp.proxy.port"); err != nil { + } else if err, proxyPort = mod.IntParam("tcp.proxy.port"); err != nil { return err - } else if err, port = p.IntParam("tcp.port"); err != nil { + } else if err, port = mod.IntParam("tcp.port"); err != nil { return err - } else if err, tunnelAddress = p.StringParam("tcp.tunnel.address"); err != nil { + } else if err, tunnelAddress = mod.StringParam("tcp.tunnel.address"); err != nil { return err - } else if err, tunnelPort = p.IntParam("tcp.tunnel.port"); err != nil { + } else if err, tunnelPort = mod.IntParam("tcp.tunnel.port"); err != nil { return err - } else if err, scriptPath = p.StringParam("tcp.proxy.script"); err != nil { + } else if err, scriptPath = mod.StringParam("tcp.proxy.script"); err != nil { return err - } else if p.localAddr, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", proxyAddress, proxyPort)); err != nil { + } else if mod.localAddr, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", proxyAddress, proxyPort)); err != nil { return err - } else if p.remoteAddr, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", address, port)); err != nil { + } else if mod.remoteAddr, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", address, port)); err != nil { return err - } else if p.tunnelAddr, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", tunnelAddress, tunnelPort)); err != nil { + } else if mod.tunnelAddr, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", tunnelAddress, tunnelPort)); err != nil { return err - } else if p.listener, err = net.ListenTCP("tcp", p.localAddr); err != nil { + } else if mod.listener, err = net.ListenTCP("tcp", mod.localAddr); err != nil { return err } if scriptPath != "" { - if err, p.script = LoadTcpProxyScript(scriptPath, p.Session); err != nil { + if err, mod.script = LoadTcpProxyScript(scriptPath, mod.Session); err != nil { return err } else { - p.Debug("script %s loaded.", scriptPath) + mod.Debug("script %s loaded.", scriptPath) } } - if !p.Session.Firewall.IsForwardingEnabled() { - p.Info("enabling forwarding.") - p.Session.Firewall.EnableForwarding(true) + if !mod.Session.Firewall.IsForwardingEnabled() { + mod.Info("enabling forwarding.") + mod.Session.Firewall.EnableForwarding(true) } - p.Redirection = firewall.NewRedirection(p.Session.Interface.Name(), + mod.Redirection = firewall.NewRedirection(mod.Session.Interface.Name(), "TCP", port, proxyAddress, proxyPort) - p.Redirection.SrcAddress = address + mod.Redirection.SrcAddress = address - if err := p.Session.Firewall.EnableRedirection(p.Redirection, true); err != nil { + if err := mod.Session.Firewall.EnableRedirection(mod.Redirection, true); err != nil { return err } - p.Debug("applied redirection %s", p.Redirection.String()) + mod.Debug("applied redirection %s", mod.Redirection.String()) return nil } -func (p *TcpProxy) doPipe(from, to net.Addr, src, dst io.ReadWriter, wg *sync.WaitGroup) { +func (mod *TcpProxy) doPipe(from, to net.Addr, src, dst io.ReadWriter, wg *sync.WaitGroup) { defer wg.Done() buff := make([]byte, 0xffff) @@ -158,18 +158,18 @@ func (p *TcpProxy) doPipe(from, to net.Addr, src, dst io.ReadWriter, wg *sync.Wa n, err := src.Read(buff) if err != nil { if err.Error() != "EOF" { - p.Warning("read failed: %s", err) + mod.Warning("read failed: %s", err) } return } b := buff[:n] - if p.script != nil { - ret := p.script.OnData(from, to, b) + if mod.script != nil { + ret := mod.script.OnData(from, to, b) if ret != nil { nret := len(ret) - p.Info("overriding %d bytes of data from %s to %s with %d bytes of new data.", + mod.Info("overriding %d bytes of data from %s to %s with %d bytes of new data.", n, from.String(), to.String(), nret) b = make([]byte, nret) copy(b, ret) @@ -178,28 +178,28 @@ func (p *TcpProxy) doPipe(from, to net.Addr, src, dst io.ReadWriter, wg *sync.Wa n, err = dst.Write(b) if err != nil { - p.Warning("write failed: %s", err) + mod.Warning("write failed: %s", err) return } - p.Debug("%s -> %s : %d bytes", from.String(), to.String(), n) + mod.Debug("%s -> %s : %d bytes", from.String(), to.String(), n) } } -func (p *TcpProxy) handleConnection(c *net.TCPConn) { +func (mod *TcpProxy) handleConnection(c *net.TCPConn) { defer c.Close() - p.Info("got a connection from %s", c.RemoteAddr().String()) + mod.Info("got a connection from %s", c.RemoteAddr().String()) // tcp tunnel enabled - if p.tunnelAddr.IP.To4() != nil { - p.Info("tcp tunnel started ( %s -> %s )", p.remoteAddr.String(), p.tunnelAddr.String()) - p.remoteAddr = p.tunnelAddr + if mod.tunnelAddr.IP.To4() != nil { + mod.Info("tcp tunnel started ( %s -> %s )", mod.remoteAddr.String(), mod.tunnelAddr.String()) + mod.remoteAddr = mod.tunnelAddr } - remote, err := net.DialTCP("tcp", nil, p.remoteAddr) + remote, err := net.DialTCP("tcp", nil, mod.remoteAddr) if err != nil { - p.Warning("error while connecting to remote %s: %s", p.remoteAddr.String(), err) + mod.Warning("error while connecting to remote %s: %s", mod.remoteAddr.String(), err) return } defer remote.Close() @@ -208,43 +208,43 @@ func (p *TcpProxy) handleConnection(c *net.TCPConn) { wg.Add(2) // start pipeing - go p.doPipe(c.RemoteAddr(), p.remoteAddr, c, remote, &wg) - go p.doPipe(p.remoteAddr, c.RemoteAddr(), remote, c, &wg) + go mod.doPipe(c.RemoteAddr(), mod.remoteAddr, c, remote, &wg) + go mod.doPipe(mod.remoteAddr, c.RemoteAddr(), remote, c, &wg) wg.Wait() } -func (p *TcpProxy) Start() error { - if err := p.Configure(); err != nil { +func (mod *TcpProxy) Start() error { + if err := mod.Configure(); err != nil { return err } - return p.SetRunning(true, func() { - p.Info("started ( x -> %s -> %s )", p.localAddr.String(), p.remoteAddr.String()) + return mod.SetRunning(true, func() { + mod.Info("started ( x -> %s -> %s )", mod.localAddr.String(), mod.remoteAddr.String()) - for p.Running() { - conn, err := p.listener.AcceptTCP() + for mod.Running() { + conn, err := mod.listener.AcceptTCP() if err != nil { - p.Warning("error while accepting TCP connection: %s", err) + mod.Warning("error while accepting TCP connection: %s", err) continue } - go p.handleConnection(conn) + go mod.handleConnection(conn) } }) } -func (p *TcpProxy) Stop() error { +func (mod *TcpProxy) Stop() error { - if p.Redirection != nil { - p.Debug("disabling redirection %s", p.Redirection.String()) - if err := p.Session.Firewall.EnableRedirection(p.Redirection, false); err != nil { + if mod.Redirection != nil { + mod.Debug("disabling redirection %s", mod.Redirection.String()) + if err := mod.Session.Firewall.EnableRedirection(mod.Redirection, false); err != nil { return err } - p.Redirection = nil + mod.Redirection = nil } - return p.SetRunning(false, func() { - p.listener.Close() + return mod.SetRunning(false, func() { + mod.listener.Close() }) } diff --git a/modules/ticker/ticker.go b/modules/ticker/ticker.go index 4dfc965b..5e62139c 100644 --- a/modules/ticker/ticker.go +++ b/modules/ticker/ticker.go @@ -13,87 +13,87 @@ type Ticker struct { } func NewTicker(s *session.Session) *Ticker { - t := &Ticker{ + mod := &Ticker{ SessionModule: session.NewSessionModule("ticker", s), } - t.AddParam(session.NewStringParameter("ticker.commands", + mod.AddParam(session.NewStringParameter("ticker.commands", "clear; net.show; events.show 20", "", "List of commands separated by a ;")) - t.AddParam(session.NewIntParameter("ticker.period", + mod.AddParam(session.NewIntParameter("ticker.period", "1", "Ticker period in seconds")) - t.AddHandler(session.NewModuleHandler("ticker on", "", + mod.AddHandler(session.NewModuleHandler("ticker on", "", "Start the ticker.", func(args []string) error { - return t.Start() + return mod.Start() })) - t.AddHandler(session.NewModuleHandler("ticker off", "", + mod.AddHandler(session.NewModuleHandler("ticker off", "", "Stop the ticker.", func(args []string) error { - return t.Stop() + return mod.Stop() })) - return t + return mod } -func (t *Ticker) Name() string { +func (mod *Ticker) Name() string { return "ticker" } -func (t *Ticker) Description() string { +func (mod *Ticker) Description() string { return "A module to execute one or more commands every given amount of seconds." } -func (t *Ticker) Author() string { +func (mod *Ticker) Author() string { return "Simone Margaritelli " } -func (t *Ticker) Configure() error { +func (mod *Ticker) Configure() error { var err error var commands string var period int - if t.Running() { + if mod.Running() { return session.ErrAlreadyStarted - } else if err, commands = t.StringParam("ticker.commands"); err != nil { + } else if err, commands = mod.StringParam("ticker.commands"); err != nil { return err - } else if err, period = t.IntParam("ticker.period"); err != nil { + } else if err, period = mod.IntParam("ticker.period"); err != nil { return err } - t.Commands = session.ParseCommands(commands) - t.Period = time.Duration(period) * time.Second + mod.Commands = session.ParseCommands(commands) + mod.Period = time.Duration(period) * time.Second return nil } -func (t *Ticker) Start() error { - if err := t.Configure(); err != nil { +func (mod *Ticker) Start() error { + if err := mod.Configure(); err != nil { return err } - return t.SetRunning(true, func() { - t.Info("running with period %.fs", t.Period.Seconds()) - tick := time.NewTicker(t.Period) + return mod.SetRunning(true, func() { + mod.Info("running with period %.fs", mod.Period.Seconds()) + tick := time.NewTicker(mod.Period) for range tick.C { - if !t.Running() { + if !mod.Running() { break } - for _, cmd := range t.Commands { - if err := t.Session.Run(cmd); err != nil { - t.Error("%s", err) + for _, cmd := range mod.Commands { + if err := mod.Session.Run(cmd); err != nil { + mod.Error("%s", err) } } } }) } -func (t *Ticker) Stop() error { - return t.SetRunning(false, nil) +func (mod *Ticker) Stop() error { + return mod.SetRunning(false, nil) } diff --git a/modules/update/update.go b/modules/update/update.go index 7db74f6c..ac2296fc 100644 --- a/modules/update/update.go +++ b/modules/update/update.go @@ -20,41 +20,42 @@ type UpdateModule struct { } func NewUpdateModule(s *session.Session) *UpdateModule { - u := &UpdateModule{ + mod := &UpdateModule{ SessionModule: session.NewSessionModule("update", s), client: github.NewClient(nil), } - u.AddHandler(session.NewModuleHandler("update.check on", "", + mod.AddHandler(session.NewModuleHandler("update.check on", "", "Check latest available stable version and compare it with the one being used.", func(args []string) error { - return u.Start() + return mod.Start() })) - return u + return mod } -func (u *UpdateModule) Name() string { + +func (mod *UpdateModule) Name() string { return "update" } -func (u *UpdateModule) Description() string { +func (mod *UpdateModule) Description() string { return "A module to check for bettercap's updates." } -func (u *UpdateModule) Author() string { +func (mod *UpdateModule) Author() string { return "Simone Margaritelli " } -func (u *UpdateModule) Configure() error { +func (mod *UpdateModule) Configure() error { return nil } -func (u *UpdateModule) Stop() error { +func (mod *UpdateModule) Stop() error { return nil } -func (u *UpdateModule) versionToNum(ver string) float64 { +func (mod *UpdateModule) versionToNum(ver string) float64 { if ver[0] == 'v' { ver = ver[1:] } @@ -77,21 +78,21 @@ func (u *UpdateModule) versionToNum(ver string) float64 { return n } -func (u *UpdateModule) Start() error { - return u.SetRunning(true, func() { - defer u.SetRunning(false, nil) +func (mod *UpdateModule) Start() error { + return mod.SetRunning(true, func() { + defer mod.SetRunning(false, nil) - u.Info("checking latest stable release ...") + mod.Info("checking latest stable release ...") - if releases, _, err := u.client.Repositories.ListReleases(context.Background(), "bettercap", "bettercap", nil); err == nil { + if releases, _, err := mod.client.Repositories.ListReleases(context.Background(), "bettercap", "bettercap", nil); err == nil { latest := releases[0] - if u.versionToNum(core.Version) < u.versionToNum(*latest.TagName) { - u.Session.Events.Add("update.available", latest) + if mod.versionToNum(core.Version) < mod.versionToNum(*latest.TagName) { + mod.Session.Events.Add("update.available", latest) } else { - u.Info("you are running %s which is the latest stable version.", tui.Bold(core.Version)) + mod.Info("you are running %s which is the latest stable version.", tui.Bold(core.Version)) } } else { - u.Error("error while fetching latest release info from GitHub: %s", err) + mod.Error("error while fetching latest release info from GitHub: %s", err) } }) } diff --git a/modules/script_builtins.go b/modules/utils/script_builtins.go similarity index 99% rename from modules/script_builtins.go rename to modules/utils/script_builtins.go index ee6f6508..701e13db 100644 --- a/modules/script_builtins.go +++ b/modules/utils/script_builtins.go @@ -1,4 +1,4 @@ -package modules +package utils import ( "encoding/base64" diff --git a/modules/wifi/wifi.go b/modules/wifi/wifi.go index 16339328..411a12f5 100644 --- a/modules/wifi/wifi.go +++ b/modules/wifi/wifi.go @@ -53,7 +53,7 @@ type WiFiModule struct { } func NewWiFiModule(s *session.Session) *WiFiModule { - w := &WiFiModule{ + mod := &WiFiModule{ SessionModule: session.NewSessionModule("wifi", s), minRSSI: -200, channel: 0, @@ -74,47 +74,47 @@ func NewWiFiModule(s *session.Session) *WiFiModule { chanLock: &sync.Mutex{}, } - w.AddHandler(session.NewModuleHandler("wifi.recon on", "", + mod.AddHandler(session.NewModuleHandler("wifi.recon on", "", "Start 802.11 wireless base stations discovery and channel hopping.", func(args []string) error { - return w.Start() + return mod.Start() })) - w.AddHandler(session.NewModuleHandler("wifi.recon off", "", + mod.AddHandler(session.NewModuleHandler("wifi.recon off", "", "Stop 802.11 wireless base stations discovery and channel hopping.", func(args []string) error { - return w.Stop() + return mod.Stop() })) - w.AddHandler(session.NewModuleHandler("wifi.recon MAC", "wifi.recon ((?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]{2}))", + mod.AddHandler(session.NewModuleHandler("wifi.recon MAC", "wifi.recon ((?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]{2}))", "Set 802.11 base station address to filter for.", func(args []string) error { bssid, err := net.ParseMAC(args[0]) if err != nil { return err - } else if ap, found := w.Session.WiFi.Get(bssid.String()); found { - w.ap = ap - w.stickChan = ap.Channel() + } else if ap, found := mod.Session.WiFi.Get(bssid.String()); found { + mod.ap = ap + mod.stickChan = ap.Channel() return nil } return fmt.Errorf("Could not find station with BSSID %s", args[0]) })) - w.AddHandler(session.NewModuleHandler("wifi.recon clear", "", + mod.AddHandler(session.NewModuleHandler("wifi.recon clear", "", "Remove the 802.11 base station filter.", func(args []string) (err error) { - w.ap = nil - w.stickChan = 0 - w.frequencies, err = network.GetSupportedFrequencies(w.Session.Interface.Name()) - w.hopChanges <- true + mod.ap = nil + mod.stickChan = 0 + mod.frequencies, err = network.GetSupportedFrequencies(mod.Session.Interface.Name()) + mod.hopChanges <- true return err })) - w.AddParam(session.NewIntParameter("wifi.rssi.min", + mod.AddParam(session.NewIntParameter("wifi.rssi.min", "-200", "Minimum WiFi signal strength in dBm.")) - w.AddHandler(session.NewModuleHandler("wifi.deauth BSSID", `wifi\.deauth ((?:[a-fA-F0-9:]{11,})|all|\*)`, + mod.AddHandler(session.NewModuleHandler("wifi.deauth BSSID", `wifi\.deauth ((?:[a-fA-F0-9:]{11,})|all|\*)`, "Start a 802.11 deauth attack, if an access point BSSID is provided, every client will be deauthenticated, otherwise only the selected client. Use 'all', '*' or a broadcast BSSID (ff:ff:ff:ff:ff:ff) to iterate every access point with at least one client and start a deauth attack for each one.", func(args []string) error { if args[0] == "all" || args[0] == "*" { @@ -124,23 +124,23 @@ func NewWiFiModule(s *session.Session) *WiFiModule { if err != nil { return err } - return w.startDeauth(bssid) + return mod.startDeauth(bssid) })) - w.AddParam(session.NewStringParameter("wifi.deauth.skip", + mod.AddParam(session.NewStringParameter("wifi.deauth.skip", "", "", "Comma separated list of BSSID to skip while sending deauth packets.")) - w.AddParam(session.NewBoolParameter("wifi.deauth.silent", + mod.AddParam(session.NewBoolParameter("wifi.deauth.silent", "false", "If true, messages from wifi.deauth will be suppressed.")) - w.AddParam(session.NewBoolParameter("wifi.deauth.open", + mod.AddParam(session.NewBoolParameter("wifi.deauth.open", "true", "Send wifi deauth packets to open networks.")) - w.AddHandler(session.NewModuleHandler("wifi.assoc BSSID", `wifi\.assoc ((?:[a-fA-F0-9:]{11,})|all|\*)`, + mod.AddHandler(session.NewModuleHandler("wifi.assoc BSSID", `wifi\.assoc ((?:[a-fA-F0-9:]{11,})|all|\*)`, "Send an association request to the selected BSSID in order to receive a RSN PMKID key. Use 'all', '*' or a broadcast BSSID (ff:ff:ff:ff:ff:ff) to iterate for every access point.", func(args []string) error { if args[0] == "all" || args[0] == "*" { @@ -150,81 +150,81 @@ func NewWiFiModule(s *session.Session) *WiFiModule { if err != nil { return err } - return w.startAssoc(bssid) + return mod.startAssoc(bssid) })) - w.AddParam(session.NewStringParameter("wifi.assoc.skip", + mod.AddParam(session.NewStringParameter("wifi.assoc.skip", "", "", "Comma separated list of BSSID to skip while sending association requests.")) - w.AddParam(session.NewBoolParameter("wifi.assoc.silent", + mod.AddParam(session.NewBoolParameter("wifi.assoc.silent", "false", "If true, messages from wifi.assoc will be suppressed.")) - w.AddParam(session.NewBoolParameter("wifi.assoc.open", + mod.AddParam(session.NewBoolParameter("wifi.assoc.open", "false", "Send association requests to open networks.")) - w.AddHandler(session.NewModuleHandler("wifi.ap", "", + mod.AddHandler(session.NewModuleHandler("wifi.ap", "", "Inject fake management beacons in order to create a rogue access point.", func(args []string) error { - if err := w.parseApConfig(); err != nil { + if err := mod.parseApConfig(); err != nil { return err } else { - return w.startAp() + return mod.startAp() } })) - w.AddParam(session.NewStringParameter("wifi.handshakes.file", + mod.AddParam(session.NewStringParameter("wifi.handshakes.file", "~/bettercap-wifi-handshakes.pcap", "", "File path of the pcap file to save handshakes to.")) - w.AddParam(session.NewStringParameter("wifi.ap.ssid", + mod.AddParam(session.NewStringParameter("wifi.ap.ssid", "FreeWiFi", "", "SSID of the fake access point.")) - w.AddParam(session.NewStringParameter("wifi.ap.bssid", + mod.AddParam(session.NewStringParameter("wifi.ap.bssid", session.ParamRandomMAC, "[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}", "BSSID of the fake access point.")) - w.AddParam(session.NewIntParameter("wifi.ap.channel", + mod.AddParam(session.NewIntParameter("wifi.ap.channel", "1", "Channel of the fake access point.")) - w.AddParam(session.NewBoolParameter("wifi.ap.encryption", + mod.AddParam(session.NewBoolParameter("wifi.ap.encryption", "true", "If true, the fake access point will use WPA2, otherwise it'll result as an open AP.")) - w.AddHandler(session.NewModuleHandler("wifi.show.wps BSSID", + mod.AddHandler(session.NewModuleHandler("wifi.show.wps BSSID", `wifi\.show\.wps ((?:[a-fA-F0-9:]{11,})|all|\*)`, "Show WPS information about a given station (use 'all', '*' or a broadcast BSSID for all).", func(args []string) error { if args[0] == "all" || args[0] == "*" { args[0] = "ff:ff:ff:ff:ff:ff" } - return w.ShowWPS(args[0]) + return mod.ShowWPS(args[0]) })) - w.AddHandler(session.NewModuleHandler("wifi.show", "", + mod.AddHandler(session.NewModuleHandler("wifi.show", "", "Show current wireless stations list (default sorting by essid).", func(args []string) error { - return w.Show() + return mod.Show() })) - w.selector = utils.ViewSelectorFor(&w.SessionModule, "wifi.show", + mod.selector = utils.ViewSelectorFor(&mod.SessionModule, "wifi.show", []string{"rssi", "bssid", "essid", "channel", "encryption", "clients", "seen", "sent", "rcvd"}, "rssi asc") - w.AddHandler(session.NewModuleHandler("wifi.recon.channel", `wifi\.recon\.channel[\s]+([0-9]+(?:[, ]+[0-9]+)*|clear)`, + mod.AddHandler(session.NewModuleHandler("wifi.recon.channel", `wifi\.recon\.channel[\s]+([0-9]+(?:[, ]+[0-9]+)*|clear)`, "WiFi channels (comma separated) or 'clear' for channel hopping.", func(args []string) (err error) { freqs := []int{} if args[0] != "clear" { - w.Debug("setting hopping channels to %s", args[0]) + mod.Debug("setting hopping channels to %s", args[0]) for _, s := range str.Comma(args[0]) { if ch, err := strconv.Atoi(s); err != nil { return err @@ -239,48 +239,48 @@ func NewWiFiModule(s *session.Session) *WiFiModule { } if len(freqs) == 0 { - w.Debug("resetting hopping channels") - if freqs, err = network.GetSupportedFrequencies(w.Session.Interface.Name()); err != nil { + mod.Debug("resetting hopping channels") + if freqs, err = network.GetSupportedFrequencies(mod.Session.Interface.Name()); err != nil { return err } } - w.Debug("new frequencies: %v", freqs) - w.frequencies = freqs + mod.Debug("new frequencies: %v", freqs) + mod.frequencies = freqs // if wifi.recon is not running, this would block forever - if w.Running() { - w.hopChanges <- true + if mod.Running() { + mod.hopChanges <- true } return nil })) - w.AddParam(session.NewStringParameter("wifi.source.file", + mod.AddParam(session.NewStringParameter("wifi.source.file", "", "", "If set, the wifi module will read from this pcap file instead of the hardware interface.")) - w.AddParam(session.NewIntParameter("wifi.hop.period", + mod.AddParam(session.NewIntParameter("wifi.hop.period", "250", "If channel hopping is enabled (empty wifi.recon.channel), this is the time in milliseconds the algorithm will hop on every channel (it'll be doubled if both 2.4 and 5.0 bands are available).")) - w.AddParam(session.NewBoolParameter("wifi.skip-broken", + mod.AddParam(session.NewBoolParameter("wifi.skip-broken", "true", "If true, dot11 packets with an invalid checksum will be skipped.")) - return w + return mod } -func (w WiFiModule) Name() string { +func (mod WiFiModule) Name() string { return "wifi" } -func (w WiFiModule) Description() string { +func (mod WiFiModule) Description() string { return "A module to monitor and perform wireless attacks on 802.11." } -func (w WiFiModule) Author() string { +func (mod WiFiModule) Author() string { return "Simone Margaritelli && Gianluca Braga " } @@ -290,31 +290,31 @@ const ( ErrIfaceNotUp = "Interface Not Up" ) -func (w *WiFiModule) Configure() error { +func (mod *WiFiModule) Configure() error { var hopPeriod int var err error - if err, w.source = w.StringParam("wifi.source.file"); err != nil { + if err, mod.source = mod.StringParam("wifi.source.file"); err != nil { return err } - if err, w.shakesFile = w.StringParam("wifi.handshakes.file"); err != nil { + if err, mod.shakesFile = mod.StringParam("wifi.handshakes.file"); err != nil { return err - } else if w.shakesFile != "" { - if w.shakesFile, err = fs.Expand(w.shakesFile); err != nil { + } else if mod.shakesFile != "" { + if mod.shakesFile, err = fs.Expand(mod.shakesFile); err != nil { return err } } - if err, w.minRSSI = w.IntParam("wifi.rssi.min"); err != nil { + if err, mod.minRSSI = mod.IntParam("wifi.rssi.min"); err != nil { return err } - ifName := w.Session.Interface.Name() + ifName := mod.Session.Interface.Name() - if w.source != "" { - if w.handle, err = pcap.OpenOffline(w.source); err != nil { - return fmt.Errorf("error while opening file %s: %s", w.source, err) + if mod.source != "" { + if mod.handle, err = pcap.OpenOffline(mod.source); err != nil { + return fmt.Errorf("error while opening file %s: %s", mod.source, err) } } else { for retry := 0; ; retry++ { @@ -336,9 +336,9 @@ func (w *WiFiModule) Configure() error { readTimeout := 500 * time.Millisecond if err = ihandle.SetTimeout(readTimeout); err != nil { return fmt.Errorf("error while setting timeout: %s", err) - } else if w.handle, err = ihandle.Activate(); err != nil { + } else if mod.handle, err = ihandle.Activate(); err != nil { if retry == 0 && err.Error() == ErrIfaceNotUp { - w.Warning("interface %s is down, bringing it up ...", ifName) + mod.Warning("interface %s is down, bringing it up ...", ifName) if err := network.ActivateInterface(ifName); err != nil { return err } @@ -351,39 +351,39 @@ func (w *WiFiModule) Configure() error { } } - if err, w.skipBroken = w.BoolParam("wifi.skip-broken"); err != nil { + if err, mod.skipBroken = mod.BoolParam("wifi.skip-broken"); err != nil { return err - } else if err, hopPeriod = w.IntParam("wifi.hop.period"); err != nil { + } else if err, hopPeriod = mod.IntParam("wifi.hop.period"); err != nil { return err } - w.hopPeriod = time.Duration(hopPeriod) * time.Millisecond + mod.hopPeriod = time.Duration(hopPeriod) * time.Millisecond - if w.source == "" { + if mod.source == "" { // No channels setted, retrieve frequencies supported by the card - if len(w.frequencies) == 0 { - if w.frequencies, err = network.GetSupportedFrequencies(ifName); err != nil { + if len(mod.frequencies) == 0 { + if mod.frequencies, err = network.GetSupportedFrequencies(ifName); err != nil { return fmt.Errorf("error while getting supported frequencies of %s: %s", ifName, err) } - w.Debug("wifi supported frequencies: %v", w.frequencies) + mod.Debug("wifi supported frequencies: %v", mod.frequencies) // we need to start somewhere, this is just to check if // this OS supports switching channel programmatically. if err = network.SetInterfaceChannel(ifName, 1); err != nil { return fmt.Errorf("error while initializing %s to channel 1: %s", ifName, err) } - w.Info("started (min rssi: %d dBm)", w.minRSSI) + mod.Info("started (min rssi: %d dBm)", mod.minRSSI) } } return nil } -func (w *WiFiModule) updateInfo(dot11 *layers.Dot11, packet gopacket.Packet) { +func (mod *WiFiModule) updateInfo(dot11 *layers.Dot11, packet gopacket.Packet) { if ok, enc, cipher, auth := packets.Dot11ParseEncryption(packet, dot11); ok { bssid := dot11.Address3.String() - if station, found := w.Session.WiFi.Get(bssid); found { + if station, found := mod.Session.WiFi.Get(bssid); found { station.Encryption = enc station.Cipher = cipher station.Authentication = auth @@ -391,7 +391,7 @@ func (w *WiFiModule) updateInfo(dot11 *layers.Dot11, packet gopacket.Packet) { } if ok, bssid, info := packets.Dot11ParseWPS(packet, dot11); ok { - if station, found := w.Session.WiFi.Get(bssid.String()); found { + if station, found := mod.Session.WiFi.Get(bssid.String()); found { for name, value := range info { station.WPS[name] = value } @@ -399,84 +399,84 @@ func (w *WiFiModule) updateInfo(dot11 *layers.Dot11, packet gopacket.Packet) { } } -func (w *WiFiModule) updateStats(dot11 *layers.Dot11, packet gopacket.Packet) { +func (mod *WiFiModule) updateStats(dot11 *layers.Dot11, packet gopacket.Packet) { // collect stats from data frames if dot11.Type.MainType() == layers.Dot11TypeData { bytes := uint64(len(packet.Data())) dst := dot11.Address1.String() - if station, found := w.Session.WiFi.Get(dst); found { + if station, found := mod.Session.WiFi.Get(dst); found { station.Received += bytes } src := dot11.Address2.String() - if station, found := w.Session.WiFi.Get(src); found { + if station, found := mod.Session.WiFi.Get(src); found { station.Sent += bytes } } } -func (w *WiFiModule) Start() error { - if err := w.Configure(); err != nil { +func (mod *WiFiModule) Start() error { + if err := mod.Configure(); err != nil { return err } - w.SetRunning(true, func() { + mod.SetRunning(true, func() { // start channel hopper if needed - if w.channel == 0 && w.source == "" { - go w.channelHopper() + if mod.channel == 0 && mod.source == "" { + go mod.channelHopper() } // start the pruner - go w.stationPruner() + go mod.stationPruner() - w.reads.Add(1) - defer w.reads.Done() + mod.reads.Add(1) + defer mod.reads.Done() - src := gopacket.NewPacketSource(w.handle, w.handle.LinkType()) - w.pktSourceChan = src.Packets() - for packet := range w.pktSourceChan { - if !w.Running() { + src := gopacket.NewPacketSource(mod.handle, mod.handle.LinkType()) + mod.pktSourceChan = src.Packets() + for packet := range mod.pktSourceChan { + if !mod.Running() { break } else if packet == nil { continue } - w.Session.Queue.TrackPacket(uint64(len(packet.Data()))) + mod.Session.Queue.TrackPacket(uint64(len(packet.Data()))) // perform initial dot11 parsing and layers validation if ok, radiotap, dot11 := packets.Dot11Parse(packet); ok { // check FCS checksum - if w.skipBroken && !dot11.ChecksumValid() { - w.Debug("skipping dot11 packet with invalid checksum.") + if mod.skipBroken && !dot11.ChecksumValid() { + mod.Debug("skipping dot11 packet with invalid checksum.") continue } - w.discoverProbes(radiotap, dot11, packet) - w.discoverAccessPoints(radiotap, dot11, packet) - w.discoverClients(radiotap, dot11, packet) - w.discoverHandshakes(radiotap, dot11, packet) - w.updateInfo(dot11, packet) - w.updateStats(dot11, packet) + mod.discoverProbes(radiotap, dot11, packet) + mod.discoverAccessPoints(radiotap, dot11, packet) + mod.discoverClients(radiotap, dot11, packet) + mod.discoverHandshakes(radiotap, dot11, packet) + mod.updateInfo(dot11, packet) + mod.updateStats(dot11, packet) } } - w.pktSourceChanClosed = true + mod.pktSourceChanClosed = true }) return nil } -func (w *WiFiModule) Stop() error { - return w.SetRunning(false, func() { +func (mod *WiFiModule) Stop() error { + return mod.SetRunning(false, func() { // wait any pending write operation - w.writes.Wait() + mod.writes.Wait() // signal the main for loop we want to exit - if !w.pktSourceChanClosed { - w.pktSourceChan <- nil + if !mod.pktSourceChanClosed { + mod.pktSourceChan <- nil } - w.reads.Wait() + mod.reads.Wait() // close the pcap handle to make the main for exit - w.handle.Close() + mod.handle.Close() }) } diff --git a/modules/wifi/wifi_ap.go b/modules/wifi/wifi_ap.go index 751e9568..fcc4c29a 100644 --- a/modules/wifi/wifi_ap.go +++ b/modules/wifi/wifi_ap.go @@ -14,54 +14,54 @@ import ( var errNoRecon = errors.New("Module wifi.ap requires module wifi.recon to be activated.") -func (w *WiFiModule) parseApConfig() (err error) { +func (mod *WiFiModule) parseApConfig() (err error) { var bssid string - if err, w.apConfig.SSID = w.StringParam("wifi.ap.ssid"); err != nil { + if err, mod.apConfig.SSID = mod.StringParam("wifi.ap.ssid"); err != nil { return - } else if err, bssid = w.StringParam("wifi.ap.bssid"); err != nil { + } else if err, bssid = mod.StringParam("wifi.ap.bssid"); err != nil { return - } else if w.apConfig.BSSID, err = net.ParseMAC(network.NormalizeMac(bssid)); err != nil { + } else if mod.apConfig.BSSID, err = net.ParseMAC(network.NormalizeMac(bssid)); err != nil { return - } else if err, w.apConfig.Channel = w.IntParam("wifi.ap.channel"); err != nil { + } else if err, mod.apConfig.Channel = mod.IntParam("wifi.ap.channel"); err != nil { return - } else if err, w.apConfig.Encryption = w.BoolParam("wifi.ap.encryption"); err != nil { + } else if err, mod.apConfig.Encryption = mod.BoolParam("wifi.ap.encryption"); err != nil { return } return } -func (w *WiFiModule) startAp() error { +func (mod *WiFiModule) startAp() error { // we need channel hopping and packet injection for this - if !w.Running() { + if !mod.Running() { return errNoRecon - } else if w.apRunning { + } else if mod.apRunning { return session.ErrAlreadyStarted } go func() { - w.apRunning = true + mod.apRunning = true defer func() { - w.apRunning = false + mod.apRunning = false }() enc := tui.Yellow("WPA2") - if !w.apConfig.Encryption { + if !mod.apConfig.Encryption { enc = tui.Green("Open") } - w.Info("sending beacons as SSID %s (%s) on channel %d (%s).", - tui.Bold(w.apConfig.SSID), - w.apConfig.BSSID.String(), - w.apConfig.Channel, + mod.Info("sending beacons as SSID %s (%s) on channel %d (%s).", + tui.Bold(mod.apConfig.SSID), + mod.apConfig.BSSID.String(), + mod.apConfig.Channel, enc) - for seqn := uint16(0); w.Running(); seqn++ { - w.writes.Add(1) - defer w.writes.Done() + for seqn := uint16(0); mod.Running(); seqn++ { + mod.writes.Add(1) + defer mod.writes.Done() - if err, pkt := packets.NewDot11Beacon(w.apConfig, seqn); err != nil { - w.Error("could not create beacon packet: %s", err) + if err, pkt := packets.NewDot11Beacon(mod.apConfig, seqn); err != nil { + mod.Error("could not create beacon packet: %s", err) } else { - w.injectPacket(pkt) + mod.injectPacket(pkt) } time.Sleep(100 * time.Millisecond) diff --git a/modules/wifi/wifi_assoc.go b/modules/wifi/wifi_assoc.go index 89483a30..ff3524cd 100644 --- a/modules/wifi/wifi_assoc.go +++ b/modules/wifi/wifi_assoc.go @@ -10,22 +10,22 @@ import ( "github.com/bettercap/bettercap/packets" ) -func (w *WiFiModule) sendAssocPacket(ap *network.AccessPoint) { - if err, pkt := packets.NewDot11Auth(w.Session.Interface.HW, ap.HW, 1); err != nil { - w.Error("cloud not create auth packet: %s", err) +func (mod *WiFiModule) sendAssocPacket(ap *network.AccessPoint) { + if err, pkt := packets.NewDot11Auth(mod.Session.Interface.HW, ap.HW, 1); err != nil { + mod.Error("cloud not create auth packet: %s", err) } else { - w.injectPacket(pkt) + mod.injectPacket(pkt) } - if err, pkt := packets.NewDot11AssociationRequest(w.Session.Interface.HW, ap.HW, ap.ESSID(), 1); err != nil { - w.Error("cloud not create association request packet: %s", err) + if err, pkt := packets.NewDot11AssociationRequest(mod.Session.Interface.HW, ap.HW, ap.ESSID(), 1); err != nil { + mod.Error("cloud not create association request packet: %s", err) } else { - w.injectPacket(pkt) + mod.injectPacket(pkt) } } -func (w *WiFiModule) skipAssoc(to net.HardwareAddr) bool { - for _, mac := range w.assocSkip { +func (mod *WiFiModule) skipAssoc(to net.HardwareAddr) bool { + for _, mac := range mod.assocSkip { if bytes.Equal(to, mac) { return true } @@ -33,51 +33,51 @@ func (w *WiFiModule) skipAssoc(to net.HardwareAddr) bool { return false } -func (w *WiFiModule) isAssocSilent() bool { - if err, is := w.BoolParam("wifi.assoc.silent"); err != nil { - w.Warning("%v", err) +func (mod *WiFiModule) isAssocSilent() bool { + if err, is := mod.BoolParam("wifi.assoc.silent"); err != nil { + mod.Warning("%v", err) } else { - w.assocSilent = is + mod.assocSilent = is } - return w.assocSilent + return mod.assocSilent } -func (w *WiFiModule) doAssocOpen() bool { - if err, is := w.BoolParam("wifi.assoc.open"); err != nil { - w.Warning("%v", err) +func (mod *WiFiModule) doAssocOpen() bool { + if err, is := mod.BoolParam("wifi.assoc.open"); err != nil { + mod.Warning("%v", err) } else { - w.assocOpen = is + mod.assocOpen = is } - return w.assocOpen + return mod.assocOpen } -func (w *WiFiModule) startAssoc(to net.HardwareAddr) error { +func (mod *WiFiModule) startAssoc(to net.HardwareAddr) error { // parse skip list - if err, assocSkip := w.StringParam("wifi.assoc.skip"); err != nil { + if err, assocSkip := mod.StringParam("wifi.assoc.skip"); err != nil { return err } else if macs, err := network.ParseMACs(assocSkip); err != nil { return err } else { - w.assocSkip = macs + mod.assocSkip = macs } // if not already running, temporarily enable the pcap handle // for packet injection - if !w.Running() { - if err := w.Configure(); err != nil { + if !mod.Running() { + if err := mod.Configure(); err != nil { return err } - defer w.handle.Close() + defer mod.handle.Close() } toAssoc := make([]*network.AccessPoint, 0) isBcast := network.IsBroadcastMac(to) - for _, ap := range w.Session.WiFi.List() { + for _, ap := range mod.Session.WiFi.List() { if isBcast || bytes.Equal(ap.HW, to) { - if !w.skipAssoc(ap.HW) { + if !mod.skipAssoc(ap.HW) { toAssoc = append(toAssoc, ap) } else { - w.Debug("skipping ap:%v because skip list %v", ap, w.assocSkip) + mod.Debug("skipping ap:%v because skip list %v", ap, mod.assocSkip) } } } @@ -90,8 +90,8 @@ func (w *WiFiModule) startAssoc(to net.HardwareAddr) error { } go func() { - w.writes.Add(1) - defer w.writes.Done() + mod.writes.Add(1) + defer mod.writes.Done() // since we need to change the wifi adapter channel for each // association request, let's sort by channel so we do the minimum @@ -102,19 +102,19 @@ func (w *WiFiModule) startAssoc(to net.HardwareAddr) error { // send the association request frames for _, ap := range toAssoc { - if w.Running() { - logger := w.Info - if w.isAssocSilent() { - logger = w.Debug + if mod.Running() { + logger := mod.Info + if mod.isAssocSilent() { + logger = mod.Debug } - if ap.IsOpen() && !w.doAssocOpen() { - w.Debug("skipping association for open network %s (wifi.assoc.open is false)", ap.ESSID()) + if ap.IsOpen() && !mod.doAssocOpen() { + mod.Debug("skipping association for open network %s (wifi.assoc.open is false)", ap.ESSID()) } else { logger("sending association request to AP %s (channel:%d encryption:%s)", ap.ESSID(), ap.Channel(), ap.Encryption) - w.onChannel(ap.Channel(), func() { - w.sendAssocPacket(ap) + mod.onChannel(ap.Channel(), func() { + mod.sendAssocPacket(ap) }) } } diff --git a/modules/wifi/wifi_deauth.go b/modules/wifi/wifi_deauth.go index db663634..a4522a13 100644 --- a/modules/wifi/wifi_deauth.go +++ b/modules/wifi/wifi_deauth.go @@ -11,37 +11,37 @@ import ( "github.com/bettercap/bettercap/packets" ) -func (w *WiFiModule) injectPacket(data []byte) { - if err := w.handle.WritePacketData(data); err != nil { - w.Error("could not inject WiFi packet: %s", err) - w.Session.Queue.TrackError() +func (mod *WiFiModule) injectPacket(data []byte) { + if err := mod.handle.WritePacketData(data); err != nil { + mod.Error("could not inject WiFi packet: %s", err) + mod.Session.Queue.TrackError() } else { - w.Session.Queue.TrackSent(uint64(len(data))) + mod.Session.Queue.TrackSent(uint64(len(data))) } // let the network card breath a little time.Sleep(10 * time.Millisecond) } -func (w *WiFiModule) sendDeauthPacket(ap net.HardwareAddr, client net.HardwareAddr) { - for seq := uint16(0); seq < 64 && w.Running(); seq++ { +func (mod *WiFiModule) sendDeauthPacket(ap net.HardwareAddr, client net.HardwareAddr) { + for seq := uint16(0); seq < 64 && mod.Running(); seq++ { if err, pkt := packets.NewDot11Deauth(ap, client, ap, seq); err != nil { - w.Error("could not create deauth packet: %s", err) + mod.Error("could not create deauth packet: %s", err) continue } else { - w.injectPacket(pkt) + mod.injectPacket(pkt) } if err, pkt := packets.NewDot11Deauth(client, ap, ap, seq); err != nil { - w.Error("could not create deauth packet: %s", err) + mod.Error("could not create deauth packet: %s", err) continue } else { - w.injectPacket(pkt) + mod.injectPacket(pkt) } } } -func (w *WiFiModule) skipDeauth(to net.HardwareAddr) bool { - for _, mac := range w.deauthSkip { +func (mod *WiFiModule) skipDeauth(to net.HardwareAddr) bool { + for _, mac := range mod.deauthSkip { if bytes.Equal(to, mac) { return true } @@ -49,41 +49,41 @@ func (w *WiFiModule) skipDeauth(to net.HardwareAddr) bool { return false } -func (w *WiFiModule) isDeauthSilent() bool { - if err, is := w.BoolParam("wifi.deauth.silent"); err != nil { - w.Warning("%v", err) +func (mod *WiFiModule) isDeauthSilent() bool { + if err, is := mod.BoolParam("wifi.deauth.silent"); err != nil { + mod.Warning("%v", err) } else { - w.deauthSilent = is + mod.deauthSilent = is } - return w.deauthSilent + return mod.deauthSilent } -func (w *WiFiModule) doDeauthOpen() bool { - if err, is := w.BoolParam("wifi.deauth.open"); err != nil { - w.Warning("%v", err) +func (mod *WiFiModule) doDeauthOpen() bool { + if err, is := mod.BoolParam("wifi.deauth.open"); err != nil { + mod.Warning("%v", err) } else { - w.deauthOpen = is + mod.deauthOpen = is } - return w.deauthOpen + return mod.deauthOpen } -func (w *WiFiModule) startDeauth(to net.HardwareAddr) error { +func (mod *WiFiModule) startDeauth(to net.HardwareAddr) error { // parse skip list - if err, deauthSkip := w.StringParam("wifi.deauth.skip"); err != nil { + if err, deauthSkip := mod.StringParam("wifi.deauth.skip"); err != nil { return err } else if macs, err := network.ParseMACs(deauthSkip); err != nil { return err } else { - w.deauthSkip = macs + mod.deauthSkip = macs } // if not already running, temporarily enable the pcap handle // for packet injection - if !w.Running() { - if err := w.Configure(); err != nil { + if !mod.Running() { + if err := mod.Configure(); err != nil { return err } - defer w.handle.Close() + defer mod.handle.Close() } type flow struct { @@ -93,14 +93,14 @@ func (w *WiFiModule) startDeauth(to net.HardwareAddr) error { toDeauth := make([]flow, 0) isBcast := network.IsBroadcastMac(to) - for _, ap := range w.Session.WiFi.List() { + for _, ap := range mod.Session.WiFi.List() { isAP := bytes.Equal(ap.HW, to) for _, client := range ap.Clients() { if isBcast || isAP || bytes.Equal(client.HW, to) { - if !w.skipDeauth(ap.HW) && !w.skipDeauth(client.HW) { + if !mod.skipDeauth(ap.HW) && !mod.skipDeauth(client.HW) { toDeauth = append(toDeauth, flow{Ap: ap, Client: client}) } else { - w.Debug("skipping ap:%v client:%v because skip list %v", ap, client, w.deauthSkip) + mod.Debug("skipping ap:%v client:%v because skip list %v", ap, client, mod.deauthSkip) } } } @@ -114,8 +114,8 @@ func (w *WiFiModule) startDeauth(to net.HardwareAddr) error { } go func() { - w.writes.Add(1) - defer w.writes.Done() + mod.writes.Add(1) + defer mod.writes.Done() // since we need to change the wifi adapter channel for each // deauth packet, let's sort by channel so we do the minimum @@ -128,19 +128,19 @@ func (w *WiFiModule) startDeauth(to net.HardwareAddr) error { for _, deauth := range toDeauth { client := deauth.Client ap := deauth.Ap - if w.Running() { - logger := w.Info - if w.isDeauthSilent() { - logger = w.Debug + if mod.Running() { + logger := mod.Info + if mod.isDeauthSilent() { + logger = mod.Debug } - if ap.IsOpen() && !w.doDeauthOpen() { - w.Debug("skipping deauth for open network %s (wifi.deauth.open is false)", ap.ESSID()) + if ap.IsOpen() && !mod.doDeauthOpen() { + mod.Debug("skipping deauth for open network %s (wifi.deauth.open is false)", ap.ESSID()) } else { logger("deauthing client %s from AP %s (channel:%d encryption:%s)", client.String(), ap.ESSID(), ap.Channel(), ap.Encryption) - w.onChannel(ap.Channel(), func() { - w.sendDeauthPacket(ap.HW, client.HW) + mod.onChannel(ap.Channel(), func() { + mod.sendDeauthPacket(ap.HW, client.HW) }) } } diff --git a/modules/wifi/wifi_events.go b/modules/wifi/wifi_events.go index 0f33e95f..d455c9e7 100644 --- a/modules/wifi/wifi_events.go +++ b/modules/wifi/wifi_events.go @@ -6,12 +6,12 @@ import ( "github.com/bettercap/bettercap/network" ) -type WiFiClientEvent struct { +type ClientEvent struct { AP *network.AccessPoint Client *network.Station } -type WiFiProbeEvent struct { +type ProbeEvent struct { FromAddr net.HardwareAddr FromVendor string FromAlias string @@ -19,7 +19,7 @@ type WiFiProbeEvent struct { RSSI int8 } -type WiFiHandshakeEvent struct { +type HandshakeEvent struct { File string NewPackets int AP net.HardwareAddr diff --git a/modules/wifi/wifi_hopping.go b/modules/wifi/wifi_hopping.go index 076915ae..80a2c0c2 100644 --- a/modules/wifi/wifi_hopping.go +++ b/modules/wifi/wifi_hopping.go @@ -6,64 +6,64 @@ import ( "github.com/bettercap/bettercap/network" ) -func (w *WiFiModule) onChannel(channel int, cb func()) { - w.chanLock.Lock() - defer w.chanLock.Unlock() +func (mod *WiFiModule) onChannel(channel int, cb func()) { + mod.chanLock.Lock() + defer mod.chanLock.Unlock() - prev := w.stickChan - w.stickChan = channel + prev := mod.stickChan + mod.stickChan = channel - if err := network.SetInterfaceChannel(w.Session.Interface.Name(), channel); err != nil { - w.Warning("error while hopping to channel %d: %s", channel, err) + if err := network.SetInterfaceChannel(mod.Session.Interface.Name(), channel); err != nil { + mod.Warning("error while hopping to channel %d: %s", channel, err) } else { - w.Debug("hopped on channel %d", channel) + mod.Debug("hopped on channel %d", channel) } cb() - w.stickChan = prev + mod.stickChan = prev } -func (w *WiFiModule) channelHopper() { - w.reads.Add(1) - defer w.reads.Done() +func (mod *WiFiModule) channelHopper() { + mod.reads.Add(1) + defer mod.reads.Done() - w.Info("channel hopper started.") + mod.Info("channel hopper started.") - for w.Running() { - delay := w.hopPeriod + for mod.Running() { + delay := mod.hopPeriod // if we have both 2.4 and 5ghz capabilities, we have // more channels, therefore we need to increase the time // we hop on each one otherwise me lose information - if len(w.frequencies) > 14 { + if len(mod.frequencies) > 14 { delay = delay * 2 } - frequencies := w.frequencies + frequencies := mod.frequencies loopCurrentChannels: for _, frequency := range frequencies { channel := network.Dot11Freq2Chan(frequency) // stick to the access point channel as long as it's selected // or as long as we're deauthing on it - if w.stickChan != 0 { - channel = w.stickChan + if mod.stickChan != 0 { + channel = mod.stickChan } - w.Debug("hopping on channel %d", channel) + mod.Debug("hopping on channel %d", channel) - w.chanLock.Lock() - if err := network.SetInterfaceChannel(w.Session.Interface.Name(), channel); err != nil { - w.Warning("error while hopping to channel %d: %s", channel, err) + mod.chanLock.Lock() + if err := network.SetInterfaceChannel(mod.Session.Interface.Name(), channel); err != nil { + mod.Warning("error while hopping to channel %d: %s", channel, err) } - w.chanLock.Unlock() + mod.chanLock.Unlock() select { - case _ = <-w.hopChanges: - w.Debug("hop changed") + case _ = <-mod.hopChanges: + mod.Debug("hop changed") break loopCurrentChannels case <-time.After(delay): - if !w.Running() { + if !mod.Running() { return } } diff --git a/modules/wifi/wifi_recon.go b/modules/wifi/wifi_recon.go index a733c1f9..c61129e1 100644 --- a/modules/wifi/wifi_recon.go +++ b/modules/wifi/wifi_recon.go @@ -13,28 +13,28 @@ import ( var maxStationTTL = 5 * time.Minute -func (w *WiFiModule) stationPruner() { - w.reads.Add(1) - defer w.reads.Done() +func (mod *WiFiModule) stationPruner() { + mod.reads.Add(1) + defer mod.reads.Done() - w.Debug("wifi stations pruner started.") - for w.Running() { + mod.Debug("wifi stations pruner started.") + for mod.Running() { // loop every AP - for _, ap := range w.Session.WiFi.List() { + for _, ap := range mod.Session.WiFi.List() { sinceLastSeen := time.Since(ap.LastSeen) if sinceLastSeen > maxStationTTL { - w.Debug("station %s not seen in %s, removing.", ap.BSSID(), sinceLastSeen) - w.Session.WiFi.Remove(ap.BSSID()) + mod.Debug("station %s not seen in %s, removing.", ap.BSSID(), sinceLastSeen) + mod.Session.WiFi.Remove(ap.BSSID()) continue } // loop every AP client for _, c := range ap.Clients() { sinceLastSeen := time.Since(c.LastSeen) if sinceLastSeen > maxStationTTL { - w.Debug("client %s of station %s not seen in %s, removing.", c.String(), ap.BSSID(), sinceLastSeen) + mod.Debug("client %s of station %s not seen in %s, removing.", c.String(), ap.BSSID(), sinceLastSeen) ap.RemoveClient(c.BSSID()) - w.Session.Events.Add("wifi.client.lost", WiFiClientEvent{ + mod.Session.Events.Add("wifi.client.lost", ClientEvent{ AP: ap, Client: c, }) @@ -45,18 +45,18 @@ func (w *WiFiModule) stationPruner() { } } -func (w *WiFiModule) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) { +func (mod *WiFiModule) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) { // search for Dot11InformationElementIDSSID if ok, ssid := packets.Dot11ParseIDSSID(packet); ok { from := dot11.Address3 // skip stuff we're sending - if w.apRunning && bytes.Equal(from, w.apConfig.BSSID) { + if mod.apRunning && bytes.Equal(from, mod.apConfig.BSSID) { return } if !network.IsZeroMac(from) && !network.IsBroadcastMac(from) { - if int(radiotap.DBMAntennaSignal) >= w.minRSSI { + if int(radiotap.DBMAntennaSignal) >= mod.minRSSI { var frequency int bssid := from.String() @@ -66,19 +66,19 @@ func (w *WiFiModule) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *laye frequency = int(radiotap.ChannelFrequency) } - if ap, isNew := w.Session.WiFi.AddIfNew(ssid, bssid, frequency, radiotap.DBMAntennaSignal); !isNew { + if ap, isNew := mod.Session.WiFi.AddIfNew(ssid, bssid, frequency, radiotap.DBMAntennaSignal); !isNew { ap.EachClient(func(mac string, station *network.Station) { station.Handshake.SetBeacon(packet) }) } } else { - w.Debug("skipping %s with %d dBm", from.String(), radiotap.DBMAntennaSignal) + mod.Debug("skipping %s with %d dBm", from.String(), radiotap.DBMAntennaSignal) } } } } -func (w *WiFiModule) discoverProbes(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) { +func (mod *WiFiModule) discoverProbes(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) { if dot11.Type != layers.Dot11TypeMgmtProbeReq { return } @@ -107,17 +107,17 @@ func (w *WiFiModule) discoverProbes(radiotap *layers.RadioTap, dot11 *layers.Dot return } - w.Session.Events.Add("wifi.client.probe", WiFiProbeEvent{ + mod.Session.Events.Add("wifi.client.probe", ProbeEvent{ FromAddr: dot11.Address2, FromVendor: network.ManufLookup(dot11.Address2.String()), - FromAlias: w.Session.Lan.GetAlias(dot11.Address2.String()), + FromAlias: mod.Session.Lan.GetAlias(dot11.Address2.String()), SSID: string(req.Contents[2 : 2+size]), RSSI: radiotap.DBMAntennaSignal, }) } -func (w *WiFiModule) discoverClients(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) { - w.Session.WiFi.EachAccessPoint(func(bssid string, ap *network.AccessPoint) { +func (mod *WiFiModule) discoverClients(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) { + mod.Session.WiFi.EachAccessPoint(func(bssid string, ap *network.AccessPoint) { // packet going to this specific BSSID? if packets.Dot11IsDataFor(dot11, ap.HW) { bssid := dot11.Address2.String() @@ -125,7 +125,7 @@ func (w *WiFiModule) discoverClients(radiotap *layers.RadioTap, dot11 *layers.Do rssi := radiotap.DBMAntennaSignal if station, isNew := ap.AddClientIfNew(bssid, freq, rssi); isNew { - w.Session.Events.Add("wifi.client.new", WiFiClientEvent{ + mod.Session.Events.Add("wifi.client.new", ClientEvent{ AP: ap, Client: station, }) @@ -143,12 +143,12 @@ func allZeros(s []byte) bool { return true } -func (w *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) { +func (mod *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) { if ok, key, apMac, staMac := packets.Dot11ParseEAPOL(packet, dot11); ok { // first, locate the AP in our list by its BSSID - ap, found := w.Session.WiFi.Get(apMac.String()) + ap, found := mod.Session.WiFi.Get(apMac.String()) if !found { - w.Warning("could not find AP with BSSID %s", apMac.String()) + mod.Warning("could not find AP with BSSID %s", apMac.String()) return } @@ -158,7 +158,7 @@ func (w *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers // (Reference about PMKID https://hashcat.net/forum/thread-7717.html) // In this case, we need to add ourselves as a client station of the AP // in order to have a consistent association of AP, client and handshakes. - staIsUs := bytes.Equal(staMac, w.Session.Interface.HW) + staIsUs := bytes.Equal(staMac, mod.Session.Interface.HW) station, found := ap.Get(staMac.String()) if !found { station, _ = ap.AddClientIfNew(staMac.String(), ap.Frequency, ap.RSSI) @@ -173,7 +173,7 @@ func (w *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers PMKID = "with PMKID" } - w.Debug("got frame 1/4 of the %s <-> %s handshake (%s) (anonce:%x)", + mod.Debug("got frame 1/4 of the %s <-> %s handshake (%s) (anonce:%x)", apMac, staMac, PMKID, @@ -182,7 +182,7 @@ func (w *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers // [2] (MIC) client is sending SNonce+MIC to the API station.Handshake.AddFrame(1, packet) - w.Debug("got frame 2/4 of the %s <-> %s handshake (snonce:%x mic:%x)", + mod.Debug("got frame 2/4 of the %s <-> %s handshake (snonce:%x mic:%x)", apMac, staMac, key.Nonce, @@ -191,7 +191,7 @@ func (w *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers // [3]: (INSTALL+ACK+MIC) AP informs the client that the PTK is installed station.Handshake.AddFrame(2, packet) - w.Debug("got frame 3/4 of the %s <-> %s handshake (mic:%x)", + mod.Debug("got frame 3/4 of the %s <-> %s handshake (mic:%x)", apMac, staMac, key.MIC) @@ -200,18 +200,18 @@ func (w *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers // if we have unsaved packets as part of the handshake, save them. numUnsaved := station.Handshake.NumUnsaved() doSave := numUnsaved > 0 - if doSave && w.shakesFile != "" { - w.Debug("saving handshake frames to %s", w.shakesFile) - if err := w.Session.WiFi.SaveHandshakesTo(w.shakesFile, w.handle.LinkType()); err != nil { - w.Error("error while saving handshake frames to %s: %s", w.shakesFile, err) + if doSave && mod.shakesFile != "" { + mod.Debug("saving handshake frames to %s", mod.shakesFile) + if err := mod.Session.WiFi.SaveHandshakesTo(mod.shakesFile, mod.handle.LinkType()); err != nil { + mod.Error("error while saving handshake frames to %s: %s", mod.shakesFile, err) } } // if we had unsaved packets and either the handshake is complete // or it contains the PMKID, generate a new event. if doSave && (rawPMKID != nil || station.Handshake.Complete()) { - w.Session.Events.Add("wifi.client.handshake", WiFiHandshakeEvent{ - File: w.shakesFile, + mod.Session.Events.Add("wifi.client.handshake", HandshakeEvent{ + File: mod.shakesFile, NewPackets: numUnsaved, AP: apMac, Station: staMac, diff --git a/modules/wifi/wifi_show.go b/modules/wifi/wifi_show.go index 139b45ca..9a556fad 100644 --- a/modules/wifi/wifi_show.go +++ b/modules/wifi/wifi_show.go @@ -8,7 +8,7 @@ import ( "strings" "time" - "github.com/bettercap/bettercap/modules/discovery" + "github.com/bettercap/bettercap/modules/net_recon" "github.com/bettercap/bettercap/network" "github.com/dustin/go-humanize" @@ -17,11 +17,11 @@ import ( "github.com/evilsocket/islazy/tui" ) -func (w *WiFiModule) isApSelected() bool { - return w.ap != nil +func (mod *WiFiModule) isApSelected() bool { + return mod.ap != nil } -func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) { +func (mod *WiFiModule) getRow(station *network.Station) ([]string, bool) { // ref. https://www.metageek.com/training/resources/understanding-rssi-2.html rssi := fmt.Sprintf("%d dBm", station.RSSI) if station.RSSI >= -67 { @@ -35,19 +35,19 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) { } bssid := station.HwAddress - sinceStarted := time.Since(w.Session.StartedAt) + sinceStarted := time.Since(mod.Session.StartedAt) sinceFirstSeen := time.Since(station.FirstSeen) - if sinceStarted > (discovery.JustJoinedTimeInterval*2) && sinceFirstSeen <= discovery.JustJoinedTimeInterval { + if sinceStarted > (net_recon.JustJoinedTimeInterval*2) && sinceFirstSeen <= net_recon.JustJoinedTimeInterval { // if endpoint was first seen in the last 10 seconds bssid = tui.Bold(bssid) } seen := station.LastSeen.Format("15:04:05") sinceLastSeen := time.Since(station.LastSeen) - if sinceStarted > discovery.AliveTimeInterval && sinceLastSeen <= discovery.AliveTimeInterval { + if sinceStarted > net_recon.AliveTimeInterval && sinceLastSeen <= net_recon.AliveTimeInterval { // if endpoint seen in the last 10 seconds seen = tui.Bold(seen) - } else if sinceLastSeen > discovery.PresentTimeInterval { + } else if sinceLastSeen > net_recon.PresentTimeInterval { // if endpoint not seen in the last 60 seconds seen = tui.Dim(seen) } @@ -67,7 +67,7 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) { // this is ugly, but necessary in order to have this // method handle both access point and clients // transparently - if ap, found := w.Session.WiFi.Get(station.HwAddress); found && (ap.HasHandshakes() || ap.HasPMKID()) { + if ap, found := mod.Session.WiFi.Get(station.HwAddress); found && (ap.HasHandshakes() || ap.HasPMKID()) { encryption = tui.Red(encryption) } } @@ -76,8 +76,8 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) { recvd := ops.Ternary(station.Received > 0, humanize.Bytes(station.Received), "").(string) include := false - if w.source == "" { - for _, frequencies := range w.frequencies { + if mod.source == "" { + for _, frequencies := range mod.frequencies { if frequencies == station.Frequency { include = true break @@ -87,11 +87,11 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) { include = true } - if int(station.RSSI) < w.minRSSI { + if int(station.RSSI) < mod.minRSSI { include = false } - if w.isApSelected() { + if mod.isApSelected() { return []string{ rssi, bssid, @@ -105,7 +105,7 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) { // method handle both access point and clients // transparently clients := "" - if ap, found := w.Session.WiFi.Get(station.HwAddress); found { + if ap, found := mod.Session.WiFi.Get(station.HwAddress); found { if ap.NumClients() > 0 { clients = strconv.Itoa(ap.NumClients()) } @@ -143,43 +143,43 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) { } } -func (w *WiFiModule) doFilter(station *network.Station) bool { - if w.selector.Expression == nil { +func (mod *WiFiModule) doFilter(station *network.Station) bool { + if mod.selector.Expression == nil { return true } - return w.selector.Expression.MatchString(station.BSSID()) || - w.selector.Expression.MatchString(station.ESSID()) || - w.selector.Expression.MatchString(station.Alias) || - w.selector.Expression.MatchString(station.Vendor) || - w.selector.Expression.MatchString(station.Encryption) + return mod.selector.Expression.MatchString(station.BSSID()) || + mod.selector.Expression.MatchString(station.ESSID()) || + mod.selector.Expression.MatchString(station.Alias) || + mod.selector.Expression.MatchString(station.Vendor) || + mod.selector.Expression.MatchString(station.Encryption) } -func (w *WiFiModule) doSelection() (err error, stations []*network.Station) { - if err = w.selector.Update(); err != nil { +func (mod *WiFiModule) doSelection() (err error, stations []*network.Station) { + if err = mod.selector.Update(); err != nil { return } - apSelected := w.isApSelected() + apSelected := mod.isApSelected() if apSelected { - if ap, found := w.Session.WiFi.Get(w.ap.HwAddress); found { + if ap, found := mod.Session.WiFi.Get(mod.ap.HwAddress); found { stations = ap.Clients() } else { - err = fmt.Errorf("Could not find station %s", w.ap.HwAddress) + err = fmt.Errorf("Could not find station %s", mod.ap.HwAddress) return } } else { - stations = w.Session.WiFi.Stations() + stations = mod.Session.WiFi.Stations() } filtered := []*network.Station{} for _, station := range stations { - if w.doFilter(station) { + if mod.doFilter(station) { filtered = append(filtered, station) } } stations = filtered - switch w.selector.SortField { + switch mod.selector.SortField { case "seen": sort.Sort(ByWiFiSeenSorter(stations)) case "essid": @@ -203,7 +203,7 @@ func (w *WiFiModule) doSelection() (err error, stations []*network.Station) { } // default is asc - if w.selector.Sort == "desc" { + if mod.selector.Sort == "desc" { // from https://github.com/golang/go/wiki/SliceTricks for i := len(stations)/2 - 1; i >= 0; i-- { opp := len(stations) - 1 - i @@ -211,8 +211,8 @@ func (w *WiFiModule) doSelection() (err error, stations []*network.Station) { } } - if w.selector.Limit > 0 { - limit := w.selector.Limit + if mod.selector.Limit > 0 { + limit := mod.selector.Limit max := len(stations) if limit > max { limit = max @@ -223,7 +223,7 @@ func (w *WiFiModule) doSelection() (err error, stations []*network.Station) { return } -func (w *WiFiModule) colDecorate(colNames []string, name string, dir string) { +func (mod *WiFiModule) colDecorate(colNames []string, name string, dir string) { for i, c := range colNames { if c == name { colNames[i] += " " + dir @@ -232,101 +232,101 @@ func (w *WiFiModule) colDecorate(colNames []string, name string, dir string) { } } -func (w *WiFiModule) colNames(nrows int) []string { +func (mod *WiFiModule) colNames(nrows int) []string { columns := []string(nil) - if !w.isApSelected() { + if !mod.isApSelected() { columns = []string{"RSSI", "BSSID", "SSID", "Encryption", "WPS", "Ch", "Clients", "Sent", "Recvd", "Seen"} } else if nrows > 0 { columns = []string{"RSSI", "BSSID", "Ch", "Sent", "Recvd", "Seen"} - fmt.Printf("\n%s clients:\n", w.ap.HwAddress) + fmt.Printf("\n%s clients:\n", mod.ap.HwAddress) } else { - fmt.Printf("\nNo authenticated clients detected for %s.\n", w.ap.HwAddress) + fmt.Printf("\nNo authenticated clients detected for %s.\n", mod.ap.HwAddress) } if columns != nil { - switch w.selector.SortField { + switch mod.selector.SortField { case "seen": - w.colDecorate(columns, "Seen", w.selector.SortSymbol) + mod.colDecorate(columns, "Seen", mod.selector.SortSymbol) case "essid": - w.colDecorate(columns, "SSID", w.selector.SortSymbol) + mod.colDecorate(columns, "SSID", mod.selector.SortSymbol) case "bssid": - w.colDecorate(columns, "BSSID", w.selector.SortSymbol) + mod.colDecorate(columns, "BSSID", mod.selector.SortSymbol) case "channel": - w.colDecorate(columns, "Ch", w.selector.SortSymbol) + mod.colDecorate(columns, "Ch", mod.selector.SortSymbol) case "clients": - w.colDecorate(columns, "Clients", w.selector.SortSymbol) + mod.colDecorate(columns, "Clients", mod.selector.SortSymbol) case "encryption": - w.colDecorate(columns, "Encryption", w.selector.SortSymbol) + mod.colDecorate(columns, "Encryption", mod.selector.SortSymbol) case "sent": - w.colDecorate(columns, "Sent", w.selector.SortSymbol) + mod.colDecorate(columns, "Sent", mod.selector.SortSymbol) case "rcvd": - w.colDecorate(columns, "Recvd", w.selector.SortSymbol) + mod.colDecorate(columns, "Recvd", mod.selector.SortSymbol) case "rssi": - w.colDecorate(columns, "RSSI", w.selector.SortSymbol) + mod.colDecorate(columns, "RSSI", mod.selector.SortSymbol) } } return columns } -func (w *WiFiModule) showStatusBar() { - w.Session.Queue.Stats.RLock() - defer w.Session.Queue.Stats.RUnlock() +func (mod *WiFiModule) showStatusBar() { + mod.Session.Queue.Stats.RLock() + defer mod.Session.Queue.Stats.RUnlock() parts := []string{ - fmt.Sprintf("%s (ch. %d)", w.Session.Interface.Name(), network.GetInterfaceChannel(w.Session.Interface.Name())), - fmt.Sprintf("%s %s", tui.Red("↑"), humanize.Bytes(w.Session.Queue.Stats.Sent)), - fmt.Sprintf("%s %s", tui.Green("↓"), humanize.Bytes(w.Session.Queue.Stats.Received)), - fmt.Sprintf("%d pkts", w.Session.Queue.Stats.PktReceived), + fmt.Sprintf("%s (ch. %d)", mod.Session.Interface.Name(), network.GetInterfaceChannel(mod.Session.Interface.Name())), + fmt.Sprintf("%s %s", tui.Red("↑"), humanize.Bytes(mod.Session.Queue.Stats.Sent)), + fmt.Sprintf("%s %s", tui.Green("↓"), humanize.Bytes(mod.Session.Queue.Stats.Received)), + fmt.Sprintf("%d pkts", mod.Session.Queue.Stats.PktReceived), } - if nErrors := w.Session.Queue.Stats.Errors; nErrors > 0 { + if nErrors := mod.Session.Queue.Stats.Errors; nErrors > 0 { parts = append(parts, fmt.Sprintf("%d errs", nErrors)) } - if nHandshakes := w.Session.WiFi.NumHandshakes(); nHandshakes > 0 { + if nHandshakes := mod.Session.WiFi.NumHandshakes(); nHandshakes > 0 { parts = append(parts, fmt.Sprintf("%d handshakes", nHandshakes)) } fmt.Printf("\n%s\n\n", strings.Join(parts, " / ")) } -func (w *WiFiModule) Show() (err error) { +func (mod *WiFiModule) Show() (err error) { var stations []*network.Station - if err, stations = w.doSelection(); err != nil { + if err, stations = mod.doSelection(); err != nil { return } rows := make([][]string, 0) for _, s := range stations { - if row, include := w.getRow(s); include { + if row, include := mod.getRow(s); include { rows = append(rows, row) } } nrows := len(rows) if nrows > 0 { - tui.Table(os.Stdout, w.colNames(nrows), rows) + tui.Table(os.Stdout, mod.colNames(nrows), rows) } - w.showStatusBar() + mod.showStatusBar() - w.Session.Refresh() + mod.Session.Refresh() return nil } -func (w *WiFiModule) ShowWPS(bssid string) (err error) { +func (mod *WiFiModule) ShowWPS(bssid string) (err error) { toShow := []*network.Station{} if bssid == network.BroadcastMac { - for _, station := range w.Session.WiFi.List() { + for _, station := range mod.Session.WiFi.List() { if station.HasWPS() { toShow = append(toShow, station.Station) } } } else { - if station, found := w.Session.WiFi.Get(bssid); found { + if station, found := mod.Session.WiFi.Get(bssid); found { if station.HasWPS() { toShow = append(toShow, station.Station) } diff --git a/modules/wol/wol.go b/modules/wol/wol.go index 0deb8d4e..2f9e1f66 100644 --- a/modules/wol/wol.go +++ b/modules/wol/wol.go @@ -23,31 +23,31 @@ type WOL struct { } func NewWOL(s *session.Session) *WOL { - w := &WOL{ + mod := &WOL{ SessionModule: session.NewSessionModule("wol", s), } - w.AddHandler(session.NewModuleHandler("wol.eth MAC", "wol.eth(\\s.+)?", + mod.AddHandler(session.NewModuleHandler("wol.eth MAC", "wol.eth(\\s.+)?", "Send a WOL as a raw ethernet packet of type 0x0847 (if no MAC is specified, ff:ff:ff:ff:ff:ff will be used).", func(args []string) error { if mac, err := parseMAC(args); err != nil { return err } else { - return w.wolETH(mac) + return mod.wolETH(mac) } })) - w.AddHandler(session.NewModuleHandler("wol.udp MAC", "wol.udp(\\s.+)?", + mod.AddHandler(session.NewModuleHandler("wol.udp MAC", "wol.udp(\\s.+)?", "Send a WOL as an IPv4 broadcast packet to UDP port 9 (if no MAC is specified, ff:ff:ff:ff:ff:ff will be used).", func(args []string) error { if mac, err := parseMAC(args); err != nil { return err } else { - return w.wolUDP(mac) + return mod.wolUDP(mac) } })) - return w + return mod } func parseMAC(args []string) (string, error) { @@ -66,27 +66,27 @@ func parseMAC(args []string) (string, error) { return mac, nil } -func (w *WOL) Name() string { +func (mod *WOL) Name() string { return "wol" } -func (w *WOL) Description() string { +func (mod *WOL) Description() string { return "A module to send Wake On LAN packets in broadcast or to a specific MAC." } -func (w *WOL) Author() string { +func (mod *WOL) Author() string { return "Simone Margaritelli " } -func (w *WOL) Configure() error { +func (mod *WOL) Configure() error { return nil } -func (w *WOL) Start() error { +func (mod *WOL) Start() error { return nil } -func (w *WOL) Stop() error { +func (mod *WOL) Stop() error { return nil } @@ -99,14 +99,14 @@ func buildPayload(mac string) []byte { return payload } -func (w *WOL) wolETH(mac string) error { - w.SetRunning(true, nil) - defer w.SetRunning(false, nil) +func (mod *WOL) wolETH(mac string) error { + mod.SetRunning(true, nil) + defer mod.SetRunning(false, nil) payload := buildPayload(mac) - w.Info("sending %d bytes of ethernet WOL packet to %s", len(payload), tui.Bold(mac)) + mod.Info("sending %d bytes of ethernet WOL packet to %s", len(payload), tui.Bold(mac)) eth := layers.Ethernet{ - SrcMAC: w.Session.Interface.HW, + SrcMAC: mod.Session.Interface.HW, DstMAC: layers.EthernetBroadcast, EthernetType: 0x0842, } @@ -117,18 +117,18 @@ func (w *WOL) wolETH(mac string) error { } raw = append(raw, payload...) - return w.Session.Queue.Send(raw) + return mod.Session.Queue.Send(raw) } -func (w *WOL) wolUDP(mac string) error { - w.SetRunning(true, nil) - defer w.SetRunning(false, nil) +func (mod *WOL) wolUDP(mac string) error { + mod.SetRunning(true, nil) + defer mod.SetRunning(false, nil) payload := buildPayload(mac) - w.Info("sending %d bytes of UDP WOL packet to %s", len(payload), tui.Bold(mac)) + mod.Info("sending %d bytes of UDP WOL packet to %s", len(payload), tui.Bold(mac)) eth := layers.Ethernet{ - SrcMAC: w.Session.Interface.HW, + SrcMAC: mod.Session.Interface.HW, DstMAC: layers.EthernetBroadcast, EthernetType: layers.EthernetTypeIPv4, } @@ -137,7 +137,7 @@ func (w *WOL) wolUDP(mac string) error { Protocol: layers.IPProtocolUDP, Version: 4, TTL: 64, - SrcIP: w.Session.Interface.IP, + SrcIP: mod.Session.Interface.IP, DstIP: net.ParseIP("255.255.255.255"), } @@ -154,5 +154,5 @@ func (w *WOL) wolUDP(mac string) error { } raw = append(raw, payload...) - return w.Session.Queue.Send(raw) + return mod.Session.Queue.Send(raw) }