无垠之码

深度剖析代码之道


ssl&tls指纹

关于JA3算法,最早可以追溯到2015年的DerbyCon会议(信息安全、黑客与渗透测试为主题),美国加州云计算公司Salesforce的Lee Brotherston公开了其关于TLS指纹的研究工作。随后2017年,Salesforce研究员John Althouse在Lee Brotherston基础上正式公开了TLS指纹算法JA3。实际上JA3算法工作由John Althouse,Jeff Atkinson,Josh Atkins三人共同完成,因此命名为JA3算法。

JA3算法基于TLS ClientHello消息字段构建的客户端指纹算法,常用于威胁情报分析、恶意软件检测及加密流量识别等安全场景。

1.JA3算法


在TLS握手阶段,客户端和服务器以明文协商加密算法套件(Cipher Suite),但后续的密钥交换和应用数据才会被加密,JA3/JA3S算法正是基于这些明文握手信息构建客户端和服务器的TLS指纹。JA3算法通过收集握手阶段TLS协议中的TLSVersion,Ciphers,Extensions,EllipticCurves,EllipticCurvePointFormats信息,计算客户端指纹,参与计算的字段如下图所示。

image

771,47–53–5–10–49161–49162–49171–49172–50–56–19–4,0–10–11,23–24–25,0,字符串随后通过MD5计算,生成易于使用和分享的32字符指纹ada70206e40642a3e4461f35503241d5。JA3算法在计算指纹时会忽略Google GREASE中定义的随机扩展字段,以保证同一客户端即使使用GREASE,也能生成唯一稳定的指纹。相同主机的不同浏览器因为使用不同的加密算法套件和扩展,一般指纹并不相同。Wireshark的3.6.2-2版本已内置对JA3算法的支持,能够直接从TLS握手数据包中实时解析并呈现客户端指纹。

JA3S是指服务器的TLS指纹,与客户端类似,其使用TLS协议中的TLSVersion,Cipher,Extensions字段,生成32字符的服务端指纹。通常情况下,服务器对不同客户端的响应不同,因此指纹可能会变化。但对于同一个客户端,生成的服务端指纹基本是唯一且稳定的。

./emerging-ja3.rules:42:alert tls $HOME_NET any -> $EXTERNAL_NET any (msg:"ET JA3 Hash - Metasploit http scanner (tested: 4.11.5 Kali)"; ja3_hash; content:"16f17c896273d1d098314a02e87dd4cb"; reference:url,github.com/trisulnsm/trisul-scripts/blob/master/lua/frontend_scripts/reassembly/ja3/prints/ja3fingerprint.json; classtype:unknown; sid:2028301; rev:2; metadata:created_at 2019_09_10, confidence Low, signature_severity Major, tag Description_Generated_By_Proofpoint_Nexus, updated_at 2019_10_29;)

恶意软件通常使用其自带的加密库进行通信,因此生成的客户端TLS指纹JA3往往具有唯一性,可用于识别特定恶意通信。即使恶意软件使用系统提供的加密库或操作系统套接字,其JA3指纹在同一环境中仍可能相对稳定,但可能与其他常用应用相同,从而降低唯一性。在这种情况下,结合 JA3S服务器端指纹进行辅助识别仍然有效。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import pprint
from pymisp import PyMISP

API_ENDPOINT = "http://10.10.0.107"
TOKEN = "StMhTXPnmErXDGrWMfddlhzdsHkkrhkUSDNyDKUQ"

def main():
    misp = PyMISP(API_ENDPOINT, TOKEN)
    iocs = misp.search(
        "attributes", type_attribute="ja3-fingerprint-md5", page=1, limit=1000
    )
    pp = pprint.PrettyPrinter(indent=4)
    pp.pprint(iocs)


if __name__ == "__main__":
    main()

{   'Attribute': [   {   'Event': {   'distribution': '3',
                                      'id': '261',
                                      'info': 'Detecting and Preventing '
                                              'Malicious Domains Proactively '
                                              'with DNS Security',
                                      'org_id': '1',
                                      'orgc_id': '2',
                                      'publish_timestamp': '1743563922',
                                      'uuid': 'e74cba52-0314-43c2-9958-43a55619fcf5'},
                         'Object': {   'distribution': '5',
                                       'id': '3',
                                       'sharing_group_id': '0'},
                         'category': 'Network activity',
                         'comment': '',
                         'deleted': False,
                         'disable_correlation': False,
                         'distribution': '5',
                         'event_id': '261',
                         'first_seen': None,
                         'id': '23158',
                         'last_seen': None,
                         'object_id': '3',
                         'object_relation': 'ja3-fingerprint-md5',
                         'sharing_group_id': '0',
                         'timestamp': '1620154157',
                         'to_ids': True,
                         'type': 'ja3-fingerprint-md5',
                         'uuid': '531b9684-6da7-463c-b1df-da8e49abfcc8',
                         'value': '6312930a139fa3ed22b87abb75c16afa'},
                     {   'Event': {   'distribution': '3',
                                      'id': '488',
                                      'info': 'MOD Netherlands uncovers '
                                              'COATHANGER, a stealthy Chinese '
                                              'FortiGate RAT',
                                      'org_id': '1',
                                      'orgc_id': '2',
                                      'publish_timestamp': '1743564056',
                                      'uuid': '67033954-cb9d-4aad-ae23-435b246b016e'},
                         'category': 'Network activity',
                         'comment': '# This JA3-hash is a fingerprint for '
                                    'connections originating # from FortiGate '
                                    'devices that support all encryption and # '
                                    'hashing algorithms for doing TLS.  # '
                                    'Whereas the far majority of '
                                    'TLS-connections use different # '
                                    'parameters, the built-in logging '
                                    'functionality of FortiGate # devices '
                                    'seems to make use of identical '
                                    'TLS-parameters, # leading to potential '
                                    'false positive results from this JA3 # '
                                    'hash.  # Therefore, traffic should be '
                                    'judged as legitimate (i.e., as # false '
                                    'positive indicator of COATHANGER) if it '
                                    'originates # from a FortiGate device and '
                                    'has: # − port 541 or 514 as destination '
                                    'port and # − an IP address belonging to '
                                    'Fortinet Inc. or a Fortinet # device, '
                                    'such as a FortiManager as destination.',
                         'deleted': False,
                         'disable_correlation': False,
                         'distribution': '5',
                         'event_id': '488',
                         'first_seen': None,
                         'id': '48254',
                         'last_seen': None,
                         'object_id': '0',
                         'object_relation': None,
                         'sharing_group_id': '0',
                         'timestamp': '1707293890',
                         'to_ids': True,
                         'type': 'ja3-fingerprint-md5',
                         'uuid': '72d82e76-2be7-4bb8-aa3b-e0b37fc02597',
                         'value': '339f6adf54e6076d069dcaac54fddc25'}]}

前面介绍的JA3|JA3S算法,是一种被动指纹采集手段。下面介绍的使用主动探测方案生成服务端指纹的JARM算法,可用于快速检查一组服务器是否使用相同的TLS配置,对于运维、合规审计或发现配置错误非常有用,同时通过将具有相同TLS指纹特征的服务器归类,有助于识别云服务提供商或基础设施归属。

JARM通过向TLS服务器,发送10个经过设计的Client Hello报文,然后选取TLS服务器响应中的特定属性汇总,并按照特定方式进行哈希运算,从而生成JARM指纹。JARM指纹使用混合模糊hash算法,生成62字符的指纹数据。前30个字符由服务器针对发送的10个Client Hello中选择的加密套件和TLS版本组成,后32个字符是服务器发送的所有扩展信息的SHA256截断哈希。在比较JARM指纹时,如果前30个字符相同,但后32个字符不同,这意味着服务器的配置非常相似,支持相同的TLS版本和加密套件,但由于扩展信息不同,配置并不是完全一致。

研究发现,攻击者使用的C2服务器通常具有相同的JARM指纹特征,而且这些指纹与Alexa前100万网站的指纹完全不重叠(Alexa是知名网站排名榜,其前100个流行网站在此前的Tor匿名流量分类研究中也被引用)。

pyjarm baidu.com
Target: baidu.com:443
JARM: 29d1fb00029d29d1fc29d1fb1fb29dfcafcab2e75118e87142efdb7e13a350

在过去,网络安全行业主要依赖对原子级别的威胁指标(IOCs,Indicators of Compromise)的被动阻断列表。也就是说,行业通常要等到某个恶意软件活动在现实中被发现、分析之后,才会将观察到的 IOC收集起来并发布到阻断列表中。问题在于,当这些IOC被发布时,恶意软件往往已经传播开来,安全工程师只能处于被动防御状态,进行损害控制。

但结合JARM的互联网扫描、其他元数据以及历史分析,现在可以实现主动识别新攻击活动的IOC。例如,网络安全研究人员或公司可以使用JARM扫描互联网上的服务器,将已知JARM指纹结果与域名和IP历史、信誉以及证书信息进行关联,从而构建高精度的阻断列表。这使得网络安全行业有可能在恶意软件首次分发之前,就程序化地建立高精度阻断列表,从而首次将威胁行为者置于被动防御的局面。

2.JA3算法的演进->JA4


在对抗环境下,单独使用JA3已难以满足高精度检测需求,因此通常需要结合更先进的指纹技术,如JA4等进行综合分析。JA4被称为新一代网络指纹技术Next-gen fingerprinting for modern threat detection,由FoxIO提出,其JA4™与JA4+™被认为是当前较为先进的网络指纹标准之一。

相较于JA3指纹技术,JA4生成的指纹在设计上更具可读性,对人类和机器均更加友好。同时,JA4具备更强的表达能力,可描述更多类型的网络设备与通信行为,例如 SSH、TCP以及HTTP等协议的指纹信息。

image

TLS指纹

在TLS指纹方面,相较于JA3算法,JA4在对信息进行分组的同时,引入了更多TLS字段参与指纹构建,从而提升了指纹的表达能力与区分度。

image image

HTTP指纹

如下图所示,HTTP指纹由a、b、c、d 四个部分构成。其中a与b用于表征应用程序指纹,主要包含HTTP请求中的常规头部字段;c表示服务端相关Cookie字段的哈希指纹;d表示用户端相关Cookie字段的哈希指纹。

image image

SSH指纹

JA4SSH指纹通过统计SSH会话周期内,默认前200个报文的流量分布特征,分别提取客户端与服务端应用层载荷的长度众数Mode,并结合双向报文总数及空确认包Bare ACKs计数构建而成。该方法能够深度刻画加密隧道内的行为演变模式,从而在不解密的前提下,实现对交互式登录、自动化脚本、反弹Shell及大文件传输等特定会话类型的精准分类与识别。

image

X509证书指纹

JA4X指纹使用X509证书的结构信息(指证书字段的排列顺序、扩展项的选择、编码方式等),而非具体字段内容作为算法指纹特征。其关注对创建该证书的应用程序或脚本进行的指纹画像,而非对证书本身的识别。当与其它元数据结合使用时,它将演变为一种极其强大的互联网对象分类工具。例如,仅通过组合使用JA4X指纹和证书颁发者Issuer信息,即可精准发现大量活跃的Cobalt Strike C2节点。

image

TCP指纹

JA4TCP算法通过提取TCP三次握手起始阶段的SYN报文特征构建指纹。该算法不仅能够基于协议栈实现差异对设备类型(如操作系统、嵌入式固件)进行精准画像,还能通过分析报文中的特定字段(如 TTL、窗口大小及选项序列)推断其所处的网络拓扑环境及中转链路特征。

image

通信延时指纹

JA4L测量通信双方在会话初始化节点的延时信息,以及TTL信息,可以大致推断通信双方的真实距离。

image image

3.参考文献

  1. https://github.com/salesforce/ja3?tab=readme-ov-file
  2. https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967/
  3. https://github.com/FoxIO-LLC/ja4
  4. https://engineering.salesforce.com/easily-identify-malicious-servers-on-the-internet-with-jarm-e095edac525a/
  5. https://x.com/4A4133/status/1887269972545839559
  6. https://raw.githubusercontent.com/FoxIO-LLC/ja4/refs/heads/main/ja4plus-mapping.csv
  7. ja4+_db.json
  8. https://sslbl.abuse.ch/blacklist/#ssl-certificates-csv