mic.git


mic

~ proxy for JA4-TLS fingerprinting evasion
git clone https://github.com/djnnvx/mic.git
log | files | refs | archive | README | LICENSE

commit 8327c17435a06f5b34a9ad379e7aa7a7227edb39
parent bb5fa11ac3c670907015b6560e33aba728eaf81c
Author: djnn <[email protected]>
Date: Wed, 20 Aug 2025 21:47:16 +0900

fix: compilation errors

Diffstat:
Mcmd/root.go | 16++++++++++++----
Mcmd/types.go | 8++------
Mproxy/https.go | 22+++-------------------
Mproxy/proxy.go | 13++++++-------

4 files changed, 23 insertions(+), 36 deletions(-)

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)
 			}
 		}()