started working on #154

This commit is contained in:
evilsocket 2018-03-08 17:37:55 +01:00
parent 1a8826436e
commit 741d9d8f6e
No known key found for this signature in database
GPG key ID: 1564D7F30393A456
4 changed files with 125 additions and 91 deletions

View file

@ -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 {

View file

@ -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

View 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),
})
}

View file

@ -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 {