mirror of
https://github.com/bettercap/bettercap
synced 2025-08-22 22:34:22 -07:00
Merge 82186e2b47
into c03a549c00
This commit is contained in:
commit
0faab40848
8 changed files with 281 additions and 20 deletions
1
main.go
1
main.go
|
@ -45,6 +45,7 @@ func main() {
|
|||
sess.Register(modules.NewTcpProxy(sess))
|
||||
sess.Register(modules.NewHttpProxy(sess))
|
||||
sess.Register(modules.NewHttpsProxy(sess))
|
||||
sess.Register(modules.NewCustomHttpProxy(sess))
|
||||
sess.Register(modules.NewHttpServer(sess))
|
||||
sess.Register(modules.NewRestAPI(sess))
|
||||
sess.Register(modules.NewWOL(sess))
|
||||
|
|
99
modules/custom_http_proxy.go
Normal file
99
modules/custom_http_proxy.go
Normal file
|
@ -0,0 +1,99 @@
|
|||
package modules
|
||||
|
||||
import (
|
||||
"github.com/bettercap/bettercap/session"
|
||||
)
|
||||
|
||||
type CustomHttpProxy struct {
|
||||
session.SessionModule
|
||||
proxy *CustomProxy
|
||||
}
|
||||
|
||||
func NewCustomHttpProxy(s *session.Session) *CustomHttpProxy {
|
||||
p := &CustomHttpProxy{
|
||||
SessionModule: session.NewSessionModule("custom.http.proxy", s),
|
||||
proxy: NewCustomProxy(s),
|
||||
}
|
||||
|
||||
p.AddParam(session.NewStringParameter("custom.http.port",
|
||||
"80", session.PortListValidator,
|
||||
"HTTP port to redirect when the proxy is activated."))
|
||||
|
||||
p.AddParam(session.NewStringParameter("custom.http.proxy.address",
|
||||
session.ParamIfaceAddress,
|
||||
session.IPv4Validator,
|
||||
"Address to bind the Custom HTTP proxy to."))
|
||||
|
||||
p.AddParam(session.NewIntParameter("custom.http.proxy.port",
|
||||
"8080",
|
||||
"Port to bind the Custom HTTP proxy to."))
|
||||
|
||||
p.AddParam(session.NewBoolParameter("custom.http.proxy.sslstrip",
|
||||
"false",
|
||||
"Enable or disable SSL stripping."))
|
||||
|
||||
p.AddHandler(session.NewModuleHandler("custom.http.proxy on", "",
|
||||
"Start Custom HTTP proxy.",
|
||||
func(args []string) error {
|
||||
return p.Start()
|
||||
}))
|
||||
|
||||
p.AddHandler(session.NewModuleHandler("custom.http.proxy off", "",
|
||||
"Stop Custom HTTP proxy.",
|
||||
func(args []string) error {
|
||||
return p.Stop()
|
||||
}))
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *CustomHttpProxy) Name() string {
|
||||
return "custom.http.proxy"
|
||||
}
|
||||
|
||||
func (p *CustomHttpProxy) Description() string {
|
||||
return "Use a custom HTTP proxy server instead of the builtin one."
|
||||
}
|
||||
|
||||
func (p *CustomHttpProxy) Author() string {
|
||||
return "Simone Margaritelli <evilsocket@protonmail.com>"
|
||||
}
|
||||
|
||||
func (p *CustomHttpProxy) Configure() error {
|
||||
var err error
|
||||
var address string
|
||||
var proxyPort int
|
||||
var httpPort []string
|
||||
var stripSSL bool
|
||||
|
||||
if p.Running() {
|
||||
return session.ErrAlreadyStarted
|
||||
} else if err, address = p.StringParam("custom.http.proxy.address"); err != nil {
|
||||
return err
|
||||
} else if err, proxyPort = p.IntParam("custom.http.proxy.port"); err != nil {
|
||||
return err
|
||||
} else if err, httpPort = p.ListParam("custom.http.port"); err != nil {
|
||||
return err
|
||||
} else if err, stripSSL = p.BoolParam("custom.http.proxy.sslstrip"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return p.proxy.Configure(address, proxyPort, httpPort, stripSSL)
|
||||
}
|
||||
|
||||
func (p *CustomHttpProxy) Start() error {
|
||||
if err := p.Configure(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return p.SetRunning(true, func() {
|
||||
p.proxy.Start()
|
||||
})
|
||||
}
|
||||
|
||||
func (p *CustomHttpProxy) Stop() error {
|
||||
return p.SetRunning(false, func() {
|
||||
p.proxy.Stop()
|
||||
})
|
||||
}
|
||||
|
119
modules/custom_proxy_base.go
Normal file
119
modules/custom_proxy_base.go
Normal file
|
@ -0,0 +1,119 @@
|
|||
package modules
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"github.com/bettercap/bettercap/firewall"
|
||||
"net"
|
||||
"github.com/bettercap/bettercap/session"
|
||||
"strings"
|
||||
"github.com/bettercap/bettercap/log"
|
||||
"github.com/bettercap/bettercap/core"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type CustomProxy struct {
|
||||
Name string
|
||||
Address string
|
||||
Redirection *firewall.Redirection
|
||||
|
||||
isTLS bool
|
||||
isRunning bool
|
||||
stripper *SSLStripper
|
||||
sniListener net.Listener
|
||||
sess *session.Session
|
||||
}
|
||||
|
||||
func NewCustomProxy(s *session.Session) *CustomProxy {
|
||||
p := &CustomProxy{
|
||||
Name: "custom.proxy",
|
||||
sess: s,
|
||||
stripper: NewSSLStripper(s, false),
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *CustomProxy) doProxy(req *http.Request) bool {
|
||||
blacklist := []string{
|
||||
"localhost",
|
||||
"127.0.0.1",
|
||||
}
|
||||
|
||||
if req.Host == "" {
|
||||
log.Error("Got request with empty host: %v", req)
|
||||
return false
|
||||
}
|
||||
|
||||
for _, blacklisted := range blacklist {
|
||||
if strings.Split(req.Host, ":")[0] == blacklisted {
|
||||
log.Error("Got request with blacklisted host: %s", req.Host)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *CustomProxy) stripPort(s string) string {
|
||||
ix := strings.IndexRune(s, ':')
|
||||
if ix == -1 {
|
||||
return s
|
||||
}
|
||||
return s[:ix]
|
||||
}
|
||||
|
||||
func (p *CustomProxy) Configure(proxyAddress string, proxyPort int, srcPort []string, stripSSL bool) error {
|
||||
|
||||
p.stripper.Enable(stripSSL)
|
||||
p.Address = proxyAddress
|
||||
|
||||
if !p.sess.Firewall.IsForwardingEnabled() {
|
||||
log.Info("Enabling forwarding.")
|
||||
p.sess.Firewall.EnableForwarding(true)
|
||||
}
|
||||
|
||||
for _,v := range srcPort {
|
||||
|
||||
port, _ := strconv.Atoi(v)
|
||||
p.Redirection = firewall.NewRedirection(p.sess.Interface.Name(),
|
||||
"TCP",
|
||||
port,
|
||||
p.Address,
|
||||
proxyPort)
|
||||
|
||||
if err := p.sess.Firewall.EnableRedirection(p.Redirection, true); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debug("Applied redirection %s", p.Redirection.String())
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *CustomProxy) Start() {
|
||||
go func() {
|
||||
var err error
|
||||
|
||||
strip := core.Yellow("enabled")
|
||||
if !p.stripper.Enabled() {
|
||||
strip = core.Dim("disabled")
|
||||
}
|
||||
|
||||
log.Info("%s started on %s (sslstrip %s)", core.Green(p.Name), p.Address, strip)
|
||||
|
||||
if err != nil && err.Error() != "http: Server closed" {
|
||||
log.Fatal("%s", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (p *CustomProxy) Stop() error {
|
||||
if p.Redirection != nil {
|
||||
log.Debug("Disabling redirection %s", p.Redirection.String())
|
||||
if err := p.sess.Firewall.EnableRedirection(p.Redirection, false); err != nil {
|
||||
return err
|
||||
}
|
||||
p.Redirection = nil
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -15,8 +15,8 @@ func NewHttpProxy(s *session.Session) *HttpProxy {
|
|||
proxy: NewHTTPProxy(s),
|
||||
}
|
||||
|
||||
p.AddParam(session.NewIntParameter("http.port",
|
||||
"80",
|
||||
p.AddParam(session.NewStringParameter("http.port",
|
||||
"80", session.PortListValidator,
|
||||
"HTTP port to redirect when the proxy is activated."))
|
||||
|
||||
p.AddParam(session.NewStringParameter("http.proxy.address",
|
||||
|
@ -68,7 +68,7 @@ func (p *HttpProxy) Configure() error {
|
|||
var err error
|
||||
var address string
|
||||
var proxyPort int
|
||||
var httpPort int
|
||||
var httpPort []string
|
||||
var scriptPath string
|
||||
var stripSSL bool
|
||||
|
||||
|
@ -78,7 +78,7 @@ func (p *HttpProxy) Configure() error {
|
|||
return err
|
||||
} else if err, proxyPort = p.IntParam("http.proxy.port"); err != nil {
|
||||
return err
|
||||
} else if err, httpPort = p.IntParam("http.port"); err != nil {
|
||||
} else if err, httpPort = p.ListParam("http.port"); err != nil {
|
||||
return err
|
||||
} else if err, scriptPath = p.StringParam("http.proxy.script"); err != nil {
|
||||
return err
|
||||
|
|
|
@ -106,7 +106,7 @@ 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 []string, scriptPath string, stripSSL bool) error {
|
||||
var err error
|
||||
|
||||
p.stripper.Enable(stripSSL)
|
||||
|
@ -132,17 +132,21 @@ func (p *HTTPProxy) Configure(address string, proxyPort int, httpPort int, scrip
|
|||
p.sess.Firewall.EnableForwarding(true)
|
||||
}
|
||||
|
||||
|
||||
for _,v := range httpPort {
|
||||
|
||||
port, _ := strconv.Atoi(v)
|
||||
p.Redirection = firewall.NewRedirection(p.sess.Interface.Name(),
|
||||
"TCP",
|
||||
httpPort,
|
||||
port,
|
||||
p.Address,
|
||||
proxyPort)
|
||||
|
||||
if err := p.sess.Firewall.EnableRedirection(p.Redirection, true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debug("Applied redirection %s", p.Redirection.String())
|
||||
}
|
||||
|
||||
p.sess.UnkCmdCallback = func(cmd string) bool {
|
||||
if p.Script != nil {
|
||||
|
@ -187,7 +191,7 @@ 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) {
|
||||
func (p *HTTPProxy) ConfigureTLS(address string, proxyPort int, httpPort []string, scriptPath string, certFile string, keyFile string, stripSSL bool) (err error) {
|
||||
if p.Configure(address, proxyPort, httpPort, scriptPath, stripSSL); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
37
modules/http_proxy_script_test.go
Normal file
37
modules/http_proxy_script_test.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
package modules
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/bettercap/bettercap/log"
|
||||
"github.com/bettercap/bettercap/session"
|
||||
)
|
||||
|
||||
func getScript(src string) *HttpProxyScript {
|
||||
sess := session.Session{}
|
||||
sess.Env = session.NewEnvironment(&sess, "")
|
||||
|
||||
err, script := LoadHttpProxyScriptSource("", src, &sess)
|
||||
if err != nil {
|
||||
log.Fatal("%s", err)
|
||||
}
|
||||
return script
|
||||
}
|
||||
|
||||
func getRequest() *http.Request {
|
||||
req, err := http.NewRequest("GET", "http://www.google.com/", nil)
|
||||
if err != nil {
|
||||
log.Fatal("%s", err)
|
||||
}
|
||||
return req
|
||||
}
|
||||
|
||||
func BenchmarkOnRequest(b *testing.B) {
|
||||
script := getScript("function onRequest(req,res){}")
|
||||
req := getRequest()
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
script.OnRequest(req)
|
||||
}
|
||||
}
|
|
@ -18,8 +18,8 @@ func NewHttpsProxy(s *session.Session) *HttpsProxy {
|
|||
proxy: NewHTTPProxy(s),
|
||||
}
|
||||
|
||||
p.AddParam(session.NewIntParameter("https.port",
|
||||
"443",
|
||||
p.AddParam(session.NewStringParameter("https.port",
|
||||
"443", session.PortListValidator,
|
||||
"HTTPS port to redirect when the proxy is activated."))
|
||||
|
||||
p.AddParam(session.NewStringParameter("https.proxy.address",
|
||||
|
@ -81,7 +81,7 @@ func (p *HttpsProxy) Configure() error {
|
|||
var err error
|
||||
var address string
|
||||
var proxyPort int
|
||||
var httpPort int
|
||||
var httpsPort []string
|
||||
var scriptPath string
|
||||
var certFile string
|
||||
var keyFile string
|
||||
|
@ -93,7 +93,7 @@ func (p *HttpsProxy) Configure() error {
|
|||
return err
|
||||
} else if err, proxyPort = p.IntParam("https.proxy.port"); err != nil {
|
||||
return err
|
||||
} else if err, httpPort = p.IntParam("https.port"); err != nil {
|
||||
} else if err, httpsPort = p.ListParam("https.port"); err != nil {
|
||||
return err
|
||||
} else if err, stripSSL = p.BoolParam("https.proxy.sslstrip"); err != nil {
|
||||
return err
|
||||
|
@ -120,7 +120,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, httpsPort, scriptPath, certFile, keyFile, stripSSL)
|
||||
}
|
||||
|
||||
func (p *HttpsProxy) Start() error {
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
)
|
||||
|
||||
const IPv4Validator = `^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$`
|
||||
const PortListValidator = `^(([0-9]|[1-9]\d{1,3}|[1-5]\d{4}|6[0-5]{2}[0-3][0-5])+[,]+)*(([0-9]|[1-9]\d{1,3}|[1-5]\d{4}|6[0-5]{2}[0-3][0-5])+)$`
|
||||
|
||||
type ModuleHandler struct {
|
||||
Name string
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue