mirror of
https://github.com/bettercap/bettercap
synced 2025-07-11 15:46:59 -07:00
new: implemented http.proxy.injectjs and https.proxy.injectjs to inject javascript code, files or URLs without a proxy module
This commit is contained in:
parent
7839a90c82
commit
6c3157e9c4
4 changed files with 74 additions and 12 deletions
|
@ -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 {
|
||||
|
|
|
@ -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("<script src=\"%s\" type=\"text/javascript\"></script></head>", 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, "<script ") == false {
|
||||
jsToInject = fmt.Sprintf("<script type=\"text/javascript\">%s</script>", jsToInject)
|
||||
}
|
||||
p.jsHook = fmt.Sprintf("%s</head>", 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
|
||||
}
|
||||
|
||||
|
|
|
@ -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,16 +64,32 @@ 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)
|
||||
}
|
||||
}
|
||||
|
||||
// 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), "</head>", 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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue