Threat Simulation – Client Signatures (TLS Signature)


This article is number 8 of 8 in a series on testing Threat Hunting software to make sure that it’s configured correctly and working successfully. If you’ve not already read the “Threat Simulation Overview and Setup” article, start there and return here to test whether your Threat hunting platform can detect rare TLS signatures.

This blog will make far more sense if you’ve already worked through “Threat simulation – client signatures (User Agent)


What Traffic Are We Trying to Find?

First, a recap of checking the User Agent. When the client software on your network is connecting to an HTTP (web) server, the browser sends a “User-Agent” field with the request; we can look at all the User Agents over a 24 hour period and show the uncommon ones in a report. Here’s an example of a User-Agent string:

“Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0”

It’s arguably a little cryptic, but at least one could read it and make an educated guess that one of the users is running Firefox on Windows 10.

Unfortunately, when one connects to an HTTPS (encrypted web) server, we no longer get to see that text fly by on the network. It’s still transmitted by the client and it’s still received by the server, to be sure, but the packets one sees on the network are all encrypted.

Let’s back up a second. The actual string used is nice to see and it does give us a first pass on what type of software is being used, but it’s actually not the most important part. What we really care about is rarity: which client signatures are really rare? As we talked about in the “Client signatures/User Agent” blog, the rare ones are more likely to be malicious or unwanted, and the common ones are more likely to be benign.

So how do we look for some kind of signature in HTTPS connections and rank them according to rarity? To do this we’re going to fall back on the TLS/SSL connection itself. Behind the scenes, the client and server negotiate what kind of encrypted conversation they want to have. Each declares what encryption types and key sizes they support; by the time they’re done they’ll find a strong encryption type they both support for actually transferring data.*

A number of Threat Hunting platforms use the “ja3” extension for Zeek to ingest this conversation and spit out a fingerprint; a random-looking 32 character string like “8f41a697eff27e008f969cf7b5ba4117”. There’s no human meaning to these strings other than this:

identical TLS negotiations will give identical fingerprints, and different TLS negotiations will give different fingerprints. By counting up the number of times we see a particular fingerprint, we can now approximate how common or rare a TLS negotiation is.

*Phew*! 🙂

*Wikipedia has a good overview of the gory details Here.


What Tools Are Needed

We’ll use some of the same tools we used in the Client Signatures (User Agent) blog – “curl” on the Internal system, and a web server on the External system.


What to Set up on the External System

Because we need to hold a TLS conversation between the Internal and External servers, the External web server will need to have a certificate installed. Since we installed a self-signed certificate in the “Threat simulation – certificate issues” blog, we’ll simply leave this in place.


What to Set up on the Internal System

Here we’re going to tell the TLS client (curl) to be really strict and only allow one type of encryption. This has two possibilities: if the server doesn’t speak the offered encryption type, the connection won’t work and we won’t be able to download anything (in which case we’ll pick a different one and try again). If the server does speak it, we’ll get our web page.

The side effect is that we’re playing with the TLS negotiation process so our Threat Hunting platform should be able to recognize this and report this as a very rare fingerprint. Because we’re depending on rarity you shouldn’t run the commands below too many times. 🙂

This page has a list of the common encryption types. Pick one from the TLS v1.2 cipher suites section; these will be strong enough that most web servers should consider them usable, while not being so new that the server hasn’t heard of them yet. In the example below I grabbed “ECDHE-RSA-AES128-SHA256”.

First, make sure you can grab the home page of the server at all with:

curl --trace-ascii /tmp/unrestricted-trace.out -s https://Ext4 | head -1 | less

This should return the first line of html. Now, let’s re-request that page, but curl will declare it will only use one type of encryption:

curl --trace-ascii /tmp/rsa-trace.out --ciphers ECDHE-RSA-AES128-SHA256 -s https://Ext4 | head -1 | less

If you’re interested in the behind-the-scenes details, see /tmp/unrestricted-trace.out and /tmp/rsa-trace.out .


What You Should See on the Threat Hunting Platform

Within a few hours, you should be able to review the rare TLS signature report and find a connection between the Internal and External systems with a very rare signature type – if you only ran the second curl command once, you should see it with a count of one at one end of the sorted report.

How to Troubleshoot It If You Don’t

With Zeek

To notice this subtle difference between the two requests, Zeek needs the ja3 plugin installed. The plugin can be found Here. To use it, you’ll need to install it on the Zeek sensor watching the traffic between the Internal and External systems and restart Zeek.

Here’s an example from the Zeek ssl.log file after running the two curl commands above:

cat ssl.log | egrep '(^#|Ext4)' | zeek-cut server_name ja3
Ext4 f436b9416f37d134cadd04886327d3e8
Ext4 418b95b8d5850caf2f05208cb42cc76d

When curl did its normal TLS negotiation with the web server, ja3 reported that with the “f436b9416f37d134cadd04886327d3e8” fingerprint. When curl said it would only use “ECDHE-RSA-AES128-SHA256“, ja3 noted that with a different fingerprint: “418b95b8d5850caf2f05208cb42cc76d“. This rare fingerprint is what you’re looking for if your Threat Hunting platform reports it.

(If you’re using Bro instead of Zeek, substitute “bro-cut” for “zeek-cut” above.)


Links to All Posts in “Threat Simulation” Series

  1. Unexpected Protocol on Non-Standard Port
  2. Long Connections
  3. Client Signatures (User Agent)
  4. DNS
  5. Beacons
  6. Threat Intel
  7. Certificate Issues
  8. Client Signatures (TLS Signature)



Interested in threat hunting tools? Check out AC-Hunter

Active Countermeasures is passionate about providing quality, educational content for the Infosec and Threat Hunting community. We appreciate your feedback so we can keep providing the type of content the community wants to see. Please feel free to Email Us with your ideas!

Share this:
AC-Hunter Datasheet
AC-Hunter Personal Demo
What We’re up To