TLS Fingerprinting for Encrypted C2 Hunting — JA3, JA4, JARM analysis on AWS VPC Flow Logs

TLS Fingerprinting (JA3, JA4, JARM) for Encrypted C2 Hunting

TLS Fingerprinting for Encrypted C2 Hunting — JA3, JA4, JARM analysis on AWS VPC Flow Logs — HACKFORLAB cover

From the hunt desk. If your network detection strategy is built around TLS interception, you have a problem coming: every modern C2 framework now ships with custom TLS stacks that defeat passive inspection, and the operators have learned to imitate browser ClientHello messages well enough that decryption is the only thing that gives you the actual payload. Decryption is increasingly impossible at cloud scale. What still works — and what every mature blue team is leaning on harder every quarter — is TLS fingerprinting. Specifically, the JA3, JA4, and JARM families of hashes that you can compute from the unencrypted handshake without ever touching key material.

This post walks through the playbook for using JA3, JA4, and JARM as primary hunt signals on AWS workloads, plus the rarity-scoring techniques that turn a fingerprint into an alert. VPC Flow Logs are the volumetric layer; the fingerprint extraction itself happens at a passive Network Load Balancer mirror, a Traffic Mirroring session, or via Suricata / Zeek running on a sensor instance. We cover all three architectures, plus the open-source fingerprint corpora that let you scope rarity without doing the work from scratch.

This is post #7 in our VPC Flow Log detection-engineering series. Together with FFT beacon detection and DGA + DNS-tunnel hunting, this completes the encrypted-channel coverage for HTTPS-based command and control.

Why JA3 Stopped Being Enough

JA3, published by the original JA3 author team in 2017, was a watershed moment. The idea was simple: hash the unencrypted ClientHello fields (TLS version, cipher suites, extensions, elliptic curves, EC point formats) into a stable string fingerprint. A specific client library — Python’s requests, Go’s net/http, the official Slack desktop app, a particular version of commercial C2 frameworks’s beacon — produces the same JA3 hash on every connection. Block the hash, you block the client. Allow the hash, you don’t have to trust the destination IP.

What killed JA3 as a standalone control was uTLS — a Go library that lets an implant impersonate any browser’s ClientHello byte-for-byte. By 2022, every serious red-team tool had uTLS support. The commercial C2 frameworks fork, open-source C2 frameworks, open-source C2 frameworks implants, commercial offensive toolkits, open-source offensive frameworks — all of them ship today with options to imitate Chrome’s exact JA3 hash. Defenders running JA3 allow-lists were silently being bypassed, often for months.

JA4 — also from the original JA3 author, published in 2023 — is the response. JA4 is structurally similar to JA3 but adds the TLS version negotiated, the ALPN value, and a separate JA4_a / JA4_b / JA4_c hash split that makes the fingerprint harder to spoof in entirety. Operators who imitated Chrome’s JA3 don’t automatically imitate Chrome’s JA4 — the hash space is larger and the negotiated parameters depend on the destination server, which the operator can’t fully control. JA4 also covers TLS 1.3 properly, which JA3 didn’t.

JARM — 2020 — is the server-side mirror. Instead of fingerprinting the client, JARM fingerprints how a TLS server responds to ten specially-crafted ClientHellos. Two servers that produce the same JARM hash are running the same TLS stack, the same library version, often the same operator configuration. C2 servers running default malleable C2 profiles common in commercial frameworks produce a JARM hash that the entire CTI community has tracked since 2020.

The Detection Pipeline

TLS Fingerprinting detection pipeline — five-step architecture from VPC Flow Logs through fingerprint extraction to rarity scoring and alert

Five stages, identical structural shape to the DGA pipeline but optimised for TLS metadata rather than DNS.

  1. Capture. JA3, JA4, JARM hashes come from a TLS-aware sensor — Suricata, Zeek, or a Lambda-based extractor reading from a VPC Traffic Mirroring session. AWS Traffic Mirroring delivers a copy of every packet to a sensor ENI; the sensor parses the TLS handshake and emits one row per session with the fingerprint and the five-tuple. Free, no decryption, no key material involved.
  2. VPC Flow Logs join. The sensor’s session rows join to VPC Flow Logs on the five-tuple. The result is one row per session containing (src, dst, dst_port, bytes, packets, start, end, ja3, ja4, jarm). Athena handles the join efficiently if both sources land in S3 partitioned by date.
  3. Rarity scoring. Each fingerprint hash is looked up against (a) your own 14-day baseline of hashes seen in the environment, (b) the open JA4 community corpus, (c) the open community threat-intel feeds for known-bad fingerprints for known-bad fingerprints. The output is a rarity score plus a tag: known_legit, known_bad, rare, or novel.
  4. Volumetric overlay. Rare and novel fingerprints get amplified by VPC Flow Log context — number of bytes transferred, persistence (multiple sessions over hours), destination geography. A novel fingerprint with two bytes transferred is probably a misconfigured agent; the same fingerprint with 50 MB transferred over six hours is an incident.
  5. Alert + IOC export. Final score crosses threshold → alert to SIEM. The fingerprint plus destination IP / domain becomes a STIX indicator pushed to your TIP. The community version of MISP has an excellent fingerprint:tls-ja3 attribute type that maps cleanly.

Feature Engineering

Feature Source Formula / method What it captures
JA3 hash Sensor (Suricata/Zeek) md5 of ClientHello fields Client library fingerprint
JA4 fingerprint Sensor JA4 spec (3-part) Improved client fingerprint (TLS 1.3-aware)
JARM hash Active prober 10-probe TLS response signature Server-side stack fingerprint
Hash rarity (internal) 14-day baseline 1 / count_in_baseline Newness in your environment
Hash rarity (global) JA4 community corpus presence + frequency Newness in the world
Destination ASN diversity VPC Flow Logs distinct ASNs per fingerprint per host Operator infrastructure rotation
Session persistence VPC Flow Logs fingerprint sessions over rolling 24h Beacon-like recurrence
Byte volume per session VPC Flow Logs bytes / session C2 vs exfil channel

Athena SQL — Fingerprint Rarity Hunt

Assume your TLS sensor lands rows into tls_sessions with the fingerprint columns. The query below scores per-host fingerprint rarity over a 7-day window and surfaces rare or novel fingerprints with non-trivial byte volume.

WITH session_features AS (
    SELECT t.srcaddr, t.dstaddr, t.dstport, t.ja3, t.ja4, t.jarm,
           t.start, f.bytes, f.packets
    FROM tls_sessions t
    JOIN central_vpc_flow_logs f
      ON t.srcaddr = f.srcaddr
     AND t.dstaddr = f.dstaddr
     AND t.dstport = f.dstport
     AND ABS(t.start - f.start) < 5
    WHERE t.day BETWEEN '2026/05/09' AND '2026/05/15'
),
fingerprint_baseline AS (
    SELECT ja4, COUNT(*) AS occurrences
    FROM session_features
    WHERE start < '2026-05-15'
    GROUP BY ja4
),
rare_fingerprints AS (
    SELECT srcaddr, ja4,
           COUNT(*)               AS sessions_24h,
           SUM(bytes)             AS total_bytes,
           COUNT(DISTINCT dstaddr) AS distinct_destinations,
           MIN(occurrences)       AS baseline_count
    FROM session_features s
    LEFT JOIN fingerprint_baseline b USING (ja4)
    GROUP BY srcaddr, ja4
)
SELECT srcaddr, ja4,
       sessions_24h, total_bytes, distinct_destinations,
       COALESCE(baseline_count, 0) AS baseline_seen
FROM rare_fingerprints
WHERE (COALESCE(baseline_count, 0) <= 5 OR baseline_count IS NULL)
  AND total_bytes > 50000
  AND sessions_24h > 3
ORDER BY total_bytes DESC;

The output is your investigation queue. Each row is a (host, fingerprint) pair that is rare in your environment, has moved meaningful data, and has recurred more than three times — a fairly clean signal for active C2.

What Specific Fingerprints Mean in 2026

Treat the list below as starting points to enrich; the corpora linked at the bottom of this section are always more current than any blog post.

  • default commercial-framework beacons (legacy JA3 72a589da586844d7f0818ce684948eea) — still seen weekly in low-skill engagements; modern operators have moved past it but the hash is a clean signal when it appears.
  • commercial frameworks with uTLS Chrome imitation — JA3 matches real Chrome; JA4 typically does not. Catching it requires JA4-based detection or JARM on the server side.
  • open-source mTLS implant defaults — distinctive JA3 hash when run unmodified; trivially rotated by operators. The JARM hash of the open-source C2 frameworks C2 listener is what catches it on the server side.
  • modular open-source agents — depends on the C2 profile chosen; the framework allows arbitrary TLS profile imitation, so detection lives entirely in the JARM signature of the listener.
  • recent commercial offensive toolkits — async beacon traffic uses standard libraries by default; JA3 looks like any Go HTTPS client. JARM on the server is reliable. JA4 on the client increasingly reliable.

The pattern is clear: client-side fingerprinting (JA3, JA4) is increasingly bypassed by uTLS-equipped implants. Server-side fingerprinting (JARM) is harder to bypass — operators have to configure their C2 listeners to imitate a real service, and most don’t bother. JARM scanning of the destination IP is the highest-yield single check in this entire post.

Limits and False-Positive Sources

  • Embedded SDKs. A new feature shipped to a mobile app brings a new TLS library, a new JA4. Filter rare fingerprints by app-version-bump correlation if you have RUM telemetry.
  • CI / CD runners. Each runner image ships a different curl/wget/Python version. The JA4 churn is high and benign. Tag at source.
  • Kubernetes Istio sidecars. The Envoy proxy that intercepts pod traffic produces a JA4 that depends on the Envoy version. Allow-list by source pod label.
  • TLS-terminating load balancers. If your sensor sees the LB-to-backend traffic instead of client-to-LB, you’re fingerprinting the LB, not the client. Place the sensor on the right side of the TLS termination point — usually outside the ELB / ALB.
  • Genuinely new SaaS adoption. A new vendor in production brings a new fingerprint that won’t be in your 14-day baseline. Pre-suppress via a “service approved this week” channel.

MITRE ATT&CK Techniques Covered

ATT&CK ID Technique / sub-technique Coverage Hunter notes
T1573 Encrypted Channel (parent) Full The whole post is about this
T1573.001 Symmetric Cryptography Full
T1573.002 Asymmetric Cryptography Full JA3/JA4 on TLS, JARM on server
T1071.001 Application Layer Protocol: Web Protocols Full HTTPS C2 is the default surface
T1090 Proxy Full HTTPS proxy hops fingerprintable
T1090.004 Proxy: Domain Fronting Partial SNI fronts the legitimate domain but JA4 still reflects the client library
T1102 Web Service Partial
T1102.002 Web Service: Bidirectional Communication Partial
T1095 Non-Application Layer Protocol Out of scope Below TLS
T1568 Dynamic Resolution Out of scope See series post #6 (DGA + DNS tunnel)

Adversary emulation. Run open-source mTLS implants with default configuration, a commercial C2 framework with default profile, and a modular open-source agent. Each will produce distinct JA4 + JARM combinations. Validate that the pipeline flags all three as rare. For repeatable emulation, the open-source adversary-emulation frameworks “C2-establishment” plugin lets you scripts those connections.

Tooling references. public ja3 reference implementation (original JA3 implementation), public ja4 reference implementation (JA4 reference + community corpus), public jarm reference implementation (JARM scanner). All Apache 2.0, all production-ready, all maintained.

D3FEND mapping. This pipeline implements D3-NTA with TLS-specific scope.

Where This Sits in a Mature Threat Hunting Programme

Closing Thoughts

TLS fingerprinting will not catch the most disciplined operators in 2026 — anyone running uTLS plus careful JARM-aware server profiling is invisible at the handshake layer. What it will catch is everyone else, which is most of what passes through a typical enterprise network on any given week. Build it, baseline it, watch the rare-fingerprint queue. The first month produces a flood; by month three the queue runs at a few alerts per day and every one of them is worth investigating.

Happy threat hunting.

#threathunting #tls #ja3 #ja4 #jarm #encryptedc2 #vpcflowlogs #awssecurity #cobaltstrike #sliver #soc #blueteam #detectionengineering #mitreattack

Core Working Areas :- Threat Intelligence, Digital Forensics, Incident Response, Fraud Investigation, Web Application Security Technical Certifications :- Computer Hacking Forensics Investigator | Certified Ethical Hacker | Certified Cyber crime investigator | Certified Professional Hacker | Certified Professional Forensics Analyst | Redhat certified Engineer | Cisco Certified Network Associates | Certified Firewall Solutions | Certified Network Monitoring Solution | Certified Proxy Solutions

Leave a Reply

Your email address will not be published. Required fields are marked *

Enter Captcha Here : *

Reload Image