Threat Hunting Exercise: Analyzing IDS JA3/TLS Fingerprint C2 Framework Detection Dataset
This hunt uses a simulated IDS/TLS-inspection dataset (ids_ja3_c2_2022-04-23T110000.json) capturing T1071.001: Web Protocols and T1573.001: Symmetric Cryptography, where an adversary's C2 framework (Cobalt Strike-style) presents a distinctive JA3 client-hello fingerprint during outbound TLS handshakes, even though the certificate itself is valid and the destination domain looks benign.
Step 1: Hypothesis Formation
Hypothesis: A host establishes outbound TLS sessions whose JA3 hash matches a known-malicious C2 framework fingerprint (e.g., default Cobalt Strike Malleable C2 JA3 72a589da586844d7f0818ce684948eea), repeated across multiple sessions to the same or rotating destinations, regardless of the SNI/domain presented. Indicators:
- IDS TLS-fingerprint module flags JA3 hash matching a published malicious-tool database.
- Repeated sessions with identical JA3 but varying SNI (domain fronting/rotation behavior).
- JA3S (server-side fingerprint) also matches a known C2 listener profile.
- Certificate is valid/trusted (e.g., Let's Encrypt) - ruling out simple cert-based detection, reinforcing the need for JA3.
Null Hypothesis: The JA3 hash collision is caused by a legitimate but uncommon TLS client library (e.g., an older Python requests/OpenSSL build) used by an internal automation script. Invalidate by checking the process/host for a known legitimate automation tool matching that TLS stack.
Rationale: As C2 frameworks increasingly use legitimate, trusted certificates and common-looking domains, JA3/JA3S fingerprinting is one of the few remaining network-only signals that survives TLS encryption; this hunt validates its detection value in isolation.
Step 2: Data Sources and Scope
- Sources: IDS/NSM with TLS fingerprinting (Zeek
ssl.logJA3/JA3S fields); Firewall session logs for corroboration; DNS logs for SNI/domain resolution history. - Scope: ~2022-04-23T11:00:00-13:00:00 UTC; Host: WKS-SALES-022 (10.50.7.19); Destinations: 3 rotating IPs, all presenting SNI values for newly-registered lookalike domains.
- SIEM Queries (Splunk/ELK):
- JA3 match:
index=zeek sourcetype=ssl ja3="72a589da586844d7f0818ce684948eea" | stats count by src_ip, dest_ip, server_name - SNI rotation check:
index=zeek sourcetype=ssl ja3="72a589da586844d7f0818ce684948eea" | stats dc(server_name) as sni_count by src_ip - JA3S corroboration:
index=zeek sourcetype=ssl ja3s="a95f...known_c2_listener"
Step 3: Key Findings
Parsed events (7 shown) confirm 22 TLS sessions from a single host all sharing a known-malicious JA3 hash across three rotating destinations.
| Timestamp (UTC) | Src IP | Dest IP | SNI | JA3/JA3S | IOC/Why Suspicious? |
|---|---|---|---|---|---|
| 2022-04-23 11:02:10 | 10.50.7.19 | 45.61.147.20 | cdn-assets-update[.]com | ja3=72a5...4eea | Fingerprint IOC: JA3 matches a published Cobalt Strike default Malleable-C2 profile. |
| 2022-04-23 11:14:33 | 10.50.7.19 | 45.61.147.20 | cdn-assets-update[.]com | ja3=72a5...4eea (same) | Repeat session, same JA3, ~12 min later - consistent with a beacon sleep/jitter interval. |
| 2022-04-23 11:45:02 | 10.50.7.19 | 91.219.238.4 | cloud-metrics-api[.]net | ja3=72a5...4eea (same) | Rotation IOC: same JA3 fingerprint, new destination IP and SNI - infrastructure/domain rotation, fingerprint stays constant since the TLS client library doesn't change. |
| 2022-04-23 12:01:19 | 10.50.7.19 | 91.219.238.4 | cloud-metrics-api[.]net | ja3s matches known listener | JA3S (server hello) also matches a cataloged C2 listener signature - corroborates from the server side, not just client side. |
| 2022-04-23 12:30:44 | 10.50.7.19 | 185.174.100.9 | update-service-cdn[.]com | ja3=72a5...4eea (same) | Third destination in the rotation, same fingerprint - three lookalike domains registered within the prior 10 days per WHOIS. |
| - | 10.50.7.19 | (process check) | N/A | Legitimacy check IOC: no automation script or legitimate tool on the asset inventory for WKS-SALES-022 uses a matching TLS library; host is a standard user workstation, not a server running scheduled jobs. | |
| 2022-04-23 13:00:00 | 10.50.7.19 | (session summary) | N/A | 22 total sessions across the 2-hour window, all sharing the identical JA3 despite three distinct SNIs and IPs - statistically implausible for organic browser/application diversity. |
Validation:
- Timeline: Consistent JA3 across rotating infrastructure over a 2-hour window - classic domain/IP-rotation C2 behavior designed to evade static IOC blocklists.
- False Positives: Ruled out legitimate automation via asset/process inventory; the JA3S server-side match independently corroborates the client-side finding, reducing single-signal false-positive risk.
- Correlation: Single source host, single consistent JA3 hash, three destinations - a tight cluster pointing to one active implant rather than shared infrastructure noise.
Step 4: Recommendations & Next Steps
- Immediate Response: Isolate WKS-SALES-022; capture memory for implant extraction; block all three observed destination IPs and SNI domains at the proxy/firewall; pull EDR process telemetry to identify the beaconing process and its parent chain.
- Detection: Sigma-style NSM rule:
title: Known-Malicious JA3 Fingerprint Outbound→selection: ja3 IN (known_c2_ja3_list)- maintain and regularly update the JA3 blocklist from threat-intel feeds (e.g., abuse.ch SSLBL). - Pro Tip: JA3 alone is not infallible - commodity libraries can collide - so always pair it with JA3S and behavioral corroboration (rotation, interval regularity) before declaring high confidence; treat single-signal JA3 hits as leads, not verdicts.
Hypothesis confirmed - a known-malicious JA3/JA3S TLS fingerprint was observed across rotating C2 infrastructure from a single compromised host!