Skip to content

HackingLZ/ja4_proxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JA4 Proxy

A single Go binary that makes outgoing HTTPS connections look exactly like OneDrive.exe (or other Windows apps) at the TLS layer. Every part of the Client Hello -- cipher suites, extensions, signature algorithms, extension order -- matches a real Windows 11 SChannel TLS 1.3 handshake.

Optionally chain through TREVORproxy for IPv6 source address rotation from a /64 subnet.

Architecture

                          single Go binary
                     ┌──────────────────────┐
Client ──HTTP──▶     │  ja4proxy              │ ──uTLS──▶ Target
  curl / Python      │  profiles embedded    │           (sees OneDrive JA4)
                     └──────────┬───────────┘
                                │ optional
                                ▼
                          TREVORproxy SOCKS5
                          (IPv6 /64 rotation)
  • ja4proxy is a ~12 MB static binary with 6 YAML TLS profiles compiled in. No Python, no runtime deps.
  • TREVORproxy is only needed for IPv6 source rotation. Without it, the proxy connects directly.

Quick Start

# Build
go build -o ja4proxy

# See all profiles
./ja4proxy -list

# Run (default profile: onedrive)
./ja4proxy

# Test via X-Target-URL
curl -H "X-Target-URL: https://tls.browserleaks.com/json" http://127.0.0.1:8443/

# Test via CONNECT
curl -x http://127.0.0.1:8443 https://tls.browserleaks.com/json

# Verify fingerprint
./ja4proxy -profile onedrive -verify

Profiles

All profiles are embedded YAML files in profiles/. The -profile flag accepts any name or alias.

Name Alias JA4 Description
schannel_tls13_win11 onedrive t13d2013h2_2b729b4bf6f3_e24568c0d440 OneDrive.exe Windows 11 SChannel TLS 1.3
schannel_tls12_telemetry onedrive-telemetry t12d180800_4b22cbed5bed_7af1ed941c26 Watson telemetry TLS 1.2
schannel_tls12_pss schannel_tls12 t12d180700_4b22cbed5bed_2dae41c691ec .NET Framework / SChannel TLS 1.2 with RSA-PSS
edge_legacy_schannel edge_legacy t12d1810h2_4b22cbed5bed_27793441e138 Legacy Edge (EdgeHTML) SChannel TLS 1.2
edge_chromium t13d1516h2_8daaf6152771_e5627efa2ab1 Edge/Chrome (BoringSSL)
winhttp_tls12 winhttp t12d210800_76e208dd3e22_16bbda4055b2 WinHTTP native Win32 TLS 1.2

CLI

./ja4proxy [flags]

  -addr string        Listen address (default "127.0.0.1:8443")
  -profile string     Profile name or alias (default "onedrive")
  -profiles-dir path  Load profiles from directory instead of embedded
  -socks string       SOCKS5 upstream (e.g. "127.0.0.1:1080")
  -list               List profiles and exit
  -verify             Hit tls.peet.ws and compare actual vs expected JA4

Deployment with TREVORproxy

For production use with IPv6 rotation on a Linux server.

What you need

  • Linux server with a routed IPv6 /64 subnet
  • Go 1.21+ on your build machine
  • TREVORproxy on the server (or any SOCKS5 proxy on :1080)

Build and upload

GOOS=linux GOARCH=amd64 go build -o ja4proxy_linux_amd64
scp ja4proxy_linux_amd64 root@your-server:/srv/ja4proxy/

Run

Terminal 1 -- start TREVORproxy:

trevorproxy subnet -s 2001:db8:abcd:1234::/64 -i eth0

Terminal 2 -- start ja4proxy chained through SOCKS:

/srv/ja4proxy/ja4proxy_linux_amd64 \
  -addr 0.0.0.0:8443 \
  -socks 127.0.0.1:1080 \
  -profile onedrive

Verify

# Check JA4 fingerprint
curl -s -H "X-Target-URL: https://tls.browserleaks.com/json" http://127.0.0.1:8443/ \
  | python3 -c "import sys,json; print('JA4:', json.load(sys.stdin)['ja4'])"
# Expected: t13d2013h2_2b729b4bf6f3_e24568c0d440

# Check IPv6 rotation
for i in 1 2 3; do
  curl -s -H "X-Target-URL: https://api64.ipify.org" -H "Connection: close" http://127.0.0.1:8443/
  echo
done
# Expected: different IPv6 addresses from your /64

JA4 Fingerprint Check Services

Service URL Returns
tls.browserleaks.com https://tls.browserleaks.com/json ja4, ja4_r, ja4_o, ja3
tls.peet.ws https://tls.peet.ws/api/all ja4, ja4_r, ja3

Adding Custom Profiles

Create a YAML file in profiles/ and rebuild:

name: my_profile
aliases: [myalias]
description: "My custom TLS profile"
ja4: "t13d..."

tls_min_version: "1.2"
tls_max_version: "1.3"

cipher_suites:
  - 0x1302  # TLS_AES_256_GCM_SHA384
  - 0x1301  # TLS_AES_128_GCM_SHA256

supported_groups: [x25519, p256, p384]
ec_point_formats: [uncompressed]

signature_algorithms:
  - 0x0804  # rsa_pss_rsae_sha256

alpn: [h2, http/1.1]

# Extension order matters for JA4
extensions:
  - sni
  - status_request
  - supported_groups
  - ec_point_formats
  - signature_algorithms
  - alpn
  - extended_master_secret
  - session_ticket
  - supported_versions
  - psk_key_exchange_modes
  - key_share
  - renegotiation_info

Or load at runtime without rebuilding: ./ja4proxy -profiles-dir /path/to/profiles/

Troubleshooting

JA4 doesn't match -- Make sure traffic goes through the Go proxy, not directly through SOCKS. Verify with ./ja4proxy -verify or curl through the proxy to a fingerprint echo service.

IPv6 same address every time -- HTTP keep-alive reuses connections. Add -H "Connection: close" to force new TCP per request.

SOCKS connection refused -- Check TREVORproxy is running: ss -tlnp | grep 1080

Permission denied on AnyIP route -- TREVORproxy needs root for ip route add local.

Credits

Releases

No releases published

Packages

No packages published

Languages