diff --git a/log/log.go b/log/log.go new file mode 100644 index 00000000..b783e4c1 --- /dev/null +++ b/log/log.go @@ -0,0 +1,25 @@ +package log + +import ( + "github.com/evilsocket/bettercap-ng/session" +) + +func Debug(format string, args ...interface{}) { + session.I.Events.Log(session.DEBUG, format, args) +} + +func Info(format string, args ...interface{}) { + session.I.Events.Log(session.INFO, format, args) +} + +func Warning(format string, args ...interface{}) { + session.I.Events.Log(session.WARNING, format, args) +} + +func Error(format string, args ...interface{}) { + session.I.Events.Log(session.ERROR, format, args) +} + +func Fatal(format string, args ...interface{}) { + session.I.Events.Log(session.FATAL, format, args) +} diff --git a/main.go b/main.go index ec86d033..a888da09 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/evilsocket/bettercap-ng/core" + "github.com/evilsocket/bettercap-ng/log" "github.com/evilsocket/bettercap-ng/modules" "github.com/evilsocket/bettercap-ng/session" ) @@ -65,7 +66,7 @@ func main() { } if err = sess.Run(line); err != nil { - sess.Events.Log(session.ERROR, "%s", err) + log.Error("%s", err) } } } diff --git a/modules/api_rest.go b/modules/api_rest.go index cd46b878..e3ed287e 100644 --- a/modules/api_rest.go +++ b/modules/api_rest.go @@ -7,6 +7,7 @@ import ( "time" "github.com/evilsocket/bettercap-ng/core" + "github.com/evilsocket/bettercap-ng/log" "github.com/evilsocket/bettercap-ng/session" "github.com/evilsocket/bettercap-ng/tls" ) @@ -160,14 +161,14 @@ func (api *RestAPI) configure() error { } if core.Exists(api.certFile) == false || core.Exists(api.keyFile) == false { - api.Session.Events.Log(session.INFO, "Generating RSA key to %s", api.keyFile) - api.Session.Events.Log(session.INFO, "Generating TLS certificate to %s", api.certFile) + log.Info("Generating RSA key to %s", api.keyFile) + log.Info("Generating TLS certificate to %s", api.certFile) if err := tls.Generate(api.certFile, api.keyFile); err != nil { return err } } else { - api.Session.Events.Log(session.INFO, "Loading RSA key from %s", api.keyFile) - api.Session.Events.Log(session.INFO, "Loading TLS certificate from %s", api.certFile) + log.Info("Loading RSA key from %s", api.keyFile) + log.Info("Loading TLS certificate from %s", api.certFile) } return nil @@ -181,7 +182,7 @@ func (api *RestAPI) Start() error { if api.Running() == false { api.SetRunning(true) go func() { - api.Session.Events.Log(session.INFO, "API server starting on https://%s", api.server.Addr) + log.Info("API server starting on https://%s", api.server.Addr) err := api.server.ListenAndServeTLS(api.certFile, api.keyFile) if err != nil && err != http.ErrServerClosed { panic(err) diff --git a/modules/api_rest_routes.go b/modules/api_rest_routes.go index 53f7d631..5c187114 100644 --- a/modules/api_rest_routes.go +++ b/modules/api_rest_routes.go @@ -7,7 +7,7 @@ import ( "strconv" "strings" - "github.com/evilsocket/bettercap-ng/session" + "github.com/evilsocket/bettercap-ng/log" ) func (api *RestAPI) setupRoutes() { @@ -17,7 +17,7 @@ func (api *RestAPI) setupRoutes() { func (api RestAPI) checkAuth(w http.ResponseWriter, r *http.Request) bool { if api.Authenticated(w, r) == false { - api.Session.Events.Log(session.WARNING, "Unauthenticated access!") + log.Warning("Unauthenticated access!") http.Error(w, "Not authorized", 401) return false } @@ -57,7 +57,7 @@ func (api *RestAPI) sessRoute(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { js, err := json.Marshal(api.Session) if err != nil { - api.Session.Events.Log(session.ERROR, "Error while returning session: %s", err) + log.Error("Error while returning session: %s", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -80,7 +80,7 @@ func (api *RestAPI) sessRoute(w http.ResponseWriter, r *http.Request) { } js, err := json.Marshal(res) if err != nil { - api.Session.Events.Log(session.ERROR, "Error while returning response: %s", err) + log.Error("Error while returning response: %s", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -119,7 +119,7 @@ func (api *RestAPI) eventsRoute(w http.ResponseWriter, r *http.Request) { js, err := json.Marshal(events[0:n]) if err != nil { - api.Session.Events.Log(session.ERROR, "Error while returning events: %s", err) + log.Error("Error while returning events: %s", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } diff --git a/modules/arp_spoof.go b/modules/arp_spoof.go index 3c7d7dda..af6eeaf4 100644 --- a/modules/arp_spoof.go +++ b/modules/arp_spoof.go @@ -2,12 +2,15 @@ package modules import ( "fmt" + "net" + "time" + + "github.com/evilsocket/bettercap-ng/log" network "github.com/evilsocket/bettercap-ng/net" "github.com/evilsocket/bettercap-ng/packets" "github.com/evilsocket/bettercap-ng/session" + "github.com/malfunkt/iprange" - "net" - "time" ) type ArpSpoofer struct { @@ -85,7 +88,7 @@ func (p *ArpSpoofer) getMAC(ip net.IP, probe bool) (net.HardwareAddr, error) { from_hw := p.Session.Interface.HW if err, probe := packets.NewUDPProbe(from, from_hw, ip, 139); err != nil { - p.Session.Events.Log(session.ERROR, "Error while creating UDP probe packet for %s: %s\n", ip.String(), err) + log.Error("Error while creating UDP probe packet for %s: %s", ip.String(), err) } else { p.Session.Queue.Send(probe) } @@ -110,21 +113,21 @@ func (p *ArpSpoofer) getMAC(ip net.IP, probe bool) (net.HardwareAddr, error) { func (p *ArpSpoofer) sendArp(addresses []net.IP, saddr net.IP, smac net.HardwareAddr, check_running bool, probe bool) { for _, ip := range addresses { if p.shouldSpoof(ip) == false { - p.Session.Events.Log(session.DEBUG, "Skipping address %s from ARP spoofing.\n", ip) + log.Debug("Skipping address %s from ARP spoofing.", ip) continue } // do we have this ip mac address? hw, err := p.getMAC(ip, probe) if err != nil { - p.Session.Events.Log(session.DEBUG, "Error while looking up hardware address for %s: %s\n", ip.String(), err) + log.Debug("Error while looking up hardware address for %s: %s", ip.String(), err) continue } if err, pkt := packets.NewARPReply(saddr, smac, ip, hw); err != nil { - p.Session.Events.Log(session.ERROR, "Error while creating ARP spoof packet for %s: %s\n", ip.String(), err) + log.Error("Error while creating ARP spoof packet for %s: %s", ip.String(), err) } else { - p.Session.Events.Log(session.DEBUG, "Sending %d bytes of ARP packet to %s:%s.\n", len(pkt), ip.String(), hw.String()) + log.Debug("Sending %d bytes of ARP packet to %s:%s.", len(pkt), ip.String(), hw.String()) p.Session.Queue.Send(pkt) } @@ -152,7 +155,7 @@ func (p *ArpSpoofer) unSpoof() error { from := p.Session.Gateway.IP from_hw := p.Session.Gateway.HW - p.Session.Events.Log(session.INFO, "Restoring ARP cache of %d targets (%s).\n", len(addresses), targets) + log.Info("Restoring ARP cache of %d targets (%s).", len(addresses), targets) p.sendArp(addresses, from, from_hw, false, false) @@ -182,7 +185,7 @@ func (p *ArpSpoofer) Start() error { from := p.Session.Gateway.IP from_hw := p.Session.Interface.HW - p.Session.Events.Log(session.INFO, "ARP spoofer started, probing %d targets (%s).\n", len(addresses), targets) + log.Info("ARP spoofer started, probing %d targets (%s).", len(addresses), targets) for p.Running() { p.sendArp(addresses, from, from_hw, true, false) @@ -202,7 +205,7 @@ func (p *ArpSpoofer) Stop() error { if p.Running() == true { p.SetRunning(false) - p.Session.Events.Log(session.INFO, "Waiting for ARP spoofer to stop ...") + log.Info("Waiting for ARP spoofer to stop ...") <-p.Done diff --git a/modules/http_proxy.go b/modules/http_proxy.go index 91917fc4..5f9c4427 100644 --- a/modules/http_proxy.go +++ b/modules/http_proxy.go @@ -8,6 +8,7 @@ import ( "github.com/elazarl/goproxy" "github.com/evilsocket/bettercap-ng/firewall" + "github.com/evilsocket/bettercap-ng/log" "github.com/evilsocket/bettercap-ng/session" ) @@ -170,13 +171,13 @@ func (p *HttpProxy) Start() error { if err, p.script = LoadProxyScript(scriptPath, p.Session); err != nil { return err } else { - p.Session.Events.Log(session.DEBUG, "Proxy script %s loaded.", scriptPath) + log.Debug("Proxy script %s loaded.", scriptPath) } } } if p.Session.Firewall.IsForwardingEnabled() == false { - p.Session.Events.Log(session.INFO, "Enabling forwarding.") + log.Info("Enabling forwarding.") p.Session.Firewall.EnableForwarding(true) } @@ -190,7 +191,7 @@ func (p *HttpProxy) Start() error { return err } - p.Session.Events.Log(session.DEBUG, "Applied redirection %s", p.redirection.String()) + log.Debug("Applied redirection %s", p.redirection.String()) address := fmt.Sprintf("%s:%d", p.address, proxy_port) p.server = http.Server{Addr: address, Handler: p.proxy} @@ -198,7 +199,7 @@ func (p *HttpProxy) Start() error { p.SetRunning(true) if err := p.server.ListenAndServe(); err != nil { p.SetRunning(false) - p.Session.Events.Log(session.WARNING, "%s", err) + log.Warning("%s", err) } }() @@ -210,7 +211,7 @@ func (p *HttpProxy) Stop() error { p.SetRunning(false) p.server.Shutdown(nil) if p.redirection != nil { - p.Session.Events.Log(session.DEBUG, "Disabling redirection %s", p.redirection.String()) + log.Debug("Disabling redirection %s", p.redirection.String()) if err := p.Session.Firewall.EnableRedirection(p.redirection, false); err != nil { return err } @@ -230,13 +231,13 @@ func (p *HttpProxy) doProxy(req *http.Request) bool { } if req.Host == "" { - p.Session.Events.Log(session.ERROR, "Got request with empty host: %v", req) + log.Error("Got request with empty host: %v", req) return false } for _, blacklisted := range blacklist { if strings.HasPrefix(req.Host, blacklisted) { - p.Session.Events.Log(session.ERROR, "Got request with blacklisted host: %s", req.Host) + log.Error("Got request with blacklisted host: %s", req.Host) return false } } diff --git a/modules/http_proxy_script.go b/modules/http_proxy_script.go index 51d28474..f4d3d6e1 100644 --- a/modules/http_proxy_script.go +++ b/modules/http_proxy_script.go @@ -5,6 +5,7 @@ import ( "net/http" "sync" + "github.com/evilsocket/bettercap-ng/log" "github.com/evilsocket/bettercap-ng/session" "github.com/robertkrimen/otto" @@ -24,7 +25,7 @@ type ProxyScript struct { } func LoadProxyScript(path string, sess *session.Session) (err error, s *ProxyScript) { - sess.Events.Log(session.INFO, "Loading proxy script %s ...", path) + log.Info("Loading proxy script %s ...", path) raw, err := ioutil.ReadFile(path) if err != nil { @@ -53,7 +54,7 @@ func LoadProxyScript(path string, sess *session.Session) (err error, s *ProxyScr // define session pointer err = s.VM.Set("env", sess.Env.Storage) if err != nil { - sess.Events.Log(session.ERROR, "Error while defining environment: %s", err) + log.Error("Error while defining environment: %s", err) return } @@ -62,13 +63,13 @@ func LoadProxyScript(path string, sess *session.Session) (err error, s *ProxyScr filename := call.Argument(0).String() raw, err := ioutil.ReadFile(filename) if err != nil { - s.sess.Events.Log(session.ERROR, "Could not read %s: %s", filename, err) + log.Error("Could not read %s: %s", filename, err) return otto.Value{} } v, err := s.VM.ToValue(string(raw)) if err != nil { - s.sess.Events.Log(session.ERROR, "Could not convert to string: %s", err) + log.Error("Could not convert to string: %s", err) return otto.Value{} } return v @@ -78,7 +79,7 @@ func LoadProxyScript(path string, sess *session.Session) (err error, s *ProxyScr if s.hasCallback("onLoad") { _, err = s.VM.Run("onLoad()") if err != nil { - sess.Events.Log(session.ERROR, "Error while executing onLoad callback: %s", err) + log.Error("Error while executing onLoad callback: %s", err) return } } @@ -87,7 +88,7 @@ func LoadProxyScript(path string, sess *session.Session) (err error, s *ProxyScr if s.hasCallback("onRequest") { s.onRequestScript, err = s.VM.Compile("", "onRequest(req, res)") if err != nil { - sess.Events.Log(session.ERROR, "Error while compiling onRequest callback: %s", err) + log.Error("Error while compiling onRequest callback: %s", err) return } } @@ -96,7 +97,7 @@ func LoadProxyScript(path string, sess *session.Session) (err error, s *ProxyScr if s.hasCallback("onResponse") { s.onResponseScript, err = s.VM.Compile("", "onResponse(req, res)") if err != nil { - sess.Events.Log(session.ERROR, "Error while compiling onResponse callback: %s", err) + log.Error("Error while compiling onResponse callback: %s", err) return } } @@ -128,13 +129,13 @@ func (s *ProxyScript) doRequestDefines(req *http.Request) (err error, jsres *JSR // convert request and define empty response to be optionally filled jsreq := NewJSRequest(req) if err = s.VM.Set("req", &jsreq); err != nil { - s.sess.Events.Log(session.ERROR, "Error while defining request: %s", err) + log.Error("Error while defining request: %s", err) return } jsres = &JSResponse{} if err = s.VM.Set("res", jsres); err != nil { - s.sess.Events.Log(session.ERROR, "Error while defining response: %s", err) + log.Error("Error while defining response: %s", err) return } @@ -145,13 +146,13 @@ func (s *ProxyScript) doResponseDefines(res *http.Response) (err error, jsres *J // convert both request and response jsreq := NewJSRequest(res.Request) if err = s.VM.Set("req", jsreq); err != nil { - s.sess.Events.Log(session.ERROR, "Error while defining request: %s", err) + log.Error("Error while defining request: %s", err) return } jsres = NewJSResponse(res) if err = s.VM.Set("res", jsres); err != nil { - s.sess.Events.Log(session.ERROR, "Error while defining response: %s", err) + log.Error("Error while defining response: %s", err) return } @@ -165,13 +166,13 @@ func (s *ProxyScript) OnRequest(req *http.Request) *JSResponse { err, jsres := s.doRequestDefines(req) if err != nil { - s.sess.Events.Log(session.ERROR, "Error while running bootstrap definitions: %s", err) + log.Error("Error while running bootstrap definitions: %s", err) return nil } _, err = s.VM.Run(s.onRequestScript) if err != nil { - s.sess.Events.Log(session.ERROR, "Error while executing onRequest callback: %s", err) + log.Error("Error while executing onRequest callback: %s", err) return nil } @@ -190,13 +191,13 @@ func (s *ProxyScript) OnResponse(res *http.Response) *JSResponse { err, jsres := s.doResponseDefines(res) if err != nil { - s.sess.Events.Log(session.ERROR, "Error while running bootstrap definitions: %s", err) + log.Error("Error while running bootstrap definitions: %s", err) return nil } _, err = s.VM.Run(s.onResponseScript) if err != nil { - s.sess.Events.Log(session.ERROR, "Error while executing onRequest callback: %s", err) + log.Error("Error while executing onRequest callback: %s", err) return nil } diff --git a/modules/net_probe.go b/modules/net_probe.go index b76f6944..d12dbe6a 100644 --- a/modules/net_probe.go +++ b/modules/net_probe.go @@ -5,6 +5,7 @@ import ( "net" "time" + "github.com/evilsocket/bettercap-ng/log" "github.com/evilsocket/bettercap-ng/session" "github.com/malfunkt/iprange" @@ -73,11 +74,11 @@ func (p Prober) OnSessionEnded(s *session.Session) { func (p *Prober) sendProbe(from net.IP, from_hw net.HardwareAddr, ip net.IP) { name := fmt.Sprintf("%s:137", ip) if addr, err := net.ResolveUDPAddr("udp", name); err != nil { - p.Session.Events.Log(session.ERROR, "Could not resolve %s.", name) + log.Error("Could not resolve %s.", name) } else if con, err := net.DialUDP("udp", nil, addr); err != nil { - p.Session.Events.Log(session.ERROR, "Could not dial %s.", name) + log.Error("Could not dial %s.", name) } else { - // p.Session.Events.Log(session.DEBUG,"UDP connection to %s enstablished.\n", name) + log.Debug("UDP connection to %s enstablished.", name) defer con.Close() con.Write([]byte{0xde, 0xad, 0xbe, 0xef}) } @@ -90,7 +91,7 @@ func (p *Prober) Start() error { return err } else { throttle = v.(int) - p.Session.Events.Log(session.DEBUG, "Throttling packets of %d ms.", throttle) + log.Debug("Throttling packets of %d ms.", throttle) } p.SetRunning(true) @@ -98,7 +99,7 @@ func (p *Prober) Start() error { go func() { list, err := iprange.Parse(p.Session.Interface.CIDR()) if err != nil { - p.Session.Events.Log(session.FATAL, "%s", err) + log.Fatal("%s", err) } from := p.Session.Interface.IP @@ -108,7 +109,7 @@ func (p *Prober) Start() error { for p.Running() { for _, ip := range addresses { if p.shouldProbe(ip) == false { - p.Session.Events.Log(session.DEBUG, "Skipping address %s from UDP probing.", ip) + log.Debug("Skipping address %s from UDP probing.", ip) continue } diff --git a/modules/net_recon.go b/modules/net_recon.go index 88d9fa4e..396e1882 100644 --- a/modules/net_recon.go +++ b/modules/net_recon.go @@ -2,6 +2,7 @@ package modules import ( "fmt" + "github.com/evilsocket/bettercap-ng/log" "github.com/evilsocket/bettercap-ng/net" "github.com/evilsocket/bettercap-ng/session" "time" @@ -84,7 +85,7 @@ func (d *Discovery) checkShared(new net.ArpTable) { b = "" } - d.Session.Events.Log(session.WARNING, "Found %d endpoint%s which share%s the same MAC of the gateway (%s), there're might be some IP isolation going on, skipping.", n_gw_shared, a, b, d.Session.Gateway.HwAddress) + log.Warning("Found %d endpoint%s which share%s the same MAC of the gateway (%s), there're might be some IP isolation going on, skipping.", n_gw_shared, a, b, d.Session.Gateway.HwAddress) } } @@ -124,7 +125,7 @@ func (d *Discovery) Start() error { var err error if d.current, err = net.ArpUpdate(d.Session.Interface.Name()); err != nil { - d.Session.Events.Log(session.ERROR, "%s", err) + log.Error("%s", err) continue } diff --git a/modules/net_sniff.go b/modules/net_sniff.go index 873f6658..fd1e5bd3 100644 --- a/modules/net_sniff.go +++ b/modules/net_sniff.go @@ -2,16 +2,19 @@ package modules import ( "fmt" - "github.com/evilsocket/bettercap-ng/core" - "github.com/evilsocket/bettercap-ng/session" - "github.com/google/gopacket" - "github.com/google/gopacket/layers" - "github.com/google/gopacket/pcap" - "github.com/google/gopacket/pcapgo" "net" "os" "regexp" "time" + + "github.com/evilsocket/bettercap-ng/core" + "github.com/evilsocket/bettercap-ng/log" + "github.com/evilsocket/bettercap-ng/session" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" + "github.com/google/gopacket/pcapgo" ) type SnifferContext struct { @@ -47,27 +50,27 @@ var ( func (c *SnifferContext) Log(sess *session.Session) { if c.DumpLocal { - sess.Events.Log(session.INFO, "Skip local packets : %s", no) + log.Info("Skip local packets : %s", no) } else { - sess.Events.Log(session.INFO, "Skip local packets : %s", yes) + log.Info("Skip local packets : %s", yes) } if c.Verbose { - sess.Events.Log(session.INFO, "Verbose : %s", yes) + log.Info("Verbose : %s", yes) } else { - sess.Events.Log(session.INFO, "Verbose : %s", no) + log.Info("Verbose : %s", no) } if c.Filter != "" { - sess.Events.Log(session.INFO, "BPF Filter : '%s'", core.Yellow(c.Filter)) + log.Info("BPF Filter : '%s'", core.Yellow(c.Filter)) } if c.Expression != "" { - sess.Events.Log(session.INFO, "Regular expression : '%s'", core.Yellow(c.Expression)) + log.Info("Regular expression : '%s'", core.Yellow(c.Expression)) } if c.Output != "" { - sess.Events.Log(session.INFO, "File output : '%s'", core.Yellow(c.Output)) + log.Info("File output : '%s'", core.Yellow(c.Output)) } } @@ -281,13 +284,13 @@ func (s *Sniffer) PrintStats() error { last = s.Stats.LastPacket.String() } - s.Session.Events.Log(session.INFO, "Sniffer Started : %s", s.Stats.Started) - s.Session.Events.Log(session.INFO, "First Packet Seen : %s", first) - s.Session.Events.Log(session.INFO, "Last Packet Seen : %s", last) - s.Session.Events.Log(session.INFO, "Local Packets : %d", s.Stats.NumLocal) - s.Session.Events.Log(session.INFO, "Matched Packets : %d", s.Stats.NumMatched) - s.Session.Events.Log(session.INFO, "Dumped Packets : %d", s.Stats.NumDumped) - s.Session.Events.Log(session.INFO, "Wrote Packets : %d", s.Stats.NumWrote) + log.Info("Sniffer Started : %s", s.Stats.Started) + log.Info("First Packet Seen : %s", first) + log.Info("Last Packet Seen : %s", last) + log.Info("Local Packets : %d", s.Stats.NumLocal) + log.Info("Matched Packets : %d", s.Stats.NumMatched) + log.Info("Dumped Packets : %d", s.Stats.NumDumped) + log.Info("Wrote Packets : %d", s.Stats.NumWrote) return nil } diff --git a/session/session.go b/session/session.go index f4ef2208..c39c8931 100644 --- a/session/session.go +++ b/session/session.go @@ -17,6 +17,10 @@ import ( "github.com/evilsocket/bettercap-ng/packets" ) +var ( + I = (*Session)(nil) +) + type Session struct { Options core.Options `json:"options"` Interface *net.Endpoint `json:"interface"` @@ -65,6 +69,10 @@ func New() (*Session, error) { s.registerCoreHandlers() + if I == nil { + I = s + } + return s, nil } @@ -217,7 +225,7 @@ func (s *Session) ReadLine() (string, error) { } func (s *Session) RunCaplet(filename string) error { - s.Events.Log(INFO, "Reading from caplet %s ...\n", filename) + s.Events.Log(INFO, "Reading from caplet %s ...", filename) input, err := os.Open(filename) if err != nil {