Una huella digital JARM es un método de huellas digitales TLS pasivo, del lado del cliente, utilizado para identificar la pila TLS específica de un servidor o proxy analizando su respuesta a una serie de sondas TLS ClientHello especialmente diseñadas. Desarrollado por Salesforce, JARM proporciona una huella digital única para la implementación TLS de un servidor, permitiendo a los operadores identificar software de servidor específico, detectar proxies y rastrear infraestructura.
Entendiendo las Huellas Digitales JARM
La huella digital JARM (Just Another Rather Marvelous) funciona enviando 10 paquetes TLS ClientHello distintos a un servidor objetivo. Cada ClientHello está diseñado con variaciones específicas y ordenadas en sus parámetros, como versiones TLS compatibles, suites de cifrado, extensiones y curvas elípticas. Las respuestas del servidor a estas sondas, que incluyen su versión TLS elegida, suite de cifrado, extensiones y otros parámetros de handshake, se concatenan y se les aplica un hash para producir una huella digital de 62 caracteres.
Este proceso explota diferencias sutiles en cómo varias pilas TLS (por ejemplo, OpenSSL, Microsoft SChannel, crypto/tls de Go, BoringSSL, LibreSSL) negocian los handshakes TLS. Incluso diferencias menores en la configuración o niveles de parche pueden resultar en huellas digitales JARM distintas.
Detalles de las Sondas JARM
Las 10 sondas ClientHello varían en varias dimensiones:
* Versiones TLS: Las sondas apuntan a versiones TLS específicas (por ejemplo, TLS 1.0, 1.1, 1.2, 1.3).
* Suites de Cifrado: Cada sonda incluye una lista y un orden distintos de suites de cifrado.
* Extensiones: Se utilizan diferentes conjuntos y órdenes de extensiones TLS (por ejemplo, SNI, ALPN, renegotiation_info, supported_groups).
* Curvas Elípticas: Se incluyen variaciones en las curvas elípticas compatibles.
Se captura la respuesta ServerHello del servidor a cada una de estas 10 sondas. Los campos clave extraídos de estas respuestas incluyen:
* Versión TLS negociada
* Suite de cifrado elegida
* Lista de extensiones presentes
* Forma de la respuesta de la extensión SNI (si la hay)
Estos campos extraídos se concatenan en una sola cadena. Posteriormente, a esta cadena se le aplica un hash MD5, y un subconjunto de este hash, junto con un hash SHA-256 de la cadena de respuesta completa, forma la huella digital JARM final de 62 caracteres. La huella digital está estructurada para codificar información sobre las respuestas a cada una de las 10 sondas.
Por Qué JARM es Útil para Servicios de Proxy
Las huellas digitales JARM ofrecen varias aplicaciones prácticas para organizaciones que operan o interactúan con servicios de proxy.
Identificación de Servidores y Software
JARM puede identificar con precisión la biblioteca TLS subyacente y la configuración de un servidor o proxy. Esto permite:
* Clasificación de Software: Diferenciar entre servidores web comunes como Nginx, Apache HTTP Server, Microsoft IIS, Caddy, o servidores de aplicaciones como Tomcat, Jetty.
* Detección de Versiones: A menudo, diferentes versiones o niveles de parche del mismo software producirán huellas digitales JARM distintas debido a cambios en la implementación de su pila TLS.
* Detección de Mala Configuración: Huellas digitales inesperadas pueden indicar configuraciones no estándar o posibles problemas de seguridad.
Detección y Caracterización de Proxies
Para un servicio de proxy, identificar los proxies intermedios es fundamental para comprender las rutas de red y la postura de seguridad.
* Proxies Inversos y CDNs: Cuando un cliente se conecta a un servidor detrás de un proxy inverso, balanceador de carga o Red de Entrega de Contenido (CDN), la huella digital JARM reflejará la pila TLS del nodo perimetral del proxy/CDN, no la del servidor de origen. Esto permite la identificación de servicios como Cloudflare, Akamai, AWS CloudFront, o Nginx/HAProxy actuando como proxy inverso.
* Proxies de Reenvío: Un proxy de reenvío podría presentar su propia pila TLS al realizar la intercepción TLS (MITM). Si la conexión de un cliente es interceptada, la huella digital JARM obtenida por el cliente pertenecerá al proxy de reenvío, no al destino previsto. Los proxies de reenvío no interceptores suelen pasar el ClientHello, preservando el JARM del servidor de origen.
* WAFs (Web Application Firewalls): Muchos WAFs operan como proxies inversos y presentarán su propia huella digital JARM.
Seguridad e Inteligencia de Amenazas
JARM es una herramienta valiosa en las operaciones de seguridad:
* Identificación de C2 de Malware: Los actores de amenazas a menudo reutilizan pilas TLS específicas para su infraestructura de Comando y Control (C2). JARM puede identificar estos servidores C2, permitiendo su identificación y seguimiento a través de diferentes direcciones IP o dominios.
* Mapeo de Infraestructura: Los investigadores de seguridad utilizan JARM para mapear la infraestructura de los atacantes, identificar componentes compartidos y vincular campañas aparentemente dispares.
* Detección de Phishing: La identificación de huellas digitales JARM inesperadas para dominios legítimos puede indicar un intento de phishing donde un atacante está utilizando una infraestructura diferente.
Visibilidad de la Red
JARM proporciona una comprensión más profunda del ecosistema TLS con el que interactúa un proxy:
* Establecimiento de Línea Base: Crear una línea base de huellas digitales JARM esperadas para servicios y socios conocidos ayuda a detectar anomalías.
* Descubrimiento de Servicios: Identificar la tecnología subyacente de los servicios sin requerir interacción a nivel de aplicación.
Generando una Huella Digital JARM
Generar una huella digital JARM implica enviar las sondas específicas y procesar las respuestas. Existen herramientas y bibliotecas disponibles para este propósito.
Ejemplo: Uso de la Biblioteca jarm de Python
La biblioteca jarm de Python proporciona una forma sencilla de generar huellas digitales.
```python
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