diff --git a/modules/http_proxy.go b/modules/http_proxy.go
index 876d3665..cdd42f56 100644
--- a/modules/http_proxy.go
+++ b/modules/http_proxy.go
@@ -33,6 +33,11 @@ func NewHttpProxy(s *session.Session) *HttpProxy {
"",
"Path of a proxy JS script."))
+ p.AddParam(session.NewStringParameter("http.proxy.injectjs",
+ "",
+ "",
+ "URL, path or javascript code to inject into every HTML page."))
+
p.AddParam(session.NewBoolParameter("http.proxy.sslstrip",
"false",
"Enable or disable SSL stripping."))
@@ -71,6 +76,7 @@ func (p *HttpProxy) Configure() error {
var httpPort int
var scriptPath string
var stripSSL bool
+ var jsToInject string
if p.Running() {
return session.ErrAlreadyStarted
@@ -84,9 +90,11 @@ func (p *HttpProxy) Configure() error {
return err
} else if err, stripSSL = p.BoolParam("http.proxy.sslstrip"); err != nil {
return err
+ } else if err, jsToInject = p.StringParam("http.proxy.injectjs"); err != nil {
+ return err
}
- return p.proxy.Configure(address, proxyPort, httpPort, scriptPath, stripSSL)
+ return p.proxy.Configure(address, proxyPort, httpPort, scriptPath, jsToInject, stripSSL)
}
func (p *HttpProxy) Start() error {
diff --git a/modules/http_proxy_base.go b/modules/http_proxy_base.go
index 86816471..6677c365 100644
--- a/modules/http_proxy_base.go
+++ b/modules/http_proxy_base.go
@@ -40,6 +40,7 @@ type HTTPProxy struct {
CertFile string
KeyFile string
+ jsHook string
isTLS bool
isRunning bool
stripper *SSLStripper
@@ -106,12 +107,29 @@ func (p *HTTPProxy) doProxy(req *http.Request) bool {
return true
}
-func (p *HTTPProxy) Configure(address string, proxyPort int, httpPort int, scriptPath string, stripSSL bool) error {
+func (p *HTTPProxy) Configure(address string, proxyPort int, httpPort int, scriptPath string, jsToInject string, stripSSL bool) error {
var err error
p.stripper.Enable(stripSSL)
p.Address = address
+ if strings.HasPrefix(jsToInject, "http://") || strings.HasPrefix(jsToInject, "https://") {
+ p.jsHook = fmt.Sprintf("", jsToInject)
+ } else if core.Exists(jsToInject) {
+ if data, err := ioutil.ReadFile(jsToInject); err != nil {
+ return err
+ } else {
+ jsToInject = string(data)
+ }
+ }
+
+ if p.jsHook == "" && jsToInject != "" {
+ if strings.HasPrefix(jsToInject, "", jsToInject)
+ }
+ p.jsHook = fmt.Sprintf("%s", jsToInject)
+ }
+
if scriptPath != "" {
if err, p.Script = LoadHttpProxyScript(scriptPath, p.sess); err != nil {
return err
@@ -187,8 +205,8 @@ func TLSConfigFromCA(ca *tls.Certificate) func(host string, ctx *goproxy.ProxyCt
}
}
-func (p *HTTPProxy) ConfigureTLS(address string, proxyPort int, httpPort int, scriptPath string, certFile string, keyFile string, stripSSL bool) (err error) {
- if p.Configure(address, proxyPort, httpPort, scriptPath, stripSSL); err != nil {
+func (p *HTTPProxy) ConfigureTLS(address string, proxyPort int, httpPort int, scriptPath string, certFile string, keyFile string, jsToInject string, stripSSL bool) (err error) {
+ if p.Configure(address, proxyPort, httpPort, scriptPath, jsToInject, stripSSL); err != nil {
return err
}
diff --git a/modules/http_proxy_base_filters.go b/modules/http_proxy_base_filters.go
index c946346d..aa5615a6 100644
--- a/modules/http_proxy_base_filters.go
+++ b/modules/http_proxy_base_filters.go
@@ -1,6 +1,7 @@
package modules
import (
+ "io/ioutil"
"net/http"
"strings"
@@ -40,6 +41,17 @@ func (p *HTTPProxy) onRequestFilter(req *http.Request, ctx *goproxy.ProxyCtx) (*
return req, nil
}
+func getContentType(res *http.Response) string {
+ for name, values := range res.Header {
+ for _, value := range values {
+ if strings.ToLower(name) == "content-type" {
+ return value
+ }
+ }
+ }
+ return ""
+}
+
func (p *HTTPProxy) onResponseFilter(res *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
// sometimes it happens ¯\_(ツ)_/¯
if res == nil {
@@ -52,15 +64,31 @@ func (p *HTTPProxy) onResponseFilter(res *http.Response, ctx *goproxy.ProxyCtx)
p.stripper.Process(res, ctx)
// do we have a proxy script?
- if p.Script == nil {
- return res
+ if p.Script != nil {
+ _, jsres := p.Script.OnResponse(res)
+ if jsres != nil {
+ // the response has been changed by the script
+ p.logResponseAction(res.Request, jsres)
+ return jsres.ToResponse(res.Request)
+ }
}
- _, jsres := p.Script.OnResponse(res)
- if jsres != nil {
- // the response has been changed by the script
- p.logResponseAction(res.Request, jsres)
- return jsres.ToResponse(res.Request)
+ // inject javascript code if specified and needed
+ if cType := getContentType(res); p.jsHook != "" && strings.Contains(cType, "text/html") {
+ log.Info("(%s) > injecting javascript (%d bytes) into %s for %s", core.Green(p.Name), len(p.jsHook), core.Yellow(req.Host+req.URL.Path), core.Bold(req.RemoteAddr))
+ defer res.Body.Close()
+
+ raw, _ := ioutil.ReadAll(res.Body)
+ html := strings.Replace(string(raw), "", p.jsHook, -1)
+
+ newResp := goproxy.NewResponse(req, cType, res.StatusCode, html)
+ for k, vv := range res.Header {
+ for _, v := range vv {
+ newResp.Header.Add(k, v)
+ }
+ }
+
+ return newResp
}
return res
diff --git a/modules/https_proxy.go b/modules/https_proxy.go
index b8ee65f8..218033e5 100644
--- a/modules/https_proxy.go
+++ b/modules/https_proxy.go
@@ -35,6 +35,11 @@ func NewHttpsProxy(s *session.Session) *HttpsProxy {
"false",
"Enable or disable SSL stripping."))
+ p.AddParam(session.NewStringParameter("https.proxy.injectjs",
+ "",
+ "",
+ "URL, path or javascript code to inject into every HTML page."))
+
p.AddParam(session.NewStringParameter("https.proxy.certificate",
"~/.bettercap-ca.cert.pem",
"",
@@ -86,6 +91,7 @@ func (p *HttpsProxy) Configure() error {
var certFile string
var keyFile string
var stripSSL bool
+ var jsToInject string
if p.Running() {
return session.ErrAlreadyStarted
@@ -107,6 +113,8 @@ func (p *HttpsProxy) Configure() error {
return err
} else if err, scriptPath = p.StringParam("https.proxy.script"); err != nil {
return err
+ } else if err, jsToInject = p.StringParam("https.proxy.injectjs"); err != nil {
+ return err
}
if !core.Exists(certFile) || !core.Exists(keyFile) {
@@ -120,7 +128,7 @@ func (p *HttpsProxy) Configure() error {
log.Info("Loading proxy certification authority TLS certificate from %s", certFile)
}
- return p.proxy.ConfigureTLS(address, proxyPort, httpPort, scriptPath, certFile, keyFile, stripSSL)
+ return p.proxy.ConfigureTLS(address, proxyPort, httpPort, scriptPath, certFile, keyFile, jsToInject, stripSSL)
}
func (p *HttpsProxy) Start() error {