Blog :: General :: Uncategorized

Inspecting encrypted traffic with JA3 and JA3S fingerprinting


Two years ago, I wrote a blog about tracking malware in encrypted traffic. The overall theme of that blog was that encryption has become much more of a standard. 2017 in particular was a milestone year in which the volume of encrypted traffic officially surpassed unencrypted web traffic. It’s safe to say that in three years, that balance has shifted even more in favor of SSL/TLS encryption. In this blog, I’ll explore the concept of JA3 and JA3S fingerprinting and the benefits they introduce when it comes to inspecting encrypted traffic.

What are JA3 and JA3S fingerprints?

At a very high level, JA3 and JA3S fingerprinting are ways of generating an MD5 hash for a particular piece of software’s traffic. The MD5 hash produces a nice, light, and easy-to-consume 32 character fingerprint. The fingerprint itself is based on the unique way a client and server establish a secure session via the TCP handshake.

Inspecting encrypted traffic is by no means a new concept. Today there are plenty of products and appliances that can essentially man-in-the-middle your encrypted traffic (HTTPS most commonly). However, decrypting,  inspecting,  and re-encrypting traffic on the wire is incredibly process-intensive and can quickly create a bottleneck in the network. This, to me, gives way to the real clever nature of JA3 fingerprinting – let’s take a look under the hood!

JA3 fingerprinting relies heavily on the fact that TLS negotiations are transmitted in clear text. This means that without any decryption, we can associate encrypted traffic with a particular piece of software at a high degree of certainty. Following the 3-way handshake, a client will send a Client Hello packet. Different applications use different packages and programmatic methods to generate Client Hello packets. Therefore, this packet will always be the same from a given application. The JA3 method gathers the decimal values of the bytes for the following fields in the Client Hello packet:

  • Version
  • Accepted ciphers
  • List of extensions
  • Elliptic curves
  • Elliptic curve formats

These values are then concatenated together, delimited by a comma. In the event that there are no TLS extensions in the Client Hello, the fields are left empty:



Example (missing TLS Extensions):


These strings are then passed through a function to create an MD5 hash, examples below:

769,47–53–5–10–49161–49162–49171–49172–50–56–19–4,0–10–11,23–24–25,0 -> ada70206e40642a3e4461f35503241d5
769,4–5–10–9–100–98–3–6–19–18–99,,, -> de350869b8c85de67a350c8d186f11e6

At this point, someone must be asking “Well if the JA3 fingerprint is being generated by the Client Hello packet, can’t we expect to see completely different applications resulting in the same JA3 fingerprint?”

The answer: absolutely.

So if that’s true, how can we enhance this fingerprinting concept to provide a higher level of certainty to our threat hunters and traffic analytics teams? That’s where JA3S comes in!

Where JA3 fingerprints are generated based on the Client Hello packet, the JA3S fingerprint is generated based on the Server Hello packet. We all know that applications use common libraries or reusable OS sockets like Python or Windows Socket. Widely used pen testing software (Metasploit’s Meterpreter as an example) use a Windows socket to initiate a TLS connection. The JA3 fingerprint will look identical to any other application using a Windows socket for establishing a TLS connection.

But what the clever folks at Salesforce learned was that while the Client Hello packet resulted in identical JA3 hashes, the way in which the C2 server responds is unique in comparison to how normal servers on the internet would respond to this socket.

Basically, what this means is that by only leveraging the JA3 fingerprint, we can expect to see a steady amount of traffic (a majority likely being legitimate) matching that MD5 hash. By using a logical connective and searching for both the JA3 fingerprint and the JA3S fingerprint of how a malicious server would respond we can very quickly see more of a beaconing behavior. By combining JA3 and JA3S fingerprints, we create a higher-fidelity fingerprint of the cryptographic negotiation between client and server.

Now that we have a conceptual foundation on JA3(S) fingerprinting, I’m sure you’re wondering how you can start taking advantage of this functionality today! If you’re not already leveraging of Plixer’s FlowPro appliances for enhanced traffic visibility, combined with Scrutinizer appliances for threat hunting and visibility… JA3(S) fingerprinting is a fantastic reason to download an evaluation today!

JA3 fingerprinting alarm
JA3 fingerprinting alarm policy

If you’re interested in this making the most of this concept and want to learn more, I highly recommend watching Lee Brotherston’s Derbycon 2015 as well as reviewing the code base (yes indeed, it’s made open source).

If you would like to learn more about our FlowPro and Scrutinizer appliances, don’t hesitate to reach out to us.