关于TLS握手指纹 JA3的一些发现

前文

前几天第一次接触到ja3,十分的好奇。经过今天几天的研究和学习,发现了点东西,记录下。另外下篇会分享自己用php撸的ja3获取工具。

另外本文将https://ja3er.com/form简称为ja3er。

ja3_Hash获取规则

  • 场景
    tls clint hello,准确的说是:
    • 字节 0:值 22,表示根据 TLS 规范的“握手”。
    • 字节 5:根据 TLS 规范,值 1,在握手包内指示客户端问候。
    • 字节 9:值 3,两个字节中的第一个字节,与任何版本的 TLS 对齐的 TLS 版本。如果匹配 SSL,该值也可能为 0。
    • 字节 1:与字节 9 相同,但与记录 TLS 版本有关”
  • 字段顺序
    TLSVersion,Ciphers,Extensions,EllipticCurves,EllipticCurvePointFormats
  • 拼接规则
    按顺序连接在一起,使用“,”分隔每个字段,使用“-”分隔每个字段中的每个值。
  • MD5 哈希处理
    拼接后的ja3_str经过MD5处理得到ja3_hash
  • 忽略的值,该值在Ciphers,Extensions,EllipticCurves会出现

GREASE

具体为:

 $GREASE_TABELE = [
        2570,//(0x0A0A)
        6682,//(0x1A1A)
        10794,//(0x2A2A)
        14906,//(0x3A3A)
        19018,//(0x4A4A)
        23130,//(0x5A5A)
        27242,//(0x6A6A)
        31354,//(0x7A7A)
        35466,//(0x8A8A)
        39578,//(0x9A9A)
        43690,//(0xAAAA)
        47802,//(0xBABA)
        51914,//(0xCACA)
        56026,//(0xDADA)
        60138,//(0xEAEA)
        64250,//(0xFAFA)
    ];

发现

忽略的扩展

ja3er 中的ja3_str会把类型值为17513的扩展忽略掉

Type: application_settings (17513)
例子:

// from ja3er 
……27-21,29-23-24,0
// from mycode
……27-17513,29-23-24,0

变化的ja3

与curl 不同,ja3_str 在chrome中是2个值

//第一次访问时是一个值
……27-17513-21,29-23-24,0
// 之后的访问是另外一个值
……27-17513,29-23-24,0

主要是取决于场景,在chrome中

  1. 首次访问session_ticket为空
    此时会增加一个拓展,名为padding,类型值为21

    Type: padding (21)

  2. 之后访问session_ticket有值
    此时没有padding扩展

这个情况在ja3er和我的代码中都会出现,应该是tls session 机制导致。ja3er中比较难复现,可以尝试用无痕。

关于Wireshark的JA3

示例数据:

[JA3 Fullstring: 771,10794-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,60138-0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-31354,23130-29-23-24,0]
[JA3: 432d80490caf1b032a7e091754f2f597]

如果你也有测试,你会发现在Wireshark中,JA3不是固定的。原因很简单,它并没有忽略GREASE。如实例中,771,10794-4865 中的 10794,正是10794,//(0x2A2A)

nginx几个与ja3相关的变量

只测试了本地和我的服务器,仅供参考

nginx 配置
   location ~ \.php(.*)$ {
        fastcgi_param  ssl_protocol $ssl_protocol;
        fastcgi_param  ssl_curves $ssl_curves;
        fastcgi_param  ssl_cipher $ssl_cipher;
        fastcgi_param  ssl_ciphers $ssl_ciphers;
        fastcgi_param  ssl_server_name $ssl_server_name;
        fastcgi_param  ssl_client_fingerprint $ssl_client_fingerprint;
        fastcgi_param   ssl_session_id $ssl_session_id;
        
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
        fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO  $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED  $document_root$fastcgi_path_info;
        include fastcgi_params;
    }

php代码
var_dump(__FILE__.' line:'.__LINE__,$_SERVER);exit;
结果
  • 数据示例
  ["ssl_session_id"]=>
  string(64) "8ba7742fd5a32ddb4c842aa34ce97325cd19015720389ff8c04650e049be4b75"
  ["ssl_client_fingerprint"]=>
  string(0) ""
  ["ssl_server_name"]=>
  string(5) "xxx.com"
  ["ssl_ciphers"]=>
  string(355) "0xcaca:TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA:AES256-SHA"
  ["ssl_cipher"]=>
  string(27) "ECDHE-RSA-AES256-GCM-SHA384"
  ["ssl_curves"]=>
  string(0) "0x1a1a:X25519:prime256v1:secp384r1"
  ["ssl_protocol"]=>
  string(7) "TLSv1.2"
  • 对比
变量ssl_protocolssl_curvesssl_cipherssl_server_namessl_client_fingerprintssl_session_id
首次访问YYYYemptyempty
后续访问YemptyYYemptyY
  • 发现
  1. ssl_session_id 并不是固定值,每次请求都会变化。
  2. ssl_session_id存在时会与Wireshark抓到的一致,也就是时传递过来的,不太懂为啥第一次就没有。

Session ID: 8ba7742fd5a32ddb4c842aa34ce97325cd19015720389ff8c04650e049be4b75

  1. 首次访问时,与jas_str字段差距只是缺少Extensions。或许可以作为一个简化版的ja3。

TLSVersion,Ciphers,Extensions,EllipticCurves,EllipticCurvePointFormats

SNI 真的很好取

备案检测是怎么做到的?,另外了解到,ie部分版本是不支持SNI,也就是你可以用它上未备案的网站,然而这没卵用。具体支持情况:
SNI支持情况

参考

tls-fingerprinting

原文链接

关于TLS握手指纹 JA3的一些发现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值