mirror of https://github.com/n1nj4sec/pupy.git
170 lines
4.4 KiB
Go
170 lines
4.4 KiB
Go
package main
|
|
|
|
import (
|
|
"net"
|
|
"path"
|
|
|
|
"io/ioutil"
|
|
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"flag"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
iniflags "github.com/vharitonsky/iniflags"
|
|
)
|
|
|
|
var (
|
|
ProxyBindHost = "[::]:9876"
|
|
ExternalBindHost = "::"
|
|
|
|
DnsBindPort uint = 5454
|
|
ProxyHostname = ""
|
|
UDPSize uint = 1400
|
|
ListenerCA = path.Join("..", "crypto", "proxy-ca.crt")
|
|
ListenerCAKey = path.Join("..", "crypto", "proxy-ca.key")
|
|
ListenerKey = path.Join("..", "crypto", "proxy.key")
|
|
ListenerCert = path.Join("..", "crypto", "proxy.crt")
|
|
ClientKey = path.Join("..", "crypto", "proxy-client.key")
|
|
ClientCert = path.Join("..", "crypto", "proxy-client.crt")
|
|
|
|
PortMaps []PortMap
|
|
|
|
OnListenerEnabledURL = ""
|
|
OnListenerDisabledURL = ""
|
|
|
|
ListenerConfig *tls.Config
|
|
)
|
|
|
|
func init() {
|
|
generate := false
|
|
loglevel := "ERROR"
|
|
portmap := ""
|
|
|
|
flag.StringVar(&ProxyBindHost, "listen-proxy", ProxyBindHost, "IP address to bind pupysh listener side")
|
|
flag.StringVar(&ExternalBindHost, "listen", ExternalBindHost, "IP address to bind services listener side")
|
|
flag.UintVar(&DnsBindPort, "dns-port", DnsBindPort, "Port to bind DNS listeners (if any)")
|
|
flag.UintVar(&UDPSize, "udp-mtu-size", UDPSize, "MTU Size for DNS and KCP UDP Packets")
|
|
flag.StringVar(&ListenerCA, "ca", ListenerCA, "Path to CA certificate (pupysh side)")
|
|
flag.StringVar(&ListenerKey, "key", ListenerKey, "Path to TLS key (pupysh side)")
|
|
flag.StringVar(&ListenerCert, "cert", ListenerCert, "Path to TLS cert (pupysh side)")
|
|
flag.StringVar(&portmap, "port-map", portmap, "Automatically substitute ports (example: \"443:1443 80:8080\")")
|
|
flag.StringVar(&ProxyHostname, "hostname-proxy", ProxyHostname,
|
|
"Hostname for pupysh listener side (used with generate)")
|
|
flag.StringVar(&loglevel, "loglevel", loglevel, "Set log level")
|
|
flag.StringVar(&OnListenerEnabledURL, "on-enabled-url", OnListenerEnabledURL,
|
|
"Send GET request when at least one client connected")
|
|
flag.StringVar(&OnListenerDisabledURL, "on-disabled-url", OnListenerDisabledURL,
|
|
"Send GET request when at least one client connected")
|
|
flag.BoolVar(&generate, "generate", false, "Generate all the keys")
|
|
|
|
iniflags.Parse()
|
|
|
|
switch strings.ToLower(loglevel) {
|
|
case "error":
|
|
log.SetLevel(log.ErrorLevel)
|
|
case "err":
|
|
log.SetLevel(log.ErrorLevel)
|
|
case "warning":
|
|
log.SetLevel(log.WarnLevel)
|
|
case "warn":
|
|
log.SetLevel(log.WarnLevel)
|
|
case "info":
|
|
log.SetLevel(log.InfoLevel)
|
|
case "debug":
|
|
log.SetLevel(log.DebugLevel)
|
|
default:
|
|
log.Fatalln("Invalid log level", loglevel)
|
|
}
|
|
|
|
if strings.Contains(portmap, ":") {
|
|
for _, mapping := range strings.Split(portmap, " ") {
|
|
if !strings.Contains(portmap, ":") {
|
|
continue
|
|
}
|
|
|
|
parts := strings.Split(mapping, ":")
|
|
if len(parts) != 2 {
|
|
log.Fatalln("Invalid mapping specification: ", parts)
|
|
}
|
|
|
|
var (
|
|
from, to int
|
|
err error
|
|
)
|
|
|
|
from, err = strconv.Atoi(parts[0])
|
|
if err != nil {
|
|
log.Fatalln("Invalid mapping specification: ", parts, "From: ", err)
|
|
}
|
|
|
|
to, err = strconv.Atoi(parts[1])
|
|
if err != nil {
|
|
log.Fatalln("Invalid mapping specification: ", parts, "To: ", err)
|
|
}
|
|
|
|
PortMaps = append(PortMaps, PortMap{
|
|
From: from,
|
|
To: to,
|
|
})
|
|
|
|
}
|
|
}
|
|
|
|
host, _, err := net.SplitHostPort(ExternalBindHost)
|
|
if err == nil && host != "" {
|
|
ExternalBindHost = host
|
|
}
|
|
|
|
if ExternalBindHost == "" {
|
|
ExternalBindHost = "::"
|
|
}
|
|
|
|
if strings.Index(ExternalBindHost, ":") != -1 {
|
|
ExternalBindHost = "[" + ExternalBindHost + "]"
|
|
}
|
|
|
|
log.Warn("Mapper binds to ", ExternalBindHost)
|
|
log.Warn("Proxy binds to ", ProxyBindHost)
|
|
|
|
if generate {
|
|
log.Warn("Genrating NEW keys")
|
|
generateKeys()
|
|
}
|
|
|
|
cert, err := tls.LoadX509KeyPair(ListenerCert, ListenerKey)
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
|
|
pem, err := ioutil.ReadFile(ListenerCA)
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
|
|
caPool := x509.NewCertPool()
|
|
if !caPool.AppendCertsFromPEM(pem) {
|
|
log.Fatalln("Could't append CA certificates to CA pool")
|
|
}
|
|
|
|
ListenerConfig = &tls.Config{
|
|
Certificates: []tls.Certificate{cert},
|
|
CipherSuites: []uint16{
|
|
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
|
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
|
tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
|
|
tls.TLS_RSA_WITH_AES_256_CBC_SHA,
|
|
},
|
|
ClientAuth: tls.RequireAndVerifyClientCert,
|
|
ClientCAs: caPool,
|
|
NextProtos: []string{"pp/1"},
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
NewDaemon(ProxyBindHost).ListenAndServe()
|
|
}
|