mirror of
https://github.com/bettercap/bettercap
synced 2025-07-06 13:02:12 -07:00
new: api.rest is now on HTTPS (closes #5)
This commit is contained in:
parent
be570432ef
commit
47e814c9a9
4 changed files with 143 additions and 12 deletions
26
core/core.go
26
core/core.go
|
@ -2,7 +2,10 @@ package core
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -20,3 +23,26 @@ func Exec(executable string, args []string) (string, error) {
|
|||
return strings.Trim(string(raw), "\r\n\t "), nil
|
||||
}
|
||||
}
|
||||
|
||||
func Exists(path string) bool {
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func ExpandPath(path string) (string, error) {
|
||||
// Check if path is empty
|
||||
if path != "" {
|
||||
if strings.HasPrefix(path, "~") {
|
||||
usr, err := user.Current()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// Replace only the first occurence of ~
|
||||
path = strings.Replace(path, "~", usr.HomeDir, 1)
|
||||
}
|
||||
return filepath.Abs(path)
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
|
10
main.go
10
main.go
|
@ -30,11 +30,11 @@ func main() {
|
|||
sess.Register(session_modules.NewRestAPI(sess))
|
||||
|
||||
if err = sess.Start(); err != nil {
|
||||
sess.Events.Log(session.FATAL, "%s", err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err = sess.Run("events.stream on"); err != nil {
|
||||
sess.Events.Log(session.FATAL, "%s", err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
defer sess.Close()
|
||||
|
@ -43,21 +43,21 @@ func main() {
|
|||
for _, cmd := range strings.Split(*sess.Options.Commands, ";") {
|
||||
cmd = strings.Trim(cmd, "\r\n\t ")
|
||||
if err = sess.Run(cmd); err != nil {
|
||||
sess.Events.Log(session.FATAL, "%s", err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if *sess.Options.Caplet != "" {
|
||||
if err = sess.RunCaplet(*sess.Options.Caplet); err != nil {
|
||||
sess.Events.Log(session.FATAL, "%s", err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
for sess.Active {
|
||||
line, err := sess.ReadLine()
|
||||
if err != nil {
|
||||
sess.Events.Log(session.FATAL, "%s", err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if line == "" || line[0] == '#' {
|
||||
|
|
|
@ -8,7 +8,9 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/evilsocket/bettercap-ng/core"
|
||||
"github.com/evilsocket/bettercap-ng/session"
|
||||
"github.com/evilsocket/bettercap-ng/tls"
|
||||
)
|
||||
|
||||
type RestAPI struct {
|
||||
|
@ -16,6 +18,8 @@ type RestAPI struct {
|
|||
server *http.Server
|
||||
username string
|
||||
password string
|
||||
certFile string
|
||||
keyFile string
|
||||
}
|
||||
|
||||
func NewRestAPI(s *session.Session) *RestAPI {
|
||||
|
@ -32,7 +36,7 @@ func NewRestAPI(s *session.Session) *RestAPI {
|
|||
"Address to bind the API REST server to."))
|
||||
|
||||
api.AddParam(session.NewIntParameter("api.rest.port",
|
||||
"8081",
|
||||
"8083",
|
||||
"Port to bind the API REST server to."))
|
||||
|
||||
api.AddParam(session.NewStringParameter("api.rest.username",
|
||||
|
@ -40,6 +44,16 @@ func NewRestAPI(s *session.Session) *RestAPI {
|
|||
"",
|
||||
"API authentication username."))
|
||||
|
||||
api.AddParam(session.NewStringParameter("api.rest.certificate",
|
||||
"~/.bettercap-ng.certificate.pem",
|
||||
"",
|
||||
"API TLS certificate."))
|
||||
|
||||
api.AddParam(session.NewStringParameter("api.rest.key",
|
||||
"~/.bettercap-ng.key.pem",
|
||||
"",
|
||||
"API TLS key"))
|
||||
|
||||
api.AddParam(session.NewStringParameter("api.rest.password",
|
||||
"",
|
||||
"",
|
||||
|
@ -229,6 +243,24 @@ func (api *RestAPI) Start() error {
|
|||
port = v.(int)
|
||||
}
|
||||
|
||||
if err, v := api.Param("api.rest.certificate").Get(api.Session); err != nil {
|
||||
return err
|
||||
} else {
|
||||
api.certFile = v.(string)
|
||||
if api.certFile, err = core.ExpandPath(api.certFile); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err, v := api.Param("api.rest.key").Get(api.Session); err != nil {
|
||||
return err
|
||||
} else {
|
||||
api.keyFile = v.(string)
|
||||
if api.keyFile, err = core.ExpandPath(api.keyFile); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err, v := api.Param("api.rest.username").Get(api.Session); err != nil {
|
||||
return err
|
||||
} else {
|
||||
|
@ -247,16 +279,25 @@ func (api *RestAPI) Start() error {
|
|||
}
|
||||
}
|
||||
|
||||
if core.Exists(api.certFile) == false || core.Exists(api.keyFile) == false {
|
||||
api.Session.Events.Log(session.INFO, "Generating RSA key to %s", api.keyFile)
|
||||
api.Session.Events.Log(session.INFO, "Generating TLS certificate to %s", api.certFile)
|
||||
if err := tls.Generate(api.certFile, api.keyFile); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
api.Session.Events.Log(session.INFO, "Loading RSA key from %s", api.keyFile)
|
||||
api.Session.Events.Log(session.INFO, "Loading TLS certificate from %s", api.certFile)
|
||||
}
|
||||
|
||||
if api.Running() == false {
|
||||
api.SetRunning(true)
|
||||
|
||||
api.server.Addr = fmt.Sprintf("%s:%d", address, port)
|
||||
go func() {
|
||||
|
||||
api.Session.Events.Log(session.INFO, "API server starting on http://%s", api.server.Addr)
|
||||
err := api.server.ListenAndServe()
|
||||
if err != nil {
|
||||
api.Session.Events.Log(session.ERROR, "%s", err)
|
||||
api.Session.Events.Log(session.INFO, "API server starting on https://%s", api.server.Addr)
|
||||
err := api.server.ListenAndServeTLS(api.certFile, api.keyFile)
|
||||
if err != nil && err != http.ErrServerClosed {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
|
|
64
tls/cert.go
Normal file
64
tls/cert.go
Normal file
|
@ -0,0 +1,64 @@
|
|||
package tls
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"math/big"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Generate(certPath string, keyPath string) error {
|
||||
keyfile, err := os.Create(keyPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer keyfile.Close()
|
||||
|
||||
certfile, err := os.Create(certPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer certfile.Close()
|
||||
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 4096)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
notBefore := time.Now()
|
||||
notAfter := notBefore.Add(time.Duration(24*365) * time.Hour)
|
||||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
||||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
template := x509.Certificate{
|
||||
SerialNumber: serialNumber,
|
||||
Subject: pkix.Name{
|
||||
CommonName: "bettercap-ng",
|
||||
Organization: []string{"bettercap-ng"},
|
||||
OrganizationalUnit: []string{"RSA key generation module"},
|
||||
},
|
||||
NotBefore: notBefore,
|
||||
NotAfter: notAfter,
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
|
||||
cert_raw, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := pem.Encode(keyfile, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return pem.Encode(certfile, &pem.Block{Type: "CERTIFICATE", Bytes: cert_raw})
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue