tun

package
v0.0.0-...-1f8f401 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 7, 2025 License: MIT Imports: 50 Imported by: 0

Documentation

Overview

Support code for TLS camouflage using uTLS.

The goal is: provide an http.RoundTripper abstraction that retains the features of http.Transport (e.g., persistent connections and HTTP/2 support), while making TLS connections using uTLS in place of crypto/tls. The challenge is: while http.Transport provides a DialTLS hook, setting it to non-nil disables automatic HTTP/2 support in the client. Most of the uTLS fingerprints contain an ALPN extension containing "h2"; i.e., they declare support for HTTP/2. If the server also supports HTTP/2, then uTLS may negotiate an HTTP/2 connection without the http.Transport knowing it, which leads to an HTTP/1.1 client speaking to an HTTP/2 server, a protocol error.

The code here uses an idea adapted from meek_lite in obfs4proxy: https://gitlab.com/yawning/obfs4/commit/4d453dab2120082b00bf6e63ab4aaeeda6b8d8a3 Instead of setting DialTLS on an http.Transport and exposing it directly, we expose a wrapper type, UTLSRoundTripper, that contains within it either an http.Transport or an http2.Transport. The first time a caller calls RoundTrip on the wrapper, we initiate a uTLS connection (bootstrapConn), then peek at the ALPN-negotiated protocol: if "h2", create an internal http2.Transport; otherwise, create an internal http.Transport. In either case, set DialTLS on the created Transport to a function that dials using uTLS. As a special case, the first time the DialTLS callback is called, it reuses bootstrapConn (the one made to peek at the ALPN), rather than make a new connection.

Subsequent calls to RoundTripper on the wrapper just pass the requests though the previously created http.Transport or http2.Transport. We assume that in future RoundTrips, the ALPN-negotiated protocol will remain the same as it was in the initial RoundTrip. At this point it is the http.Transport or http2.Transport calling DialTLS, not us, so we can't dynamically swap the underlying transport based on the ALPN.

https://bugs.torproject.org/29077 https://github.com/refraction-networking/utls/issues/16

Index

Constants

View Source
const (
	// WebRoot root path of APIs
	WebRoot = "emp3r0r"

	// CheckInAPI agent send POST to this API to report its system info
	CheckInAPI = WebRoot + "/checkin"

	// MsgAPI duplex tunnel between agent and cc
	MsgAPI = WebRoot + "/msg"

	// ReverseShellAPI duplex tunnel between agent and cc
	ReverseShellAPI = WebRoot + "/rshell"

	// ProxyAPI proxy interface
	ProxyAPI = WebRoot + "/proxy"

	// FTPAPI file transfer
	FTPAPI = WebRoot + "/ftp"

	// FileAPI host some files
	FileAPI = WebRoot + "/www"

	// Static hosting
	WWW = "/www/"
)
View Source
const (
	CA_CERT_FILE = "ca-cert.pem"
	CA_KEY_FILE  = "ca-key.pem"
)
View Source
const (
	TGT_UNIX = iota
	TGT_TCP
)
View Source
const (
	// MicrosoftNCSIURL is the URL used by Microsoft to check internet connectivity
	MicrosoftNCSIURL  = "http://www.msftncsi.com/ncsi.txt"
	MicrosoftNCSIResp = "Microsoft NCSI"

	// UbuntuConnectivityURL is the URL used by Ubuntu to check internet connectivity
	UbuntuConnectivityURL = "https://connectivity-check.ubuntu.com"
	// UbuntuConnectivityResp will be empty with 204 status code
	UbuntuConnectivityResp = 204
)

Variables

View Source
var (
	Stager_HTTP_Server http.Server
	Stager_Ctx         context.Context
	Stager_Cancel      context.CancelFunc
)
View Source
var CACrt = []byte("")

CACrt for TLS server cert signing

View Source
var ServerPubKey string

PEM encoded server public key

Functions

func AES_GCM_Decrypt

func AES_GCM_Decrypt(password, ciphertext []byte) ([]byte, error)

AES_GCM_Decrypt decrypts ciphertext with password using AES-GCM

func AES_GCM_Encrypt

func AES_GCM_Encrypt(password, plaintext []byte) ([]byte, error)

AES_GCM_Encrypt encrypts plaintext with password using AES-GCM

func Base64URLDecode

func Base64URLDecode(text string) []byte

Base64URLDecode decode a base64 encoded string (to []byte)

func Base64URLEncode

func Base64URLEncode(text string) string

Base64URLEncode encode a string with base64

func DeriveKey

func DeriveKey(password, salt []byte) []byte

func EmpHTTPClient

func EmpHTTPClient(c2_addr, proxyServer string) *http.Client

EmpHTTPClient add our CA to trusted CAs, while keeps TLS InsecureVerify on

func ExtractCABundle

func ExtractCABundle() (*x509.CertPool, error)

ExtractCABundle extracts built-in Ubuntu CA bundle

func FindIPToUse

func FindIPToUse(target string) string

FindIPToUse find an IP that resides in target IP range target: 192.168.1.1/24

func FwdToDport

func FwdToDport(ctx context.Context, cancel context.CancelFunc,
	to, sessionID, protocol string, h2 *h2conn.Conn, timeout int,
)

FwdToDport forward request to agent-side destination, h2 <-> tcp/udp

func GenCerts

func GenCerts(
	hosts []string,
	outname string,
	isCA bool,
) ([]byte, error)

GenCerts generate a CA cert or a server cert signed by CA cert if isCA is true, the outfile will be a CA cert/key named as ca-cert.pem/ca-key.pem if isCA is false, the outfile will be named as is, for example, outfile-cert.pem, outfile-key.pem Returns public key bytes

func GenerateRandomBytes

func GenerateRandomBytes(size int) ([]byte, error)

func GenerateSSHKeyPair

func GenerateSSHKeyPair() (privateKey, publicKey []byte, err error)

Generate a new key pair for use with openssh

func GetFingerprint

func GetFingerprint(cert_file string) string

GetFingerprint return SHA256 fingerprint of a cert

func HTTPClientWithEmpCA

func HTTPClientWithEmpCA(target_url, proxy string) (client *http.Client)

HTTPClientWithEmpCA is a http client with system CA pool with utls client hello randomization url: target URL, proxy: proxy URL

func IPIfaces

func IPIfaces() (ifaces []net.Interface)

IPIfaces returns a list of network interfaces

func IPLink() (links []netlink.Link)

IPLink get all interfaces

func IPNeigh

func IPNeigh() []string

IPNeigh works like `ip neigh`, dumps ARP cache

func IPa

func IPa() (ips []string)

IPa works like `ip addr`, you get a list of IP strings

func IPbroadcastAddr

func IPbroadcastAddr(ipMask IPWithMask) string

IPbroadcastAddr calculate broadcast address of an IP

func IPinCIDR

func IPinCIDR(port, cidr string) (ips []string)

IPinCIDR all IPs in a CIDR

func IPr

func IPr() (routes []string)

IPr works like `ip r`, covers both IPv4 and IPv6

func IsPortOpen

func IsPortOpen(host string, port string) bool

IsPortOpen is this TCP port open?

func IsProxyOK

func IsProxyOK(proxy, test_url string) bool

IsProxyOK test if the proxy works against the test URL

func IsTor

func IsTor(addr string) bool

IsTor is the C2 on Tor?

func KCPTunClient

func KCPTunClient(remote_kcp_addr, kcp_listen_port, password, salt string, ctx context.Context, cancel context.CancelFunc) error

main function for KCP tunneling using smux remote_kcp_addr: KCP server address (host:port) kcp_listen_port: KCP client listen port password: Runtime password salt: emp3r0r_def.MagicString

func KCPTunServer

func KCPTunServer(target, kcp_server_port, password, salt string, ctx context.Context, cancel context.CancelFunc) error

target: target address (host:port) kcp_server_port: KCP server listen port password: Runtime password salt: emp3r0r_def.MagicString

func LogError

func LogError(format string, a ...interface{})

LogError print log in red, and exit

func LogFatalError

func LogFatalError(format string, a ...interface{})

LogFatalError print log in red, and exit

func LogInfo

func LogInfo(format string, a ...interface{})

LogInfo print log in blue

func LogWarn

func LogWarn(format string, a ...interface{})

LogWarn print log in yellow

func MD5Sum

func MD5Sum(text string) string

MD5Sum calc md5 of a string

func NamesInCert

func NamesInCert(cert_file string) (names []string)

NamesInCert find domain names and IPs in server certificate

func NewUTLSRoundTripper

func NewUTLSRoundTripper(name string, cfg *utls.Config, proxyURL *url.URL) (http.RoundTripper, error)

func PKCS5Padding

func PKCS5Padding(ciphertext []byte, blockSize int) []byte

Go implementation of PKCS5Padding

func PKCS5Trimming

func PKCS5Trimming(encrypt []byte) []byte

func ParseCertPemFile

func ParseCertPemFile(cert_file string) (cert *x509.Certificate, err error)

ParseCertPemFile read from PEM file and return parsed cert

func ParseKeyPemFile

func ParseKeyPemFile(key_file string) (cert *ecdsa.PrivateKey, err error)

ParseKeyPemFile read from PEM file and return parsed cert

func ParsePem

func ParsePem(data []byte) (*x509.Certificate, error)

func ProxyHTTP

func ProxyHTTP(network, addr string, auth *proxy.Auth, forward proxy.Dialer) (*httpProxy, error)

func ProxyHTTPS

func ProxyHTTPS(network, addr string, auth *proxy.Auth, forward proxy.Dialer, cfg *utls.Config, clientHelloID *utls.ClientHelloID) (*httpProxy, error)

func SHA256Sum

func SHA256Sum(text string) string

SHA256Sum calc sha256 of a string

func SHA256SumFile

func SHA256SumFile(path string) string

SHA256SumFile calc sha256 of a file (of any size)

func SHA256SumRaw

func SHA256SumRaw(data []byte) string

func SSHPublicKey

func SSHPublicKey(privkey []byte) (pubkey ssh.PublicKey, err error)

SSHPublicKey return ssh.PublicKey from PEM encoded private key

func SSHRemoteFwdClient

func SSHRemoteFwdClient(ssh_serverAddr, password string,
	hostkey ssh.PublicKey,
	local_port int,
	conns *map[string]context.CancelFunc,
	ctx context.Context, cancel context.CancelFunc,
) (err error)

SSHRemoteFwdClient dial SSHRemoteFwdServer, forward local TCP port to remote server serverAddr format: 127.0.0.1:22 hostkey is the ssh server public key

func SSHRemoteFwdServer

func SSHRemoteFwdServer(port, password string, hostkey []byte) (err error)

SSHRemoteFwdServer start a ssh proxy server that forward to client side TCP port port: binding port on server side, ssh client will try authentication with this port password: ssh client will try authentication with this password. We will always use RuntimeConfig.ShadowsocksPassword

func SSHReverseProxyClient

func SSHReverseProxyClient(ssh_serverAddr string,
	password string,
	proxyPort int,
	reverseConns *map[string]context.CancelFunc,
	socks5proxy *socks5.Server,
	ctx context.Context, cancel context.CancelFunc,
) (err error)

SSHReverseProxyClient dial SSHProxyServer, start a reverse proxy serverAddr format: 127.0.0.1:22 FIXME: when using KCP, port number calculation is wrong

func ServeFileHTTP

func ServeFileHTTP(file_path, port string, ctx context.Context, cancel context.CancelFunc) (err error)

func SignECDSA

func SignECDSA(message []byte, privateKey *ecdsa.PrivateKey) ([]byte, error)

SignECDSA sign a message with ECDSA private key

func SignWithCAKey

func SignWithCAKey(data []byte) ([]byte, error)

SignWithCAKey signs the given data using the CA's private key

func StartSocks5Proxy

func StartSocks5Proxy(addr, doh string, proxyserver *socks5.Server) (err error)

StartSocks5Proxy sock5 proxy server on agent, listening on addr

func TCPFwd

func TCPFwd(addr, port string, ctx context.Context, cancel context.CancelFunc) (err error)

TCPFwd listen on a TCP port and forward to another TCP address addr: forward to this addr port: listen on this port

func TestConnectivity

func TestConnectivity(test_url, proxy string) bool

TestConnectivity does this machine has internet access,

func ValidateIP

func ValidateIP(ip string) bool

ValidateIP is this IP legit?

func ValidateIPPort

func ValidateIPPort(to string) bool

ValidateIPPort check if the host string looks like IP:Port

func VerifySignatureWithCA

func VerifySignatureWithCA(data []byte, signature []byte) (bool, error)

VerifySignatureWithCA verifies the given signature against the data using the CA's public key

func XOREncrypt

func XOREncrypt(key []byte, plaintext []byte) []byte

XOREncrypt

Types

type Config

type Config struct {
	LocalAddr    string `json:"localaddr"`   // Local listen address, e.g., ":12948"
	Listen       string `json:"listen"`      // kcp server listen address, eg: "IP:29900" for a single port, "IP:minport-maxport"
	Target       string `json:"target"`      // target server address, or path/to/unix_socket
	RemoteAddr   string `json:"remoteaddr"`  // KCP server address, e.g., "vps:29900", can be a single port or port range "IP:minport-maxport"
	Key          string `json:"key"`         // Pre-shared secret between client and server, e.g., "it's a secret"
	Crypt        string `json:"crypt"`       // Encryption method, e.g., aes, aes-128, aes-192, salsa20, blowfish, twofish, etc.
	Mode         string `json:"mode"`        // Performance profile, e.g., fast, fast2, fast3, normal, or manual
	Conn         int    `json:"conn"`        // Number of UDP connections to the server
	AutoExpire   int    `json:"autoexpire"`  // Auto expiration time (in seconds) for a single UDP connection, 0 disables auto-expire
	ScavengeTTL  int    `json:"scavengettl"` // Time (in seconds) an expired connection can remain active before scavenging
	MTU          int    `json:"mtu"`         // Maximum Transmission Unit size for UDP packets
	SndWnd       int    `json:"sndwnd"`      // Send window size (number of packets)
	RcvWnd       int    `json:"rcvwnd"`      // Receive window size (number of packets)
	DataShard    int    `json:"datashard"`   // Number of data shards for Reed-Solomon erasure coding
	ParityShard  int    `json:"parityshard"` // Number of parity shards for Reed-Solomon erasure coding
	DSCP         int    `json:"dscp"`        // DSCP value for quality of service (QoS) marking (6-bit)
	NoComp       bool   `json:"nocomp"`      // Disable compression if set to true
	AckNodelay   bool   `json:"acknodelay"`  // Flush ACK immediately when a packet is received (reduces latency)
	NoDelay      int    `json:"nodelay"`     // KCP 'NoDelay' mode configuration (latency vs throughput trade-off)
	Interval     int    `json:"interval"`    // KCP update interval in milliseconds
	Resend       int    `json:"resend"`      // KCP resend parameter, controls packet retransmission
	NoCongestion int    `json:"nc"`          // Disable KCP congestion control (1 = disable, 0 = enable)
	SockBuf      int    `json:"sockbuf"`     // Per-socket buffer size (in bytes), e.g., 4194304
	SmuxVer      int    `json:"smuxver"`     // Smux version, either 1 or 2
	SmuxBuf      int    `json:"smuxbuf"`     // Overall de-mux buffer size (in bytes), e.g., 4194304
	StreamBuf    int    `json:"streambuf"`   // Per-stream receive buffer size (in bytes) for Smux v2+, e.g., 2097152
	KeepAlive    int    `json:"keepalive"`   // NAT keep-alive interval in seconds
	Log          string `json:"log"`         // Path to the log file, default is empty (logs to stderr)
	SnmpLog      string `json:"snmplog"`     // Path to collect SNMP logs, follows Go time format e.g., "./snmp-20060102.log"
	SnmpPeriod   int    `json:"snmpperiod"`  // SNMP collection period in seconds
	Quiet        bool   `json:"quiet"`       // Suppress 'stream open/close' messages if set to true
	TCP          bool   `json:"tcp"`         // Emulate a TCP connection (Linux only)
	Pprof        bool   `json:"pprof"`       // Enable a profiling server on port :6060 if set to true
	QPP          bool   `json:"qpp"`         // Enable Quantum Permutation Pads (QPP) for added encryption security
	QPPCount     int    `json:"qpp-count"`   // Number of pads to use for QPP (must be a prime number)
	CloseWait    int    `json:"closewait"`   // Time (in seconds) to wait before tearing down a connection
}

Config holds the client configuration for KCP tunneling.

func NewConfig

func NewConfig(remote_addr, target, port, password, salt string) *Config

remote_addr: KCP server address (host) target: forward to this address, leave empty for client port: KCP listen port on client, server listen port on server

type IPWithMask

type IPWithMask struct {
	IP   net.IP
	Mask net.IPMask
}

IPWithMask net.IP and net.IPMask

func IPaddr

func IPaddr() (ips []IPWithMask)

IPaddr returns a list of local IP addresses

type UTLSDialer

type UTLSDialer struct {
	// contains filtered or unexported fields
}

func (*UTLSDialer) Dial

func (dialer *UTLSDialer) Dial(network, addr string) (net.Conn, error)

type UTLSRoundTripper

type UTLSRoundTripper struct {
	sync.Mutex
	// contains filtered or unexported fields
}

A http.RoundTripper that uses uTLS (with a specified Client Hello ID) to make TLS connections.

Can only be reused among servers which negotiate the same ALPN.

func (*UTLSRoundTripper) RoundTrip

func (rt *UTLSRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL