声明

本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!

引言:

在当今互联网时代,保护通信数据的安全性变得至关重要。为了建立安全的通信连接,TLS(Transport Layer Security)协议被广泛应用于Web浏览器、移动应用和其他网络应用程序中。而与此同时,识别和分析这些TLS通信也成为网络安全研究和威胁情报分析的重要任务之一。JA3指纹作为一种独特的指纹识别技术,为我们提供了一种有效的手段来识别和分析TLS通信。

JA3指纹的概述

什么是JA3指纹?

JA3指纹(JA3 fingerprint)是一种用于网络流量分析的技术,旨在识别和分类不同的TLS(Transport Layer Security)客户端。TLS是一种常用于加密互联网通信的协议,它提供了安全的数据传输和身份验证机制。

JA3指纹通过分析TLS握手阶段中客户端和服务器之间交换的握手消息来创建一个唯一的指纹。在TLS握手期间,客户端和服务器交换一系列的握手消息,包括支持的TLS版本、密码套件、压缩算法和TLS扩展等信息。JA3指纹将这些消息中的特定字段进行哈希处理,生成一个字符串来表示客户端的TLS配置。

由于不同的TLS客户端在握手消息中的字段值可能会有所不同,因此它们生成的JA3指纹也会有所不同。这使得JA3指纹可以用于识别和区分不同类型的TLS客户端,例如Web浏览器、移动应用程序、恶意软件等。

通过分析网络流量中的JA3指纹,安全分析人员和网络管理员可以检测和识别异常的TLS行为、恶意软件的活动或者潜在的网络攻击。然而,值得注意的是,JA3指纹并非绝对可靠,因为攻击者可以通过更改TLS

JA3指纹的组成和格式

JA3指纹由TLS握手消息中的特定字段值组成,并使用逗号进行分隔。以下是JA3指纹的一般格式和组成:

  • JA3_HASH,JA3_SSLVersion,JA3_CipherSuites,JA3_Extensions

  • JA3_HASH:这是根据TLS握手消息中的客户端Hello消息计算得出的哈希值,通常使用MD5或SHA256算法生成。JA3_HASH用于唯一标识TLS客户端的配置。

  • JA3_SSLVersion:这是客户端支持的TLS版本号。例如,TLS 1.2的版本号是0x0303,TLS 1.3的版本号是0x0304。

  • JA3_CipherSuites:这是客户端支持的加密套件列表。加密套件指定了用于加密通信的加密算法和密钥交换协议。每个加密套件都有一个唯一的标识号。在JA3指纹中,多个加密套件由逗号分隔。

  • JA3_Extensions:这是客户端在TLS握手消息中发送的TLS扩展列表。TLS扩展提供了额外的功能和安全性选项。常见的扩展包括Server Name Indication (SNI)、Supported Elliptic Curves、Supported Point Formats等。在JA3指纹中,多个扩展由逗号分隔。

以下是一个示例JA3指纹的格式:

eb6f49e8db7ad1809f885d12232f4855,0x0303,0xc02c,c02b,c02f,c00a,c009,c013,c014,0xff01,0x0000

在上述示例中,JA3_HASH为"eb6f49e8db7ad1809f885d12232f4855",JA3_SSLVersion为0x0303(表示TLS 1.2),JA3_CipherSuites包括多个加密套件,JA3_Extensions为空。

JA3握手指纹和JA3S指纹的区别

JA3指纹和JA3S指纹是两种相关但略有不同的TLS指纹技术。

  1. JA3指纹(Just Another SSL/TLS Fingerprint):它是根据客户端发送的TLS握手消息中的字段值生成的指纹。这些字段包括SSL/TLS版本、加密套件、TLS扩展等信息。JA3指纹用于识别和分类不同的TLS客户端。

  2. JA3S指纹(Just Another SSL/TLS Signature):它是基于服务器在TLS握手过程中发送的服务器Hello消息中的字段值生成的指纹。与JA3指纹不同,JA3S指纹用于识别和分类不同的TLS服务器。

JA3指纹和JA3S指纹的生成方法类似,都是通过计算握手消息中的字段值的哈希值来生成唯一的指纹。它们的区别在于指纹生成的消息来源不同:JA3指纹是基于客户端Hello消息,而JA3S指纹是基于服务器Hello消息。

这两种指纹技术在网络安全领域中被广泛应用,可以用于检测异常的TLS行为、识别恶意软件和网络攻击等。同时,它们也有一定的局限性,因为攻击者可以伪造或篡改握手消息中的字段值,以逃避指纹识别。因此,在使用JA3和JA3S指纹进行分析时,需要结合其他技术和方法进行验证和确认。

JA3和JA3S工具现在已经开源
下载地址: https://github.com/salesforce/ja3

JA3指纹的工作原理

TLS握手过程的关键信息

TLS握手过程中包含了多个关键信息,这些信息对于建立安全连接和进行身份验证非常重要。以下是TLS握手过程中的一些关键信息:

  1. 客户端支持的TLS版本:客户端在ClientHello消息中指定其支持的TLS版本,例如TLS 1.2或TLS 1.3。服务器会根据客户端支持的版本选择适当的协议版本进行通信。

  2. 加密套件(Cipher Suite):加密套件定义了在通信过程中使用的加密算法和密钥交换算法。它包括对称加密算法(如AES、DES)、密钥交换算法(如RSA、Diffie-Hellman)和消息认证算法(如HMAC)等。

  3. 随机数(Random):客户端和服务器都会生成一个随机数,用于生成对称加密算法的密钥、初始化向量(IV)和计算消息认证码(MAC)。随机数的目的是增加通信的随机性和安全性。

  4. 数字证书(Digital Certificate):服务器在ServerHello消息中会发送数字证书,证书用于验证服务器的身份。证书包含服务器的公钥和证书颁发机构(CA)的签名,客户端可以使用该公钥验证服务器的身份和建立安全通信。

  5. 客户端密钥交换(Client Key Exchange):在握手过程中,客户端可能需要发送密钥交换相关的信息,用于与服务器协商会话密钥。这可以是一个PreMaster Secret(预主密钥)或Diffie-Hellman交换的公钥。

  6. 会话标识符(Session Identifier):服务器可以为成功建立的会话分配一个唯一的会话标识符,以便在后续的握手过程中快速恢复会话状态,从而提高性能。

  7. TLS扩展(TLS Extensions):TLS扩展提供了额外的功能和安全性选项。常见的扩展包括Server Name Indication(SNI,用于指定服务器的域名)、支持的加密算法、应用层协议协商(ALPN)等。

这些关键信息在TLS握手期间的交换和协商,确保了通信的机密性、完整性和身份验证,从而建立了安全的TLS连接。

通过TLS握手信息生成JA3指纹

生成JA3指纹需要从TLS握手信息中提取关键字段,并对这些字段进行哈希处理。以下是生成JA3指纹的一般步骤:

  1. 提取TLS握手消息中的关键字段:从客户端Hello消息中提取以下字段值:

       - 支持的TLS版本(SSLVersion)
       - 加密套件(CipherSuites)
       - TLS扩展(Extensions)
    
  2. 将提取的字段值组合成一个字符串:将上述字段值按照特定的顺序连接起来,使用逗号进行分隔。例如:SSLVersion,CipherSuites,Extensions。

  3. 对组合的字符串进行哈希处理:使用特定的哈希算法,例如MD5或SHA256,对上述组合的字符串进行哈希处理,生成一个哈希值。

  4. 将哈希值作为JA3指纹:将生成的哈希值作为最终的JA3指纹。

需要注意的是,不同的实现和工具可能对字段的顺序和格式有所不同。为了确保一致性,建议使用广泛接受的规范来提取字段和生成JA3指纹。

示例
假设提取的字段值为:

SSLVersion: 0x0303
CipherSuites: c02c,c02b,c02f,c00a,c009,c013,c014
Extensions: 0xff01,0x0000

组合的字符串为:0x0303,c02c,c02b,c02f,c00a,c009,c013,c014,0xff01,0x0000
通过MD5哈希处理上述字符串得到哈希值:eb6f49e8db7ad1809f885d12232f4855
最终的JA3指纹为:eb6f49e8db7ad1809f885d12232f4855

实际实现中可能会有一些细微的差异。

JA3指纹的可变性和唯一性

JA3指纹具有一定的可变性和唯一性,这取决于TLS客户端的配置和握手消息中的字段值。

  1. 可变性:
  • 不同的TLS客户端可能支持不同的TLS版本、加密套件和TLS扩展,因此它们的JA3指纹会有所不同。

  • 特定的TLS客户端可能会在不同的环境或配置下生成不同的JA3指纹。例如,同一款Web浏览器在不同的操作系统、版本或插件配置下生成的JA3指纹可能会有差异。

  1. 唯一性:
  • 在大多数情况下,每个TLS客户端的配置会生成一个唯一的JA3指纹。由于握手消息中的字段值是在握手期间由客户端动态生成的,因此不同的配置通常会产生不同的JA3指纹。

  • JA3指纹的哈希算法(如MD5或SHA256)通常能够保证较低的碰撞概率,即不同的配置生成相同的指纹的可能性较低。

然而,需要注意的是,JA3指纹并不是绝对唯一和确定性的标识符,也存在一些限制和局限性:

  1. 攻击者可以通过修改握手消息中的字段值来更改JA3指纹,从而规避指纹识别。

  2. 同一款TLS客户端的不同版本或补丁更新可能会导致生成不同的JA3指纹,因此在比较和匹配JA3指纹时需要考虑版本和细微差异。

  3. 由于新的TLS版本、加密套件和扩展的发布,TLS客户端的配置也可能会发生变化,进而影响JA3指纹的唯一性。

综上所述,JA3指纹在识别和分类TLS客户端方面提供了一种有用的方法,但在实际应用中需要综合考虑其他因素并进行进一步验证,以确保准确性和可靠性。

JA3指纹的应用

具体分为两部分

网络安全领域的应用

  1. 威胁情报分析

  2. 恶意软件检测

  3. 流量分析和监测

应用领域的应用

  1. 应用识别和版本检测

  2. 通信指纹的对比和识别

  3. 数据包的分类和过滤

JA3指纹的实例和实用技巧

JA3指纹:eb6f49e8db7ad1809f885d12232f4855

实用技巧:

  1. JA3指纹的比对:通过收集和比对网络流量中的JA3指纹,可以检测和识别不同类型的TLS客户端。例如,您可以建立一个JA3指纹数据库,并与实时的网络流量进行比对,以发现异常或恶意的TLS行为。

  2. 恶意软件识别:JA3指纹可用于检测和分类恶意软件的通信行为。通过比对已知恶意软件的JA3指纹,您可以快速识别并阻止类似指纹的流量,以提高网络安全性。

  3. 威胁情报分析:JA3指纹可以与威胁情报平台进行集成,以获取有关特定指纹的更多信息。这样,您可以了解该指纹是否与已知的恶意活动、攻击或特定组织相关联。

  4. 异常检测:通过监视网络流量中的JA3指纹变化,您可以识别到不寻常的TLS行为。例如,当某个JA3指纹频繁变化或与正常流量有明显差异时,可能表明存在潜在的安全问题或攻击行为。

  5. 风险评估和访问控制:在安全环境中,根据JA3指纹可以评估客户端的安全性,并采取相应的访问控制策略。如果某个客户端的JA3指纹与高风险的配置相关,可以采取额外的安全措施,例如强制进行多因素身份验证或限制其访问权限。

  6. 安全事件响应:JA3指纹可以用于网络安全事件的响应和调查。在检测到安全事件后,可以使用JA3指纹追踪相关的TLS客户端,并识别受影响的系统或用户,从而进行进一步的分析和应对。

注意,JA3指纹仅作为一种辅助工具和指标,应与其他安全技术和方法相结合使用,以全面评估和提高网络安全性。

JA3指纹的限制和隐私考虑

JA3指纹具有隐私保护和加密协议选择以及JA3指纹的可变性和易受干扰性

以下是常见的限制和隐私考虑:

  1. 配置和环境的影响:JA3指纹受到TLS客户端的配置和环境影响。不同的配置和环境可能导致不同的JA3指纹,这可能增加了误报或漏报的风险。

  2. 版本和升级的影响:TLS客户端的版本和升级可能导致JA3指纹的变化。对于同一款TLS客户端的不同版本,其生成的JA3指纹可能会有差异。这需要在分析和比对JA3指纹时考虑版本和细微差异。

  3. 隐私泄露风险:JA3指纹可以泄露关于客户端的一些信息,例如所使用的TLS版本、加密套件和扩展。这些信息可能被用于识别和追踪特定的客户端,从而对隐私造成风险。特别是在面对具有大规模网络流量的环境时,JA3指纹的唯一性可能导致识别个体用户。

  4. 指纹伪造:攻击者有可能通过修改TLS握手消息中的字段值来伪造JA3指纹,以规避指纹识别和防御措施。这可能降低JA3指纹的可靠性和准确性,因此在使用JA3指纹时需要谨慎验证和结合其他信息进行分析。

  5. 数据采集和存储:收集和存储大量的JA3指纹数据可能需要相应的资源和隐私保护措施。确保合规性和数据安全性非常重要,包括数据保护、加密和访问控制等方面的考虑。

抓包展示

用下某网站做测试 且此网站也有有Ja3指纹加密的

aHR0cHM6Ly9nZ3p5LmppYW5neGkuZ292LmNuL3h3ZHQvMDAxMDAyL3NlYzEuaHRtbA==

fiddler

!注意 fiddler要想抓Ja3-tls指纹 包
要把CONNECTS选项取消勾选,不然抓不到指纹包

然后我们抓到了很多指纹包,然后我们挨个打开看看

逆向之Ja3指纹学习-小白菜博客
然后我们看到很多的加密算法,还有加密方式
其实这种包其实本质上就是加入黑名单

已经tls的版本也有

charles

相比较fiddler charles抓到的包就很有限了。
但是操作也更加的简单了
我们直接打开charles 然后刷新网站
逆向之Ja3指纹学习-小白菜博客
这里直接就显示了tls的信息
逆向之Ja3指纹学习-小白菜博客
我们接着点开详细信息 这里显示了tls的加密方式 已经加密的两种方式.

这两种抓包方式终究还是图一乐,真要抓包还得看wireshark

wireshark

步骤如下

  1. 查询网站IP地址 ======> cmd ======> ping xxx.com =====> 复制IP地址

  2. 打开wireShark抓包,选择抓取的网卡

  3. 刷新浏览器

  4. 在过滤器中输入 ip.addr == 你要查看的ip地址 具体如下图

  5. 找到一个Client hello的包

  6. 查看详细信息

最下面的是hash指纹 和详细指纹信息

把这个指纹fullstring复制出来
771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,18-51-35-23-45-5-27-10-13-43-65281-11-16-17513-0-21,29-23-24,0
这个指纹信息就是网站可以运行的指纹信息

指纹分析

指纹信息分析其实很简单,
我们接下来用三种方式去获取这个指纹信息
也就是上文的771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,18-51-35-23-45-5-27-10-13-43-65281-11-16-17513-0-21,29-23-24,0

浏览器

这里我们选择直接用上文抓包抓到的指纹
还有一种方式
https://tls.browserleaks.com/json 直接去网站看自己的浏览器指纹也是可以的

由于上面已经获取了浏览器的指纹了,我们直接就拿来用了

771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,18-51-35-23-45-5-27-10-13-43-65281-11-16-17513-0-21,29-23-24,0

python

接着我们使用requests原生库,即正常访问,携带基本的参数去请求即可
我们使用代码去访问下这个网站https://tls.browserleaks.com/json

import requests

r = requests.get('https://tls.browserleaks.com/json', verify=True)
print(r.text)

结果

{
  "ja3_hash": "8d9f7747675e24454cd9b7ed35c58707",
  "ja3_text": "771,4866-4867-4865-49196-49200-49195-49199-52393-52392-159-158-52394-49327-49325-49326-49324-49188-49192-49187-49191-49162-49172-49161-49171-49315-49311-49314-49310-107-103-57-51-157-156-49313-49309-49312-49308-61-60-53-47-255,0-11-10-16-22-23-49-13-43-45-51-21,29-23-30-25-24,0-1-2",
  "ja3n_hash": "a790a1e311289ac1543f411f6ffceddf",
  "ja3n_text": "771,4866-4867-4865-49196-49200-49195-49199-52393-52392-159-158-52394-49327-49325-49326-49324-49188-49192-49187-49191-49162-49172-49161-49171-49315-49311-49314-49310-107-103-57-51-157-156-49313-49309-49312-49308-61-60-53-47-255,0-10-11-13-16-21-22-23-43-45-49-51,29-23-30-25-24,0-1-2",
  "akamai_hash": "",
  "akamai_text": ""
}

所以这个指纹是

771,4866-4867-4865-49196-49200-49195-49199-52393-52392-159-158-52394-49327-49325-49326-49324-49188-49192-49187-49191-49162-49172-49161-49171-49315-49311-49314-49310-107-103-57-51-157-156-49313-49309-49312-49308-61-60-53-47-255,0-11-10-16-22-23-49-13-43-45-51-21,29-23-30-25-24,0-1-2

python 魔改库

我们再试试 Python有关SSL的魔改库
其实这类库有很多
简单举例两个吧 一个是 curl_cffi 一个是 tls_client

我们这里使用curl_cffi 去访问一下看看这个指纹是什么

from curl_cffi import requests

r = requests.get("https://tls.browserleaks.com/json", impersonate="chrome101")
print(r.text)

结果

{
  "ja3_hash": "cd08e31494f9531f560d64c695473da9",
  "ja3_text": "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0",
  "ja3n_hash": "aa56c057ad164ec4fdcb7a5a283be9fc",
  "ja3n_text": "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-5-10-11-13-16-18-21-23-27-35-43-45-51-17513-65281,29-23-24,0",
  "akamai_hash": "4f04edce68a7ecbe689edce7bf5f23f3",
  "akamai_text": "1:65536;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p"
}

而这个指纹是

771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0

总结三种方式

然后我们把这三个指纹拿出来做个对比

逆向之Ja3指纹学习-小白菜博客

可以清楚地看到 python的魔改库和浏览器的指纹是长度是一样的。

这样我们可以知道了,这个指纹长度只要和浏览器相同就可以了。

我们使用魔改库访问开头所要访问的网站实验一下

逆向之Ja3指纹学习-小白菜博客
发现可以正常访问

那该如何不借助魔改库去完成Ja3网站的解密呢
可以通过修改ssl的套接字 使得防火墙黑名单失效
从而保证指纹长度一致 即可完成解密

tls 检测的绕过方案

临时方案:

注意 requests库必须在2.4 以上版本 不然会失败

requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS ='ALL'

修改了requests内部包的 ssI里面的套接字设置,使防火墙黑名单失效

动态 DEFAULT CIPHERS :
https://www.openssl.org/docs/man1.1.1/man1/openssl-ciphers.html
https://support.huaweicloud.com/bestpractice-waf/waf_06_0012.html
这种方法国内处理就已经够了

# 默认 cipher 在这里定义:https://github.com/encode/httpx/blob/master/httpx/_config.py
import ssl
import httpx

# create an ssl context
ssl_context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS)
CIPHERS = 'DH+AES:RSA+AES'
ssl_context.set_ciphers(CIPHERS)

r = httpx.get('https://tls.browserleaks.com/json', verify=ssl_context)
print(r.text)

非临时方案:
自设ssl,并覆写requests中的类的一些方法
https://stackoverflow.com/questions/60407057/python-requests-being-fingerprinted

https://stackoverflow.com/questions/64967706/python-requests-https-code-403-without-but-code-200-when-using-burpsuite

深入理解requests中 建立 tls的过程
先抓包看下正常的访问 tls,和requests访问的区别
我们需要单步调试requests源码,并且想办法修改 tls访问过程中的UA
按照上面的思路,加上对 ssl的理解,就可以实现一个针对于 tls检测的高并发方案

总结

JA3指纹是一种通过提取和哈希TLS握手消息中的关键字段来标识和识别TLS客户端的方法。它可以用于识别不同类型的TLS客户端、检测恶意软件、进行威胁情报分析、异常检测和风险评估等。

然而,JA3指纹也有一些限制和隐私考虑。它受到TLS客户端配置和环境的影响,可能受到版本和升级的影响。此外,使用JA3指纹可能泄露一些客户端信息,存在隐私风险,并且有可能被攻击者伪造。

在使用JA3指纹时,需要综合考虑其实用性和隐私风险。适当的数据采集和存储措施、数据保护、加密和隐私保护措施都是重要的考虑因素。此外,JA3指纹应作为辅助工具和指标,并结合其他安全技术和方法来提高网络安全性。

总之,JA3指纹提供了一种用于标识和识别TLS客户端的方法,可以在网络安全领域的多个方面发挥作用,但需要在实际应用中权衡其实用性、准确性和隐私风险

参考文献