From 709232dba2f409f7a017cebf338bde51b5732c62 Mon Sep 17 00:00:00 2001 From: realgam3 Date: Thu, 5 Sep 2019 13:50:17 +0300 Subject: [PATCH 1/5] Added HTTPRequest to otto runtime --- modules/utils/script_builtins.go | 64 ++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/modules/utils/script_builtins.go b/modules/utils/script_builtins.go index cc49ec30..408592d9 100644 --- a/modules/utils/script_builtins.go +++ b/modules/utils/script_builtins.go @@ -5,6 +5,7 @@ import ( "compress/gzip" "encoding/base64" "io/ioutil" + "net/http" "github.com/bettercap/bettercap/log" "github.com/bettercap/bettercap/session" @@ -245,4 +246,67 @@ func init() { return nullOtto } + + // send http request + plugin.Defines["httpRequest"] = func(call otto.FunctionCall) otto.Value { + argv := call.ArgumentList + argc := len(argv) + if argc < 2 { + return errOtto("httpRequest: expected 2 or more, %d given instead.", argc) + } + + method := argv[0].String() + url := argv[1].String() + + client := &http.Client{} + req, err := http.NewRequest(method, url, nil) + if argc >= 3 { + data := argv[2].String() + req, err = http.NewRequest(method, url, bytes.NewBuffer([]byte(data))) + if err != nil { + return errOtto("Could create request to url %s: %s", url, err) + } + + if argc > 3 { + headers := argv[3].Object() + for _, key := range headers.Keys() { + v, err := headers.Get(key) + if err != nil { + return errOtto("Could add header %s to request: %s", key, err) + } + req.Header.Add(key, v.String()) + } + + } + } else if err != nil { + return errOtto("Could create request to url %s: %s", url, err) + } + + resp, err := client.Do(req) + if err != nil { + return errOtto("Could not request url %s: %s", url, err) + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return errOtto("Could not read response: %s", err) + } + + object, err := otto.New().Object("({})") + if err != nil { + return errOtto("Could not create response object: %s", err) + } + + err = object.Set("body", string(body)) + if err != nil { + return errOtto("Could not populate response object: %s", err) + } + + v, err := otto.ToValue(object) + if err != nil { + return errOtto("Could not convert to object: %s", err) + } + return v + } } From 11d27562831bbcdaf78ada8efd6112af6a1c788e Mon Sep 17 00:00:00 2001 From: realgam3 Date: Fri, 6 Sep 2019 02:31:48 +0300 Subject: [PATCH 2/5] Added dropCallback to drop packets instead of just changing it --- modules/tcp_proxy/tcp_proxy.go | 10 ++++++++-- modules/tcp_proxy/tcp_proxy_script.go | 8 ++++---- modules/utils/script_builtins.go | 1 - 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/modules/tcp_proxy/tcp_proxy.go b/modules/tcp_proxy/tcp_proxy.go index 23ac6041..bb4bf736 100644 --- a/modules/tcp_proxy/tcp_proxy.go +++ b/modules/tcp_proxy/tcp_proxy.go @@ -8,6 +8,8 @@ import ( "github.com/bettercap/bettercap/firewall" "github.com/bettercap/bettercap/session" + + "github.com/robertkrimen/otto" ) type TcpProxy struct { @@ -150,7 +152,7 @@ func (mod *TcpProxy) Configure() error { return nil } -func (mod *TcpProxy) doPipe(from, to net.Addr, src, dst io.ReadWriter, wg *sync.WaitGroup) { +func (mod *TcpProxy) doPipe(from, to net.Addr, src *net.TCPConn, dst io.ReadWriter, wg *sync.WaitGroup) { defer wg.Done() buff := make([]byte, 0xffff) @@ -165,7 +167,11 @@ func (mod *TcpProxy) doPipe(from, to net.Addr, src, dst io.ReadWriter, wg *sync. b := buff[:n] if mod.script != nil { - ret := mod.script.OnData(from, to, b) + ret := mod.script.OnData(from, to, b, func(call otto.FunctionCall) otto.Value { + mod.Debug("onData dropCallback called") + src.Close() + return otto.Value{} + }) if ret != nil { nret := len(ret) diff --git a/modules/tcp_proxy/tcp_proxy_script.go b/modules/tcp_proxy/tcp_proxy_script.go index 0fc7864d..f4f07d88 100644 --- a/modules/tcp_proxy/tcp_proxy_script.go +++ b/modules/tcp_proxy/tcp_proxy_script.go @@ -7,9 +7,9 @@ import ( "github.com/bettercap/bettercap/log" "github.com/bettercap/bettercap/session" - "github.com/robertkrimen/otto" - "github.com/evilsocket/islazy/plugin" + + "github.com/robertkrimen/otto" ) type TcpProxyScript struct { @@ -46,12 +46,12 @@ func LoadTcpProxyScript(path string, sess *session.Session) (err error, s *TcpPr return } -func (s *TcpProxyScript) OnData(from, to net.Addr, data []byte) []byte { +func (s *TcpProxyScript) OnData(from, to net.Addr, data []byte, callback func(call otto.FunctionCall) otto.Value) []byte { if s.doOnData { addrFrom := strings.Split(from.String(), ":")[0] addrTo := strings.Split(to.String(), ":")[0] - if ret, err := s.Call("onData", addrFrom, addrTo, data); err != nil { + if ret, err := s.Call("onData", addrFrom, addrTo, data, callback); err != nil { log.Error("error while executing onData callback: %s", err) return nil } else if ret != nil { diff --git a/modules/utils/script_builtins.go b/modules/utils/script_builtins.go index 408592d9..b197e9a9 100644 --- a/modules/utils/script_builtins.go +++ b/modules/utils/script_builtins.go @@ -276,7 +276,6 @@ func init() { } req.Header.Add(key, v.String()) } - } } else if err != nil { return errOtto("Could create request to url %s: %s", url, err) From c46bb905b9040e56342ba119fec292aad317ae2a Mon Sep 17 00:00:00 2001 From: realgam3 Date: Fri, 6 Sep 2019 17:25:54 +0300 Subject: [PATCH 3/5] Added caplets windows compatibility --- caplets/env.go | 20 ++++++++++++++++++-- caplets/manager.go | 6 +++++- modules/caplets/caplets.go | 4 ++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/caplets/env.go b/caplets/env.go index 4c803b6e..24bf8545 100644 --- a/caplets/env.go +++ b/caplets/env.go @@ -2,7 +2,9 @@ package caplets import ( "os" + "os/user" "path/filepath" + "runtime" "github.com/evilsocket/islazy/str" ) @@ -11,22 +13,36 @@ const ( EnvVarName = "CAPSPATH" Suffix = ".cap" InstallArchive = "https://github.com/bettercap/caplets/archive/master.zip" - InstallBase = "/usr/local/share/bettercap/" ) +func getInstallBase() string { + if runtime.GOOS == "windows" { + return filepath.Join(os.Getenv("ALLUSERSPROFILE"), "bettercap") + } + return "/usr/local/share/bettercap/" +} + +func getUserHomeDir() string { + usr, _ := user.Current() + return usr.HomeDir +} + var ( + InstallBase = getInstallBase() InstallPathArchive = filepath.Join(InstallBase, "caplets-master") InstallPath = filepath.Join(InstallBase, "caplets") + ArchivePath = filepath.Join(os.TempDir(), "caplets.zip") LoadPaths = []string{ "./", "./caplets/", InstallPath, + filepath.Join(getUserHomeDir(), "caplets"), } ) func init() { - for _, path := range str.SplitBy(str.Trim(os.Getenv(EnvVarName)), ":") { + for _, path := range str.SplitBy(str.Trim(os.Getenv(EnvVarName)), string(os.PathListSeparator)) { if path = str.Trim(path); len(path) > 0 { LoadPaths = append(LoadPaths, path) } diff --git a/caplets/manager.go b/caplets/manager.go index cb004d0c..99c84df2 100644 --- a/caplets/manager.go +++ b/caplets/manager.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" "sort" "strings" "sync" @@ -26,6 +27,9 @@ func List() []*Caplet { for _, fileName := range append(files, files2...) { if _, err := os.Stat(fileName); err == nil { base := strings.Replace(fileName, searchPath+"/", "", -1) + if runtime.GOOS == "windows" { + base = strings.Replace(fileName, searchPath+"\\", "", -1) + } base = strings.Replace(base, Suffix, "", -1) if err, caplet := Load(base); err != nil { @@ -58,7 +62,7 @@ func Load(name string) (error, *Caplet) { name += Suffix } - if name[0] != '/' { + if !filepath.IsAbs(name) { for _, path := range LoadPaths { names = append(names, filepath.Join(path, name)) } diff --git a/modules/caplets/caplets.go b/modules/caplets/caplets.go index 61b5589a..648df2ac 100644 --- a/modules/caplets/caplets.go +++ b/modules/caplets/caplets.go @@ -120,7 +120,7 @@ func (mod *CapletsModule) Update() error { } } - out, err := os.Create("/tmp/caplets.zip") + out, err := os.Create(caplets.ArchivePath) if err != nil { return err } @@ -140,7 +140,7 @@ func (mod *CapletsModule) Update() error { mod.Info("installing caplets to %s ...", caplets.InstallPath) - if _, err = zip.Unzip("/tmp/caplets.zip", caplets.InstallBase); err != nil { + if _, err = zip.Unzip(caplets.ArchivePath, caplets.InstallBase); err != nil { return err } From 2eb00ee11a82c402d137b5897ad80e1ce31795f4 Mon Sep 17 00:00:00 2001 From: realgam3 Date: Fri, 6 Sep 2019 17:56:36 +0300 Subject: [PATCH 4/5] Fix user home dir when using sudo on linux --- caplets/env.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/caplets/env.go b/caplets/env.go index 24bf8545..d62a516f 100644 --- a/caplets/env.go +++ b/caplets/env.go @@ -2,11 +2,11 @@ package caplets import ( "os" - "os/user" "path/filepath" "runtime" "github.com/evilsocket/islazy/str" + "github.com/mitchellh/go-homedir" ) const ( @@ -23,8 +23,8 @@ func getInstallBase() string { } func getUserHomeDir() string { - usr, _ := user.Current() - return usr.HomeDir + usr, _ := homedir.Dir() + return usr } var ( From 4181cd1c42aa6a5094725c19b1f868533959df60 Mon Sep 17 00:00:00 2001 From: realgam3 Date: Fri, 6 Sep 2019 18:05:07 +0300 Subject: [PATCH 5/5] Trying not to invent the wheel --- caplets/manager.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/caplets/manager.go b/caplets/manager.go index 99c84df2..984fc4c8 100644 --- a/caplets/manager.go +++ b/caplets/manager.go @@ -5,7 +5,6 @@ import ( "io/ioutil" "os" "path/filepath" - "runtime" "sort" "strings" "sync" @@ -26,10 +25,7 @@ func List() []*Caplet { for _, fileName := range append(files, files2...) { if _, err := os.Stat(fileName); err == nil { - base := strings.Replace(fileName, searchPath+"/", "", -1) - if runtime.GOOS == "windows" { - base = strings.Replace(fileName, searchPath+"\\", "", -1) - } + base := strings.Replace(fileName, searchPath+string(os.PathSeparator), "", -1) base = strings.Replace(base, Suffix, "", -1) if err, caplet := Load(base); err != nil {