A JARM fingerprint is a passive, client-side TLS fingerprinting method used to identify the specific TLS stack of a server or proxy by analyzing its response to a series of specially crafted TLS ClientHello probes. Developed by Salesforce, JARM provides a unique fingerprint for a server's TLS implementation, enabling operators to identify specific server software, detect proxies, and track infrastructure.
Understanding JARM Fingerprints
JARM (Just Another Rather Marvelous) fingerprinting works by sending 10 distinct TLS ClientHello packets to a target server. Each ClientHello is designed with specific, ordered variations in its parameters, such as supported TLS versions, cipher suites, extensions, and elliptic curves. The server's responses to these probes, which include its chosen TLS version, cipher suite, extensions, and other handshake parameters, are then concatenated and hashed to produce a 62-character fingerprint.
This process exploits subtle differences in how various TLS stacks (e.g., OpenSSL, Microsoft SChannel, Go's crypto/tls, BoringSSL, LibreSSL) negotiate TLS handshakes. Even minor configuration differences or patch levels can result in distinct JARM fingerprints.
JARM Probe Details
The 10 ClientHello probes vary across several dimensions:
* TLS Versions: Probes target specific TLS versions (e.g., TLS 1.0, 1.1, 1.2, 1.3).
* Cipher Suites: Each probe includes a distinct list and order of cipher suites.
* Extensions: Different sets and order of TLS extensions (e.g., SNI, ALPN, renegotiation_info, supported_groups) are used.
* Elliptic Curves: Variations in supported elliptic curves are included.
The server's ServerHello response to each of these 10 probes is captured. The key fields extracted from these responses include:
* TLS version negotiated
* Cipher suite chosen
* List of extensions present
* Form of the SNI extension response (if any)
These extracted fields are then concatenated into a single string. This string is subsequently MD5 hashed, and a subset of this hash, along with a SHA-256 hash of the full response string, forms the final 62-character JARM fingerprint. The fingerprint is structured to encode information about the responses to each of the 10 probes.
Why JARM is Useful for Proxy Services
JARM fingerprints offer several practical applications for organizations operating or interacting with proxy services.
Server and Software Identification
JARM can precisely identify the underlying TLS library and configuration of a server or proxy. This allows:
* Software Classification: Differentiating between common web servers like Nginx, Apache HTTP Server, Microsoft IIS, Caddy, or application servers like Tomcat, Jetty.
* Version Detection: Often, different versions or patch levels of the same software will yield distinct JARM fingerprints due to changes in their TLS stack implementation.
* Misconfiguration Detection: Unexpected fingerprints can indicate non-standard configurations or potential security issues.
Proxy Detection and Characterization
For a proxy service, identifying intermediate proxies is critical for understanding network paths and security posture.
* Reverse Proxies and CDNs: When a client connects to a server behind a reverse proxy, load balancer, or Content Delivery Network (CDN), the JARM fingerprint will reflect the TLS stack of the proxy/CDN edge node, not the origin server. This allows for the identification of services like Cloudflare, Akamai, AWS CloudFront, or Nginx/HAProxy acting as a reverse proxy.
* Forward Proxies: A forward proxy might present its own TLS stack when performing TLS interception (MITM). If a client's connection is intercepted, the JARM fingerprint obtained by the client will belong to the forward proxy, not the intended destination. Non-intercepting forward proxies typically pass through the ClientHello, preserving the origin server's JARM.
* WAFs (Web Application Firewalls): Many WAFs operate as reverse proxies and will present their own JARM fingerprint.
Security and Threat Intelligence
JARM is a valuable tool in security operations:
* Malware C2 Identification: Threat actors often reuse specific TLS stacks for their Command and Control (C2) infrastructure. JARM can fingerprint these C2 servers, allowing for their identification and tracking across different IP addresses or domains.
* Infrastructure Mapping: Security researchers use JARM to map out attacker infrastructure, identify shared components, and link seemingly disparate campaigns.
* Phishing Detection: Identifying unexpected JARM fingerprints for legitimate domains can indicate a phishing attempt where an attacker is using different infrastructure.
Network Visibility
JARM provides a deeper understanding of the TLS ecosystem that a proxy interacts with:
* Baseline Establishment: Creating a baseline of expected JARM fingerprints for known services and partners helps detect anomalies.
* Service Discovery: Identifying the underlying technology of services without requiring application-level interaction.
Generating a JARM Fingerprint
Generating a JARM fingerprint involves sending the specific probes and processing the responses. Tools and libraries are available for this purpose.
Example: Using Python jarm Library
The jarm Python library provides a straightforward way to generate fingerprints.
import jarm
def get_jarm_fingerprint(host, port=443):
"""
Generates a JARM fingerprint for a given host and port.
"""
try:
fingerprint = jarm.string_fingerprint(host, port, timeout=5)
return fingerprint
except Exception as e:
return f"Error generating JARM for {host}:{port}: {e}"
if __name__ == "__main__":
target_host_1 = "www.example.com"
target_host_2 = "cloudflare.com" # Often fronted by Cloudflare's own TLS stack
target_host_3 = "nginx.org"
print(f"JARM for {target_host_1}: {get_jarm_fingerprint(target_host_1)}")
print(f"JARM for {target_host_2}: {get_jarm_fingerprint(target_host_2)}")
print(f"JARM for {target_host_3}: {get_jarm_fingerprint(target_host_3)}")
This script will connect to the specified host and port, send the JARM probes, and print the resulting 62-character fingerprint.
Interpreting JARM Fingerprints
A JARM fingerprint itself is an opaque string. Its value comes from comparison and association with known services or threat actors.
* Database Lookup: Public and private databases (e.g., JARM.info, Shodan, Censys) collect and associate JARM fingerprints with known software, services, and organizations.
* Pattern Recognition: Specific JARM fingerprints often correlate with particular TLS libraries or server software. For example:
* 27d40d40d27d40d00045d40d00041d01dd2d4000000000494a000000000000 is a common fingerprint for Nginx.
* 07d14d14d07d14d00041d14d0000000d1d2d00000000000000000000000000 is often seen with Apache HTTP Server (OpenSSL).
* 07d07d07d07d07d00041d07d0000000d1d2d00000000000000000000000000 can indicate Cloudflare.
* Anomaly Detection: Any deviation from an expected fingerprint for a known service warrants investigation.
JARM and Proxy Behavior
The interaction between JARM and proxy services is central to its utility.
Forward Proxies
- Non-Intercepting Forward Proxies: These proxies simply forward the client's ClientHello to the destination server. In this scenario, the JARM fingerprint observed by the client (if the client were generating a JARM for the server) would be that of the origin server. However, if the proxy service itself were acting as a client and generating a JARM for a destination, it would still get the origin server's JARM.
- Intercepting Forward Proxies (TLS Inspection): When a forward proxy performs TLS inspection (e.g., for security scanning or policy enforcement), it acts as a Man-in-the-Middle (MITM). It terminates the client's TLS connection and establishes a new one with the origin server. The JARM fingerprint observed by the client would be that of the forward proxy's TLS stack. Conversely, the JARM fingerprint observed by the origin server would be that of the forward proxy's TLS stack. This behavior is a key indicator for detecting TLS inspection.
Reverse Proxies, Load Balancers, and CDNs
These services sit in front of one or more origin servers and handle incoming client connections.
* The JARM fingerprint obtained by a client connecting to a service fronted by a reverse proxy, load balancer, or CDN will always reflect the TLS stack of that intermediary.
* The origin server's JARM fingerprint is masked from external observation. This is a primary mechanism for identifying these types of services. For example, connecting to google.com will yield a JARM fingerprint for Google's edge infrastructure, not the specific backend server handling the request.
Limitations and Considerations
While powerful, JARM has limitations:
* Active Probing: JARM requires sending active probes to a target, which may not always be feasible or permitted in all environments.
* Dynamic Changes: Server configurations, software updates, or load balancer changes can alter a JARM fingerprint, requiring continuous monitoring and re-fingerprinting.
* Spoofing: Sophisticated adversaries can configure their TLS stacks to mimic known JARM fingerprints, though this requires specific effort.
* Coverage: JARM captures specific aspects of the TLS handshake but does not provide a complete picture of all TLS configuration details.
JARM vs. JA3
Both JARM and JA3 are TLS fingerprinting techniques, but they serve different purposes.
| Feature | JARM | JA3 |
|---|---|---|
| Target | Server (identifies the TLS stack of a server or proxy) | Client (identifies the TLS stack of a client application) |
| Methodology | Sends 10 distinct, crafted ClientHello probes and hashes the server's ServerHello responses. | Analyzes a single ClientHello packet sent by a client, extracting ordered lists of TLS version, cipher suites, extensions, elliptic curves, and elliptic curve formats, then hashes them. |
| Fingerprint Type | 62-character string derived from multiple ServerHello responses. | MD5 hash of a concatenated string (e.g., TLSVersion,Ciphers,Extensions,EllipticCurves,EllipticCurvePointFormats). |
| Use Case | Identifying server software, detecting proxies/CDNs, tracking C2 infrastructure, network mapping. | Identifying specific client applications (e.g., web browsers, malware, IoT devices), detecting botnets, application profiling. |
| Observation Point | Requires a client to initiate connections to the target server. | Requires a server or network device to observe the ClientHello from a client. |
| Origin | Salesforce (2020) | Salesforce (2017) |
JARM focuses on the server's response behavior, making it ideal for identifying the entities that terminate TLS connections, including proxy services.