要获取JA3指纹,通常需要从TLS握手的Client Hello消息中提取特定字段并进行哈希计算。以下是不同场景下获取JA3指纹的方法:
1. 从网络流量中提取(被动方式)
通过抓包工具捕获网络流量,解析TLS握手过程中的Client Hello消息。
工具推荐:
-
Scapy(Python库)
使用Python的scapy
库解析网络包,提取JA3指纹:from scapy.all import * from ja3 import parse_tls_payload, generate_ja3_digest def packet_callback(packet): if packet.haslayer("TCP") and packet.haslayer("Raw"): payload = packet["Raw"].load # 检查是否为TLS Client Hello包(SSL Record层类型0x16) if payload.startswith(b'\x16\x03'): try: ja3_dict = parse_tls_payload(payload) if ja3_dict: ja3_string = dict_to_ja3_string(ja3_dict) digest = generate_ja3_digest(ja3_string) print(f"源IP: {packet['IP'].src}, JA3指纹: {digest}") except Exception as e: pass # 开始抓包(监听443端口的HTTPS流量) sniff(filter="tcp port 443", prn=packet_callback, store=0)
-
JA3er(在线工具)
使用在线工具JA3er.com上传PCAP文件,自动解析JA3指纹。
2. 主动探测目标服务器的JA3指纹
通过发送TLS握手请求并记录服务器的响应来获取服务器的JA3指纹。
工具推荐:
-
OpenSSL(命令行)
使用OpenSSL发送TLS请求并查看握手细节:openssl s_client -connect example.com:443 -servername example.com
手动提取
Supported Elliptic Curves
、Supported Point Formats
等字段计算JA3。 -
Python脚本
使用ssl
和socket
库主动连接并获取服务器证书信息:import socket import ssl from ja3 import generate_ja3_digest def get_server_ja3(hostname, port=443): try: # 创建SSL上下文 context = ssl.create_default_context() with socket.create_connection((hostname, port)) as sock: with context.wrap_socket(sock, server_hostname=hostname) as ssock: # 获取TLS握手信息 cipher = ssock.cipher() print(f"密码套件: {cipher}") # 获取证书信息 cert = ssock.getpeercert() print(f"证书: {cert}") # 注意:Python标准库无法直接获取完整JA3所需的所有字段 # 这里仅作示例,实际需要更底层的TLS实现 except Exception as e: print(f"错误: {e}") get_server_ja3("example.com")
3. 浏览器/客户端JA3指纹(JavaScript)
在浏览器环境中,由于安全限制,无法直接访问完整的TLS握手信息,但可以通过JavaScript获取部分指纹信息。
方法:
-
使用
navigator
对象
获取浏览器支持的加密算法、TLS版本等信息(有限):const fingerprint = { userAgent: navigator.userAgent, languages: navigator.languages, platform: navigator.platform, // 更多指纹信息... }; console.log(JSON.stringify(fingerprint, null, 2));
-
第三方库
使用如FingerprintJS2
等库收集浏览器指纹(非JA3标准,但类似原理):<script src="https://cdn.jsdelivr.net/npm/fingerprintjs2@2.1.0/dist/fingerprint2.min.js"></script> <script> Fingerprint2.get((components) => { const values = components.map(component => component.value); const murmur = Fingerprint2.x64hash128(values.join(''), 31); console.log('浏览器指纹:', murmur); }); </script>
4. 商业工具与平台
- Wireshark
直接使用Wireshark抓包,通过插件或自定义解析器提取JA3指纹。 - Suricata
开源IDS/IPS工具,支持JA3指纹检测规则。 - 商业安全产品
如FireEye、CrowdStrike等EDR平台通常集成JA3指纹分析功能。
5. 自建JA3指纹数据库
将收集到的指纹存储到数据库,用于后续比对和分析:
import sqlite3
def create_ja3_db():
conn = sqlite3.connect('ja3_fingerprints.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS fingerprints
(id INTEGER PRIMARY KEY,
digest TEXT UNIQUE,
device_type TEXT,
first_seen TIMESTAMP DEFAULT CURRENT_TIMESTAMP)''')
conn.commit()
conn.close()
def add_fingerprint(digest, device_type):
conn = sqlite3.connect('ja3_fingerprints.db')
c = conn.cursor()
try:
c.execute("INSERT INTO fingerprints (digest, device_type) VALUES (?, ?)",
(digest, device_type))
conn.commit()
except sqlite3.IntegrityError:
# 指纹已存在,更新信息
pass
conn.close()
总结
- 被动获取:通过抓包工具(Scapy、Wireshark)从网络流量中提取。
- 主动探测:使用OpenSSL或自定义脚本连接目标服务器获取。
- 浏览器指纹:使用JavaScript获取部分信息(有限)。
- 工具集成:结合商业安全产品或开源工具(Suricata)实现自动化检测。
根据具体需求选择合适的方法,通常网络安全场景中更常用被动获取方式,而浏览器指纹多用于反欺诈或用户识别。