mirror of
https://github.com/bettercap/bettercap
synced 2025-07-30 11:40:33 -07:00
started working on #154
This commit is contained in:
parent
1a8826436e
commit
741d9d8f6e
4 changed files with 125 additions and 91 deletions
|
@ -33,6 +33,10 @@ func NewHttpProxy(s *session.Session) *HttpProxy {
|
||||||
"",
|
"",
|
||||||
"Path of a proxy JS script."))
|
"Path of a proxy JS script."))
|
||||||
|
|
||||||
|
p.AddParam(session.NewBoolParameter("http.proxy.sslstrip",
|
||||||
|
"true",
|
||||||
|
"Enable or disable SSL stripping."))
|
||||||
|
|
||||||
p.AddHandler(session.NewModuleHandler("http.proxy on", "",
|
p.AddHandler(session.NewModuleHandler("http.proxy on", "",
|
||||||
"Start HTTP proxy.",
|
"Start HTTP proxy.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
|
@ -66,6 +70,7 @@ func (p *HttpProxy) Configure() error {
|
||||||
var proxyPort int
|
var proxyPort int
|
||||||
var httpPort int
|
var httpPort int
|
||||||
var scriptPath string
|
var scriptPath string
|
||||||
|
var stripSSL bool
|
||||||
|
|
||||||
if p.Running() == true {
|
if p.Running() == true {
|
||||||
return session.ErrAlreadyStarted
|
return session.ErrAlreadyStarted
|
||||||
|
@ -77,9 +82,11 @@ func (p *HttpProxy) Configure() error {
|
||||||
return err
|
return err
|
||||||
} else if err, scriptPath = p.StringParam("http.proxy.script"); err != nil {
|
} else if err, scriptPath = p.StringParam("http.proxy.script"); err != nil {
|
||||||
return err
|
return err
|
||||||
|
} else if err, stripSSL = p.BoolParam("http.proxy.sslstrip"); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.proxy.Configure(address, proxyPort, httpPort, scriptPath)
|
return p.proxy.Configure(address, proxyPort, httpPort, scriptPath, stripSSL)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *HttpProxy) Start() error {
|
func (p *HttpProxy) Start() error {
|
||||||
|
|
|
@ -42,6 +42,7 @@ type HTTPProxy struct {
|
||||||
|
|
||||||
isTLS bool
|
isTLS bool
|
||||||
isRunning bool
|
isRunning bool
|
||||||
|
stripSSL bool
|
||||||
sniListener net.Listener
|
sniListener net.Listener
|
||||||
sess *session.Session
|
sess *session.Session
|
||||||
}
|
}
|
||||||
|
@ -56,11 +57,12 @@ func stripPort(s string) string {
|
||||||
|
|
||||||
func NewHTTPProxy(s *session.Session) *HTTPProxy {
|
func NewHTTPProxy(s *session.Session) *HTTPProxy {
|
||||||
p := &HTTPProxy{
|
p := &HTTPProxy{
|
||||||
Name: "http.proxy",
|
Name: "http.proxy",
|
||||||
Proxy: goproxy.NewProxyHttpServer(),
|
Proxy: goproxy.NewProxyHttpServer(),
|
||||||
sess: s,
|
sess: s,
|
||||||
isTLS: false,
|
isTLS: false,
|
||||||
Server: nil,
|
stripSSL: true,
|
||||||
|
Server: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Proxy.Verbose = false
|
p.Proxy.Verbose = false
|
||||||
|
@ -77,71 +79,12 @@ func NewHTTPProxy(s *session.Session) *HTTPProxy {
|
||||||
})
|
})
|
||||||
|
|
||||||
p.Proxy.OnRequest().HandleConnect(goproxy.AlwaysMitm)
|
p.Proxy.OnRequest().HandleConnect(goproxy.AlwaysMitm)
|
||||||
p.Proxy.OnRequest().DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
|
p.Proxy.OnRequest().DoFunc(p.onRequestFilter)
|
||||||
log.Debug("(%s) < %s %s %s%s", core.Green(p.Name), req.RemoteAddr, req.Method, req.Host, req.URL.Path)
|
p.Proxy.OnResponse().DoFunc(p.onResponseFilter)
|
||||||
if p.Script != nil {
|
|
||||||
jsreq, jsres := p.Script.OnRequest(req)
|
|
||||||
if jsreq != nil {
|
|
||||||
p.logRequestAction(req, jsreq)
|
|
||||||
return jsreq.ToRequest(), nil
|
|
||||||
} else if jsres != nil {
|
|
||||||
p.logResponseAction(req, jsres)
|
|
||||||
return req, jsres.ToResponse(req)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return req, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
p.Proxy.OnResponse().DoFunc(func(res *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
|
|
||||||
if res != nil {
|
|
||||||
req := res.Request
|
|
||||||
log.Debug("(%s) > %s %s %s%s", core.Green(p.Name), req.RemoteAddr, req.Method, req.Host, req.URL.Path)
|
|
||||||
if p.Script != nil {
|
|
||||||
_, jsres := p.Script.OnResponse(res)
|
|
||||||
if jsres != nil {
|
|
||||||
p.logResponseAction(res.Request, jsres)
|
|
||||||
return jsres.ToResponse(res.Request)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
})
|
|
||||||
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *HTTPProxy) logRequestAction(req *http.Request, jsreq *JSRequest) {
|
|
||||||
p.sess.Events.Add(p.Name+".spoofed-request", struct {
|
|
||||||
To string
|
|
||||||
Method string
|
|
||||||
Host string
|
|
||||||
Path string
|
|
||||||
Size int
|
|
||||||
}{
|
|
||||||
strings.Split(req.RemoteAddr, ":")[0],
|
|
||||||
jsreq.Method,
|
|
||||||
jsreq.Hostname,
|
|
||||||
jsreq.Path,
|
|
||||||
len(jsreq.Body),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *HTTPProxy) logResponseAction(req *http.Request, jsres *JSResponse) {
|
|
||||||
p.sess.Events.Add(p.Name+".spoofed-response", struct {
|
|
||||||
To string
|
|
||||||
Method string
|
|
||||||
Host string
|
|
||||||
Path string
|
|
||||||
Size int
|
|
||||||
}{
|
|
||||||
strings.Split(req.RemoteAddr, ":")[0],
|
|
||||||
req.Method,
|
|
||||||
req.Host,
|
|
||||||
req.URL.Path,
|
|
||||||
len(jsres.Body),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *HTTPProxy) doProxy(req *http.Request) bool {
|
func (p *HTTPProxy) doProxy(req *http.Request) bool {
|
||||||
blacklist := []string{
|
blacklist := []string{
|
||||||
"localhost",
|
"localhost",
|
||||||
|
@ -163,9 +106,10 @@ func (p *HTTPProxy) doProxy(req *http.Request) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *HTTPProxy) Configure(address string, proxyPort int, httpPort int, scriptPath string) error {
|
func (p *HTTPProxy) Configure(address string, proxyPort int, httpPort int, scriptPath string, stripSSL bool) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
p.stripSSL = stripSSL
|
||||||
p.Address = address
|
p.Address = address
|
||||||
|
|
||||||
if scriptPath != "" {
|
if scriptPath != "" {
|
||||||
|
@ -236,9 +180,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) error {
|
func (p *HTTPProxy) ConfigureTLS(address string, proxyPort int, httpPort int, scriptPath string, certFile string, keyFile string, stripSSL bool) (err error) {
|
||||||
err := p.Configure(address, proxyPort, httpPort, scriptPath)
|
if p.Configure(address, proxyPort, httpPort, scriptPath, stripSSL); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +192,6 @@ func (p *HTTPProxy) ConfigureTLS(address string, proxyPort int, httpPort int, sc
|
||||||
|
|
||||||
rawCert, _ := ioutil.ReadFile(p.CertFile)
|
rawCert, _ := ioutil.ReadFile(p.CertFile)
|
||||||
rawKey, _ := ioutil.ReadFile(p.KeyFile)
|
rawKey, _ := ioutil.ReadFile(p.KeyFile)
|
||||||
|
|
||||||
ourCa, err := tls.X509KeyPair(rawCert, rawKey)
|
ourCa, err := tls.X509KeyPair(rawCert, rawKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
90
modules/http_proxy_base_filters.go
Normal file
90
modules/http_proxy_base_filters.go
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
package modules
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/bettercap/bettercap/core"
|
||||||
|
"github.com/bettercap/bettercap/log"
|
||||||
|
|
||||||
|
"github.com/elazarl/goproxy"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *HTTPProxy) onRequestFilter(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
|
||||||
|
log.Debug("(%s) < %s %s %s%s", core.Green(p.Name), req.RemoteAddr, req.Method, req.Host, req.URL.Path)
|
||||||
|
|
||||||
|
// do we have a proxy script?
|
||||||
|
if p.Script == nil {
|
||||||
|
return req, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// run the module OnRequest callback if defined
|
||||||
|
jsreq, jsres := p.Script.OnRequest(req)
|
||||||
|
if jsreq != nil {
|
||||||
|
// the request has been changed by the script
|
||||||
|
p.logRequestAction(req, jsreq)
|
||||||
|
return jsreq.ToRequest(), nil
|
||||||
|
} else if jsres != nil {
|
||||||
|
// a fake response has been returned by the script
|
||||||
|
p.logResponseAction(req, jsres)
|
||||||
|
return req, jsres.ToResponse(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
return req, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *HTTPProxy) onResponseFilter(res *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
|
||||||
|
// sometimes it happens ¯\_(ツ)_/¯
|
||||||
|
if res == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
req := res.Request
|
||||||
|
log.Debug("(%s) > %s %s %s%s", core.Green(p.Name), req.RemoteAddr, req.Method, req.Host, req.URL.Path)
|
||||||
|
|
||||||
|
// do we have a proxy script?
|
||||||
|
if p.Script == nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
_, 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *HTTPProxy) logRequestAction(req *http.Request, jsreq *JSRequest) {
|
||||||
|
p.sess.Events.Add(p.Name+".spoofed-request", struct {
|
||||||
|
To string
|
||||||
|
Method string
|
||||||
|
Host string
|
||||||
|
Path string
|
||||||
|
Size int
|
||||||
|
}{
|
||||||
|
strings.Split(req.RemoteAddr, ":")[0],
|
||||||
|
jsreq.Method,
|
||||||
|
jsreq.Hostname,
|
||||||
|
jsreq.Path,
|
||||||
|
len(jsreq.Body),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *HTTPProxy) logResponseAction(req *http.Request, jsres *JSResponse) {
|
||||||
|
p.sess.Events.Add(p.Name+".spoofed-response", struct {
|
||||||
|
To string
|
||||||
|
Method string
|
||||||
|
Host string
|
||||||
|
Path string
|
||||||
|
Size int
|
||||||
|
}{
|
||||||
|
strings.Split(req.RemoteAddr, ":")[0],
|
||||||
|
req.Method,
|
||||||
|
req.Host,
|
||||||
|
req.URL.Path,
|
||||||
|
len(jsres.Body),
|
||||||
|
})
|
||||||
|
}
|
|
@ -31,6 +31,10 @@ func NewHttpsProxy(s *session.Session) *HttpsProxy {
|
||||||
"8083",
|
"8083",
|
||||||
"Port to bind the HTTPS proxy to."))
|
"Port to bind the HTTPS proxy to."))
|
||||||
|
|
||||||
|
p.AddParam(session.NewBoolParameter("https.proxy.sslstrip",
|
||||||
|
"true",
|
||||||
|
"Enable or disable SSL stripping."))
|
||||||
|
|
||||||
p.AddParam(session.NewStringParameter("https.proxy.certificate",
|
p.AddParam(session.NewStringParameter("https.proxy.certificate",
|
||||||
"~/.bettercap-ca.cert.pem",
|
"~/.bettercap-ca.cert.pem",
|
||||||
"",
|
"",
|
||||||
|
@ -81,36 +85,27 @@ func (p *HttpsProxy) Configure() error {
|
||||||
var scriptPath string
|
var scriptPath string
|
||||||
var certFile string
|
var certFile string
|
||||||
var keyFile string
|
var keyFile string
|
||||||
|
var stripSSL bool
|
||||||
|
|
||||||
if p.Running() == true {
|
if p.Running() == true {
|
||||||
return session.ErrAlreadyStarted
|
return session.ErrAlreadyStarted
|
||||||
}
|
} else if err, address = p.StringParam("https.proxy.address"); err != nil {
|
||||||
|
|
||||||
if err, address = p.StringParam("https.proxy.address"); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
} else if err, proxyPort = p.IntParam("https.proxy.port"); err != nil {
|
||||||
|
|
||||||
if err, proxyPort = p.IntParam("https.proxy.port"); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
} else if err, httpPort = p.IntParam("https.port"); err != nil {
|
||||||
|
|
||||||
if err, httpPort = p.IntParam("https.port"); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
} else if err, stripSSL = p.BoolParam("https.proxy.sslstrip"); err != nil {
|
||||||
|
return err
|
||||||
if err, certFile = p.StringParam("https.proxy.certificate"); err != nil {
|
} else if err, certFile = p.StringParam("https.proxy.certificate"); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if certFile, err = core.ExpandPath(certFile); err != nil {
|
} else if certFile, err = core.ExpandPath(certFile); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
} else if err, keyFile = p.StringParam("https.proxy.key"); err != nil {
|
||||||
|
|
||||||
if err, keyFile = p.StringParam("https.proxy.key"); err != nil {
|
|
||||||
return err
|
return err
|
||||||
} else if keyFile, err = core.ExpandPath(keyFile); err != nil {
|
} else if keyFile, err = core.ExpandPath(keyFile); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
} else if err, scriptPath = p.StringParam("https.proxy.script"); err != nil {
|
||||||
|
|
||||||
if err, scriptPath = p.StringParam("https.proxy.script"); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +120,7 @@ func (p *HttpsProxy) Configure() error {
|
||||||
log.Info("Loading proxy certification authority TLS certificate from %s", certFile)
|
log.Info("Loading proxy certification authority TLS certificate from %s", certFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.proxy.ConfigureTLS(address, proxyPort, httpPort, scriptPath, certFile, keyFile)
|
return p.proxy.ConfigureTLS(address, proxyPort, httpPort, scriptPath, certFile, keyFile, stripSSL)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *HttpsProxy) Start() error {
|
func (p *HttpsProxy) Start() error {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue