Introduction to JA3 Fingerprint and how to impersonate it using golang.
Disclaimer: This article is for educational purpose only.
JA3 is a fingerprinting mechanism used to uniquely identify clients based on their TLS clientHello packets. So whenever you access a website/service which uses https, your browser/client has to complete a TLS Handshake, this is a multistep process when the client and the server authenticate each other and negotiates security keys to be used for further data transmission.
JA3 mechanism uses the client Hello packet to create a fingerprint which can be used to identify the operating system and the client from which the request was made. This comes in handy to identify various commonly used malwares and avoid traffic from them to protect your website.
Head over to https://ja3er.com/, You can find the hash created from the request sent by your browser, and click on search for ja3 hash to find your client and operating system. This is mine
The site also provides a rest api to find your ja3 fingerprint and infromation about your client and operating system. Lets hit their API via curl see what the output is.
curl -X GET 'https://ja3er.com/json'
This endpoint gives the ja3 and the ja3_hash (fingerprint).
Get the ja3_hash
from the previous response and search for it.
curl -X GET 'https://ja3er.com/search/3faa4ad39f690c4ef1c3160caa375465'
Don't confuse this with the User-Agent
which is sent in the request headers. A client can send anything as it is under the control on the client. Even if one sends a different User-Agent
the source of the request can be found using the JA3
fingerprint.
Have you ever tried to access google using tor browser and been blocked by a screen which says their systems have found unusual traffic, It it done by a mix of fingerprint filtering and by matching IP with list of public tor exit relays. Similar methods are used by few govt sites also.
Tor Google
Tor JA3 Fingerprint
There are also other fingerprinting techniques other than ja3 and it is not public which fingerprinting method is used by Google. They might even have a proprietary technique 🤷♂️.
So basically if the fingerprint is created using the TLS handshake Client Hello packet then we can create a
packet similar to a browser when programmatically accessing a website. Yes it is possible with this golang library JA3Transport. It implements http.Client
and http.Transport
interface, allowing us to craft the TLS handshake packets and impersonate someother client. To understand more about the library and ja3 computation logic check the official medium post by the creators of the library. Link
Let's see the ja3Transport client vs standard golang http client in action.
Using the go http client we hit the same ja3er.com and fetch the results.Check the code here
From the response it is clear that the fingerprint matches highly with Go-http-client/1.1
.
Now lets use the JA3Transport Http Client and do the same.
The code changes required is very simple.
Create a http client with the ja3 string or predefined browser and use it as your http client.
httpClient,err := ja3transport.New(ja3transport.SafariAuto)
if err != nil{
fmt.Println(err)
panic(err)
}
From the response it is clear the fingerprint has majority of the matches with Mozilla and Safari.
Hurray 🎉, we successfully impersonated some other client.
One can also use the ja3transport.NewWithString method to impersonate a particular client.
As mentioned earlier the ja3transport
library also implements the http.Transport
interface which can be used to create a proxy server which impersonates some other client. This comes in handy if you have to impersonate traffic from another application or scripts from another programming language.
References: