diff --git a/cmd/root.go b/cmd/root.go
@@ -2,8 +2,10 @@ package cmd
import (
"fmt"
+ "log"
"os"
+ "github.com/djnnvx/mic/proxy"
"github.com/spf13/cobra"
)
@@ -45,17 +47,23 @@ func getParser(opts *MicCliOptions) *cobra.Command {
var rootCmd = &cobra.Command{
Use: "mic",
Short: "modular proxy for network-fingerprinting evasion",
- Long: "mic (mina-is-cute) is a proxy supporting HTTP connect & SOCKS5 to evade networking fingerprinting detection",
+ Long: "mic (mina-is-cute) is a HTTPS proxy to evade networking fingerprinting detection",
Run: func(cmd *cobra.Command, args []string) {
- print("Yaaay...:)")
+ log.Printf("[+] only HTTPS supported for now, registering default handler.")
+ p := &proxy.Proxy{
+ ListenAddr: opts.Addr,
+ ForwardTo: opts.ForwardTo,
+ }
+
+ p.RegisterHandler(proxy.HttpsHandler)
+ p.Run()
},
}
defaults := GetDefaultOptions()
- rootCmd.Flags().StringVarP(&opts.Addr, "addr", "a", defaults.Addr, "address to listen to")
- rootCmd.Flags().IntVarP(&opts.Port, "port", "p", defaults.Port, "port to listen to")
+ rootCmd.Flags().StringVarP(&opts.Addr, "addr", "a", defaults.Addr, "address to listen to (Golang notation)")
rootCmd.Flags().IntVarP(&opts.ForwardTo, "forward-to", "t", defaults.ForwardTo, "local port to forward to")
rootCmd.Flags().BoolVarP(&opts.Verbose, "verbose", "v", defaults.Verbose, "enable verbose mode")
diff --git a/cmd/types.go b/cmd/types.go
@@ -2,10 +2,7 @@ package cmd
type MicCliOptions struct {
- /// Port: port to listen to
- Port int
-
- /// Addr: address to listen to
+ /// Addr: address to listen to (Golang notation)
Addr string
/// ForwardTo: local port to forward call to
@@ -17,8 +14,7 @@ type MicCliOptions struct {
func GetDefaultOptions() MicCliOptions {
opts := MicCliOptions{
- Port: 8080,
- Addr: "127.0.0.1",
+ Addr: ":8080",
ForwardTo: 1337,
Verbose: false,
}
diff --git a/proxy/https.go b/proxy/https.go
@@ -5,7 +5,6 @@ import (
"fmt"
"io"
"log"
- "math/rand"
"net"
"net/http"
"strings"
@@ -14,17 +13,9 @@ import (
utls "github.com/refraction-networking/utls"
)
-func httpsHandler(clientConn net.Conn, p *Proxy) {
+func HttpsHandler(clientConn net.Conn, p *Proxy) {
defer clientConn.Close()
- // List of different browser fingerprints to cycle through.
- var helloIDs = []utls.HelloID{
- utls.HelloChrome_116,
- utls.HelloFirefox_105,
- utls.HelloSafari_16_0,
- utls.HelloEdge_106,
- }
-
// Read the first line of the request to check for the CONNECT method.
reader := bufio.NewReader(clientConn)
req, err := http.ReadRequest(reader)
@@ -40,15 +31,13 @@ func httpsHandler(clientConn net.Conn, p *Proxy) {
}
// The Host field contains the destination host and port.
+ // If no port is specified by the client, use the `ForwardTo` port from our Proxy struct.
host := req.URL.Host
if !strings.Contains(host, ":") {
- // If no port is specified by the client, use the `ForwardTo` port from our Proxy struct.
host = fmt.Sprintf("%s:%d", host, p.ForwardTo)
}
log.Printf("Connecting to target: %s", host)
-
- // Establish a TCP connection to the target server.
targetConn, err := net.Dial("tcp", host)
if err != nil {
log.Printf("Failed to dial target %s: %v", host, err)
@@ -56,15 +45,11 @@ func httpsHandler(clientConn net.Conn, p *Proxy) {
}
defer targetConn.Close()
- randomIndex := rand.Intn(len(helloIDs))
- randomHelloID := helloIDs[randomIndex]
- log.Printf("Using uTLS fingerprint: %s", randomHelloID.String())
-
// Create a uTLS client with the randomly selected fingerprint & perform handshake
utlsConfig := &utls.Config{
ServerName: strings.Split(host, ":")[0],
}
- uclient := utls.UClient(targetConn, utlsConfig, randomHelloID)
+ uclient := utls.UClient(targetConn, utlsConfig, utls.HelloRandomized)
if err := uclient.Handshake(); err != nil {
log.Printf("uTLS handshake failed with %s: %v", host, err)
@@ -85,7 +70,6 @@ func httpsHandler(clientConn net.Conn, p *Proxy) {
}
}()
- // Pipe data from the target server back to the client.
go func() {
defer wg.Done()
_, err := io.Copy(clientConn, uclient)
diff --git a/proxy/proxy.go b/proxy/proxy.go
@@ -8,17 +8,16 @@ import (
type Proxy struct {
ListenAddr string
ForwardTo int
+
+ handlers []Handler
}
// function is a function that processes an incoming client connection
type Handler func(conn net.Conn, p *Proxy)
-// registry for all protocol handlers
-var handlers []Handler
-
// adds a handler to the orchestrator
-func RegisterHandler(h Handler) {
- handlers = append(handlers, h)
+func (p *Proxy) RegisterHandler(h Handler) {
+ p.handlers = append(p.handlers, h)
}
// Run starts the proxy server and orchestrates all protocol handlers
@@ -30,7 +29,6 @@ func (p *Proxy) Run() error {
defer ln.Close()
log.Printf("[+] Starting proxy on %s, forwarding to port %d", p.ListenAddr, p.ForwardTo)
-
for {
c, err := ln.Accept()
if err != nil {
@@ -40,8 +38,9 @@ func (p *Proxy) Run() error {
conn := c
go func() {
- for _, h := range handlers {
+ for _, h := range p.handlers {
// Each handler processes the incoming connection.
+ // It will get discarded by a handler if it doesn't support it.
h(conn, p)
}
}()
| | | |