目录
前文
昨天在TLS指纹初探中对TLS指纹进行了一些测试。并且在stream_socket的模拟请求中,通过修改流的加密方法可以修改TLS指纹。今天尝试在其他方法。
复习下原理
JA3 为客户端 Hello 数据包中的以下字段收集字节的十进制值;SSL 版本、接受的密码、扩展列表、椭圆曲线和椭圆曲线格式。然后它将这些值按顺序连接在一起,使用“,”分隔每个字段,使用“-”分隔每个字段中的每个值。
字段顺序如下:
SSLVersion,Cipher,SSLExtension,EllipticCurve,EllipticCurvePointFormat
例子:
769,47-53-5-10-49161-49162-49171-49172-50-56-19-4,0-10-11,23-24-25,0
如果客户端问候中没有 SSL 扩展,则这些字段留空。
例子:
769,4-5-10-9-100-98-3-6-19-18-99,
然后对这些字符串进行 MD5 哈希处理,以生成易于使用和共享的 32 字符指纹。这是 JA3 SSL 客户端指纹。
769,47-53-5-10-49161-49162-49171-49172-50-56-19-4,0-10-11,23-24-25,0 --> ada70206e40642a3e4461f35503241d5
769,4-5-10-9-100-98-3-6-19-18-99, --> de350869b8c85de67a350c8d186f11e6
我们还需要引入一些代码来解释 Google 的 GREASE(生成随机扩展和维持可扩展性),如此处所述。Google 将其用作防止 TLS 生态系统中的可扩展性失败的机制。JA3 完全忽略这些值,以确保使用 GREASE 的程序仍然可以通过单个 JA3 哈希来识别。
思路
像个办法修改 SSL 版本、接受的密码、扩展列表、椭圆曲线和椭圆曲线格式 中的内容就可以是指纹改变。接下来就是找可以关于SLL配置的地方。
在翻阅一波php文档后发现以下几个页面:
测试
workerman/http-client
代码
<?php
require __DIR__ . '/../../XFrame/init.php';
use Workerman\Worker;
$worker = new Worker();
$worker->onWorkerStart = function(){
$http = new Workerman\Http\Client( [
'context'=>[
'ssl'=>[
'allow_self_signed'=>false,
'verify_peer'=>false,
'verify_peer_name'=>false,
]
]
]);
$http->request('https://ja3er.com/json', [
'method' => 'GET',
'version' => '1.1',
'headers' => ['Connection' => 'keep-alive','User-Agent'=>'ja3 test'],
'success' => function ($response) {
echo $response->getBody();
},
'error' => function ($exception) {
echo $exception;
}
]);
};
Worker::runAll();
结果
{"ja3_hash":"0a6b3cdcc29ee2ed7372388c24fae51d", "ja3": "771,49199-49195-49200-49196-158-162-163-159-49191-49187-49171-49161-49192-49188-49172-49162-103-51-64-107-56-57-156-157-49326-49324-49314-49310-50-49312-49308-60-47-49327-49325-49315-49311-106-49313-49309-61-53-52393-52392-52394-49245-49249-49239-49235-49244-49248-49238-49234-49267-49271-196-195-49266-49270-190-189-136-135-69-68-49233-49232-192-18
6-132-65-255,0-11-10-35-22-23-13-21,29-23-1035-25-24,0-1-2", "User-Agent": "ja3 test"}
- ciphers = AES128, AES256, AES
{"ja3_hash":"6adb19467d440c7bf2e4120180192de4", "ja3": "771,49195-49199-162-158-49326-49324-49314-49310-49187-49191-103-64-49161-49171-51-50-156-49312-49308-60-47-49196-49200-163-159-49327-49325-49315-49311-49188-49192-107-106-49162-49172-57-56-157-49313-49309-61-53-255,0-11-10-35-22-23-13,29-23-1035-25-24,0-1-2", "User-Agent": "ja3 test"}
php-curl
代码
$url = 'https://ja3er.com/json';
$headerArray =array("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36');
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,FALSE);
curl_setopt($curl,CURLOPT_HTTPHEADER,$headerArray);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($curl);
curl_close($curl);
echo $output;
结果
- CURLOPT_SSL_CIPHER_LIST not set
{"ja3_hash":"eaa1a9e1db47ffcca16305566a6efba4", "ja3": "771,4866-4867-4865-49196-49200-159-52393-52392-52394-49195-49199-158-49188-49192-107-49187-49191-103-49162-49172-57-49161-49171-51-157-156-61-60-53-47-255,0-11-10-13172-16-22-23-49-13-43-45-51-21,29-23-1035-25-24,0-1-2", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.
36"}
- CURLOPT_SSL_CIPHER_LIST = ‘AES128, AES256, AES’
{"ja3_hash":"1fa9be2231119b014980fd9c91116346", "ja3": "771,4866-4867-4865-49195-49199-162-158-49326-49324-49314-49310-49187-49191-103-64-49161-49171-51-50-156-49312-49308-60-47-49196-49200-163-159-49327-49325-49315-49311-49188-49192-107-106-49162-49172-57-56-157-49313-49309-61-53-255,0-11-10-13172-16-22-23-49-13-43-45-51-21,29-23-1035-25-24,0-1-2", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x
64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"}
nodejs-request
代码
let request = require('request');
request({
url: 'https://ja3er.com/json',
method: 'GET',
headers: {
"User-Agent": 'ja3 test',
},
agentOptions:{
# ciphers:'AES128, AES256, AES',
},
timeout:5000
}, function(error, res, body) {
console.log(error, body)
})
结果
{"ja3_hash":"c4aac137ff0b0ac82f3c138cf174b427", "ja3": "771,4866-4867-4865-49199-49195-49200-49196-158-49191-103-49192-107-163-159-52393-52392-52394-49327-49325-49315-49311-49245-49249-49239-49235-162-49326-49324-49314-49310-49244-49248-49238-49234-49188-106-49187-64-49162-49172-57-56-49161-49171-51-50-157-49313-49309-49233-156-49312-49308-49232-61-60-53-47-255,0-11-10-35-22-23-13-43-45-51,29-23-1035-25-24,0-1-2", "User-Agent": "ja3 test"}
- ciphers ‘AES128, AES256, AES’,
{"ja3_hash":"6adb19467d440c7bf2e4120180192de4", "ja3": "771,49195-49199-162-158-49326-49324-49314-49310-49187-49191-103-64-49161-49171-51-50-156-49312-49308-60-47-49196-49200-163-159-49327-49325-49315-49311-49188-49192-107-106-49162-49172-57-56-157-49313-49309-61-53-255,0-11-10-35-22-23-13,29-23-1035-25-24,0-1-2", "User-Agent": "ja3 test"}
小结
通过修改加密列表可以修改TLS指纹
总结
客户端的TLS指纹可以轻易的被修改,如果被攻击方使用的是指纹黑名单机制。本文的方法已经可以轻易破解。不过修改后的指纹会更加独特,在有其他追踪策略的情况下则会更容易暴露。相反,思路应该是往大众浏览器指纹去伪造才是躲避追踪的方法。
关于 curl
在命令行中的curl也有类似配置:
–ciphers <list of ciphers>
(TLS) Specifies which ciphers to use in the connection. The list of ciphers must specify valid ciphers. Read up on SSL cipher list details on this URL:
https://curl.se/docs/ssl-ciphers.html
If this option is used several times, the last one will be used.
Example:
curl --ciphers ECDHE-ECDSA-AES256-CCM8 https://example.com
参考
salesforce/ja3