ja3transport

repository·master·Indexed 18 days ago

https://github.com/cucyber/ja3transport

A Go library for mocking and impersonating JA3 TLS fingerprints. It allows developers to control ClientHello packet parameters to test security tool detection or bypass TLS fingerprinting by mimicking specific browsers or tools. The library provides a JA3Client for HTTP requests, predefined Browser presets for Chrome and Safari, and utilities to create custom http.Transport configurations using JA3 strings and uTLS.

Tokens
1.8K
Snippets
7
Records
9
Agent score
64%

What's inside ja3transport

  1. Overview of JA3Transport

    master
    JA3Transport is a Go library designed to facilitate the mocking of JA3 signatures. JA3 is a fingerprinting method for TLS clients that analyzes options within the TLS ClientHello packet (such as SSL version and available client extensions). Because the client controls the ClientHello packet, JA3 provides a more reliable detection mechanism for malicious traffic than HTTP User-Agent headers. This library allows developers to easily impersonate specific JA3 fingerprints for testing and research purposes.
  2. Use JA3Client for HTTP requests

    master

    The JA3Client provides standard HTTP methods that automatically handle JA3 fingerprinting and optional User-Agent injection. If a User-Agent is defined in the Browser field of the client, it will be automatically set in the request headers if the request doesn't already have one.

    Supported methods:

    • Do(req *http.Request): Sends a custom request.
    • Get(targetURL string): Performs a GET request.
    • Post(url, contentType string, body io.Reader): Performs a POST request with a specific content type.
    • Head(url string): Performs a HEAD request.
    • PostForm(url string, data url.Values): Performs a POST request with URL-encoded form data.
    // GET request
    resp, err := client.Get("https://example.com")
    
    // POST request with JSON body
    resp, err := client.Post("https://example.com", "application/json", strings.NewReader(`{"key":"value"}`))
    
    // POST Form request
    data := url.Values{}
    data.Set("username", "admin")
    resp, err := client.PostForm("https://example.com/login", data)
    
    // Custom Request
    req, _ := http.NewRequest("GET", "https://example.com", nil)
    resp, err := client.Do(req)
  3. Create an HTTP transport with custom uTLS configuration

    master

    If you need to provide specific TLS settings (like custom certificates or specific server names) alongside the JA3 impersonation, use NewTransportWithConfig. This allows you to pass a *tls.Config from the github.com/refraction-networking/utls package.

    import (
        "github.com/refraction-networking/utls"
        "github.com/cucyber/cucyber/ja3transport"
    )
    
    // Create a custom uTLS config
    utlsConfig := &tls.Config{
        // Add custom TLS settings here
    }
    
    transport, err := ja3transport.NewTransportWithConfig("771,4865-4866,0-5-13-16,23-24,0", utlsConfig)
  4. Initialize a JA3Client

    master

    A JA3Client is used to perform HTTP requests while mimicking specific TLS fingerprints (JA3 signatures). It embeds a standard *http.Client and includes configuration for TLS and browser-like properties.

    You can initialize it in two ways:

    1. Using a Browser struct: Use New(b Browser) to create a client that inherits both a JA3 string and other browser metadata (like UserAgent).
    2. Using a raw JA3 string: Use NewWithString(ja3 string) if you only need to specify the TLS fingerprint.
    // Option 1: Using a Browser struct
    browser := ja3transport.Browser{JA3: "your_ja3_string", UserAgent: "your_user_agent"}
    client, err := ja3transport.New(browser)
    
    // Option 2: Using only a JA3 string
    client, err := ja3transport.NewWithString("your_ja3_string")
  5. Create an HTTP transport with JA3 impersonation

    master

    Use NewTransport to create a standard *http.Transport that mocks a specific JA3 signature. This is useful for bypassing TLS fingerprinting by making your Go HTTP client appear as a different client (e.g., a specific browser or tool).

    The ja3 string must follow the standard JA3 format: version,ciphers,extensions,curves,point_formats.

    Example JA3 components:

    • version: TLS version (e.g., 771 for TLS 1.2).
    • ciphers: Hyphen-separated list of cipher suite IDs.
    • extensions: Hyphen-separated list of extension IDs.
    • curves: Hyphen-separated list of curve IDs (can be empty).
    • point_formats: Hyphen-separated list of point format IDs (can be empty).
    transport, err := ja3transport.NewTransport("771,4865-4866,0-5-13-16,23-24,0")
    if err != nil {
        log.Fatal(err)
    }
    
    client := &http.Client{
        Transport: transport,
    }
    
    resp, err := client.Get("https://example.com")
  6. Use predefined Browser presets

    master

    The package provides several predefined Browser variables that mock common browser identities. You can use these directly to quickly apply a specific JA3 fingerprint and User-Agent combination to your transport configuration.

    Available presets:

    • ChromeAuto: Mocks Chrome 78.
    • SafariAuto: Mocks Safari 604.1.
    import "github.com/cucyber/cucyber/ja3transport"
    
    // Example usage of presets
    chrome := ja3transport.ChromeAuto
    safari := ja3transport.SafariAuto
    
    fmt.Println(chrome.JA3)
    fmt.Println(safari.UserAgent)
  7. JA3Client struct definition

    master

    The JA3Client struct is the primary entry point for the library. It wraps a standard *http.Client to provide compatibility with existing Go HTTP code while adding TLS customization.

    Fields:

    • *http.Client: The underlying standard library HTTP client.
    • Config *tls.Config: A pointer to a utls.Config for advanced TLS settings.
    • Browser Browser: A struct containing the JA3 fingerprint and UserAgent to be used during requests.
  8. Handle unsupported JA3 extensions

    master

    If the provided JA3 string contains an extension ID that is not recognized by the ja3transport library, the functions will return an ErrExtensionNotExist error. This error type implements the error interface and includes the name of the missing extension.

    type ErrExtensionNotExist string
    
    // Error returns the error message: "Extension does not exist: <extension_id>\n"
    func (e ErrExtensionNotExist) Error() string
  9. Use the Browser type for JA3 and User-Agent pairs

    master

    The Browser type is a data structure used to represent a pair of a JA3 fingerprint and a corresponding User-Agent string. This is useful for mocking specific browser identities in transport-layer fingerprinting scenarios.

    type Browser struct {
    	JA3       string
    	UserAgent string
    }