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
- Variables
- func AESDecrypt(key []byte, cryptoText string) string
- func AESDecryptRaw(key, ciphertext []byte) []byte
- func AESEncrypt(key []byte, text string) string
- func AESEncryptRaw(key, plaintext []byte) []byte
- func Base64URLDecode(text string) []byte
- func Base64URLEncode(text string) string
- func EmpHTTPClient(c2_addr, proxyServer string) *http.Client
- func FindIPToUse(target string) string
- func FwdToDport(ctx context.Context, cancel context.CancelFunc, to, sessionID, protocol string, ...)
- func GenAESKey(seed string) []byte
- func GenCerts(hosts []string, outname string, isCA bool) (err error)
- func GenerateSSHKeyPair() (privateKey, publicKey []byte, err error)
- func GetFingerprint(cert_file string) string
- func HTTPClientWithEmpCA(target_url, proxy string) (client *http.Client)
- func HasInternetAccess(test_url string) bool
- func IPIfaces() (ifaces []net.Interface)
- func IPLink() (links []netlink.Link)
- func IPNeigh() []string
- func IPa() (ips []string)
- func IPbroadcastAddr(ipMask IPWithMask) string
- func IPinCIDR(port, cidr string) (ips []string)
- func IPr() (routes []string)
- func IsPortOpen(host string, port string) bool
- func IsProxyOK(proxy, test_url string) bool
- func IsTor(addr string) bool
- func LogError(format string, a ...interface{})
- func LogFatalError(format string, a ...interface{})
- func LogInfo(format string, a ...interface{})
- func LogWarn(format string, a ...interface{})
- func MD5Sum(text string) string
- func NamesInCert(cert_file string) (names []string)
- func NewUTLSRoundTripper(name string, cfg *utls.Config, proxyURL *url.URL) (http.RoundTripper, error)
- func PKCS5Padding(ciphertext []byte, blockSize int) []byte
- func PKCS5Trimming(encrypt []byte) []byte
- func ParseCertPemFile(cert_file string) (cert *x509.Certificate, err error)
- func ParsePem(data []byte) (*x509.Certificate, error)
- func ProxyHTTP(network, addr string, auth *proxy.Auth, forward proxy.Dialer) (*httpProxy, error)
- func ProxyHTTPS(network, addr string, auth *proxy.Auth, forward proxy.Dialer, cfg *utls.Config, ...) (*httpProxy, error)
- func SHA256Sum(text string) string
- func SHA256SumFile(path string) string
- func SHA256SumRaw(data []byte) string
- func SSHPublicKey(privkey []byte) (pubkey ssh.PublicKey, err error)
- func SSHRemoteFwdClient(ssh_serverAddr, password string, hostkey ssh.PublicKey, local_port int, ...) (err error)
- func SSHRemoteFwdServer(port, password string, hostkey []byte) (err error)
- func SSHReverseProxyClient(ssh_serverAddr, password string, reverseConns *map[string]context.CancelFunc, ...) (err error)
- func ServeFileHTTP(file_path, port string, ctx context.Context, cancel context.CancelFunc) (err error)
- func StartSocks5Proxy(addr, doh string, proxyserver *socks5.Server) (err error)
- func TCPFwd(addr, port string, ctx context.Context, cancel context.CancelFunc) (err error)
- func ValidateIP(ip string) bool
- func ValidateIPPort(to string) bool
- func XOREncrypt(key []byte, plaintext []byte) []byte
- type IPWithMask
- type UTLSDialer
- type UTLSRoundTripper
Constants ¶
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/" )
const ( MicrosoftNCSIURL = "http://www.msftncsi.com/ncsi.txt" MicrosoftNCSIResp = "Microsoft NCSI" )
Variables ¶
var ( Stager_HTTP_Server http.Server Stager_Ctx context.Context Stager_Cancel context.CancelFunc )
var ( // CACrt for TLS server cert signing CACrt = []byte(` [emp3r0r_ca] `) )
Functions ¶
func AESDecrypt ¶
AESDecrypt from base64 to decrypted string
func AESEncrypt ¶
AESEncrypt string to base64 crypto using AES
func Base64URLDecode ¶
Base64URLDecode decode a base64 encoded string (to []byte)
func Base64URLEncode ¶
Base64URLEncode encode a string with base64
func EmpHTTPClient ¶
EmpHTTPClient add our CA to trusted CAs, while keeps TLS InsecureVerify on
func FindIPToUse ¶
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 ¶
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
func GenerateSSHKeyPair ¶
Generate a new key pair for use with openssh
func GetFingerprint ¶
GetFingerprint return SHA256 fingerprint of a cert
func HTTPClientWithEmpCA ¶
HTTPClientWithEmpCA is a http client with system CA pool with utls client hello randomization url: target URL, proxy: proxy URL
func HasInternetAccess ¶
HasInternetAccess does this machine has internet access, does NOT use any proxies
func IPbroadcastAddr ¶
func IPbroadcastAddr(ipMask IPWithMask) string
IPbroadcastAddr calculate broadcast address of an IP
func LogFatalError ¶
func LogFatalError(format string, a ...interface{})
LogFatalError print log in red, and exit
func NamesInCert ¶
NamesInCert find domain names and IPs in server certificate
func NewUTLSRoundTripper ¶
func PKCS5Padding ¶
Go implementation of PKCS5Padding
func PKCS5Trimming ¶
func ParseCertPemFile ¶
func ParseCertPemFile(cert_file string) (cert *x509.Certificate, err error)
ParseCertPemFile read from PEM file and return parsed cert
func ProxyHTTPS ¶
func SHA256SumFile ¶
SHA256SumFile calc sha256 of a file (of any size)
func SHA256SumRaw ¶
func SSHPublicKey ¶
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 ¶
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, password string, 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
func ServeFileHTTP ¶
func StartSocks5Proxy ¶
StartSocks5Proxy sock5 proxy server on agent, listening on addr
func TCPFwd ¶
TCPFwd listen on a TCP port and forward to another TCP address addr: forward to this addr port: listen on this port
func ValidateIPPort ¶
ValidateIPPort check if the host string looks like IP:Port
Types ¶
type IPWithMask ¶
IPWithMask net.IP and net.IPMask
type UTLSDialer ¶
type UTLSDialer struct {
// contains filtered or unexported fields
}
type UTLSRoundTripper ¶
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.