1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
package https_server
import (
"context"
"fmt"
"net/http"
"strings"
"time"
"github.com/bettercap/bettercap/session"
"github.com/bettercap/bettercap/tls"
"github.com/evilsocket/islazy/fs"
"github.com/evilsocket/islazy/tui"
)
type HttpsServer struct {
session.SessionModule
server *http.Server
certFile string
keyFile string
}
func NewHttpsServer(s *session.Session) *HttpsServer {
mod := &HttpsServer{
SessionModule: session.NewSessionModule("https.server", s),
server: &http.Server{},
}
mod.AddParam(session.NewStringParameter("https.server.path",
".",
"",
"Server folder."))
mod.AddParam(session.NewStringParameter("https.server.address",
session.ParamIfaceAddress,
session.IPv4Validator,
"Address to bind the http server to."))
mod.AddParam(session.NewIntParameter("https.server.port",
"443",
"Port to bind the http server to."))
mod.AddParam(session.NewStringParameter("https.server.certificate",
"~/.bettercap-httpd.cert.pem",
"",
"TLS certificate file (will be auto generated if filled but not existing)."))
mod.AddParam(session.NewStringParameter("https.server.key",
"~/.bettercap-httpd.key.pem",
"",
"TLS key file (will be auto generated if filled but not existing)."))
tls.CertConfigToModule("https.server", &mod.SessionModule, tls.DefaultLegitConfig)
mod.AddHandler(session.NewModuleHandler("https.server on", "",
"Start https server.",
func(args []string) error {
return mod.Start()
}))
mod.AddHandler(session.NewModuleHandler("https.server off", "",
"Stop https server.",
func(args []string) error {
return mod.Stop()
}))
return mod
}
func (mod *HttpsServer) Name() string {
return "https.server"
}
func (mod *HttpsServer) Description() string {
return "A simple HTTPS server, to be used to serve files and scripts across the network."
}
func (mod *HttpsServer) Author() string {
return "Simone Margaritelli <evilsocket@gmail.com>"
}
func (mod *HttpsServer) Configure() error {
var err error
var path string
var address string
var port int
var certFile string
var keyFile string
if mod.Running() {
return session.ErrAlreadyStarted(mod.Name())
}
if err, path = mod.StringParam("https.server.path"); err != nil {
return err
}
router := http.NewServeMux()
fileServer := http.FileServer(http.Dir(path))
router.HandleFunc("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
mod.Debug("%s %s %s%s", tui.Bold(strings.Split(r.RemoteAddr, ":")[0]), r.Method, r.Host, r.URL.Path)
fileServer.ServeHTTP(w, r)
}))
mod.server.Handler = router
if err, address = mod.StringParam("https.server.address"); err != nil {
return err
}
if err, port = mod.IntParam("https.server.port"); err != nil {
return err
}
mod.server.Addr = fmt.Sprintf("%s:%d", address, port)
if err, certFile = mod.StringParam("https.server.certificate"); err != nil {
return err
} else if certFile, err = fs.Expand(certFile); err != nil {
return err
}
if err, keyFile = mod.StringParam("https.server.key"); err != nil {
return err
} else if keyFile, err = fs.Expand(keyFile); err != nil {
return err
}
if !fs.Exists(certFile) || !fs.Exists(keyFile) {
cfg, err := tls.CertConfigFromModule("https.server", mod.SessionModule)
if err != nil {
return err
}
mod.Debug("%+v", cfg)
mod.Info("generating server TLS key to %s", keyFile)
mod.Info("generating server TLS certificate to %s", certFile)
if err := tls.Generate(cfg, certFile, keyFile, false); err != nil {
return err
}
} else {
mod.Info("loading server TLS key from %s", keyFile)
mod.Info("loading server TLS certificate from %s", certFile)
}
mod.certFile = certFile
mod.keyFile = keyFile
return nil
}
func (mod *HttpsServer) Start() error {
if err := mod.Configure(); err != nil {
return err
}
return mod.SetRunning(true, func() {
mod.Info("starting on https://%s", mod.server.Addr)
if err := mod.server.ListenAndServeTLS(mod.certFile, mod.keyFile); err != nil && err != http.ErrServerClosed {
mod.Error("%v", err)
mod.Stop()
}
})
}
func (mod *HttpsServer) Stop() error {
return mod.SetRunning(false, func() {
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
mod.server.Shutdown(ctx)
})
}
|