突破tls/ja3新轮子

我之前的文章介绍了SSL指纹识别

https://mp.weixin.qq.com/s/BvotXrFXwYvGWpqHKoj3uQ

很多人来问我BYPass的方法

主流的BYPASS方法有两大类:

  1. 使用定制ja3的网络库 go在这块的库比较流行(比如go的库requests还有cycletls) 缺点在于,就是得用go语言开发(cycletls有nodejs的但是也是开了一个go语言的一个websocket)

  2. 魔改curl,最有名的就是curl-impersonate 对应win版本的 https://github.com/depler/curl-impersonate-win 缺点就是编译复杂,使用方式上,得用包装curl的第三方库,用的多就是python的pycurl 其他语言的比较少

正好五一有时间,站在巨人们的肩膀上我用go语言开发了一个代理服务.

只需要设置这个代理服务,就可以自定义ja3参数

这样任何语言都可以直接用了,而且只需要加一个webproxy即可

具体效果可以往下看

突破tls/ja3新轮子
image

解压后如上图,包含2个文件

  • ja3proxy.exe ja3proxy是go开发的一个控制台程序
  • localhost_root.pfx 本地证书

(测试加我要)

为了方便本机测试,先安装localhost_root.pfx证书, (如果不安装证书,也可以运行,只不过你需要将请求忽略ssl verify) 突破tls/ja3新轮子

证书密码为123456

突破tls/ja3新轮子
image

选择位置为:受信任的根证书颁发机构

突破tls/ja3新轮子
image

安装成功后,使用如下命令 运行ja3proxy.exe

 ja3proxy.exe -pfxFile=localhost_root.pfx -pfxPwd=123456
突破tls/ja3新轮子
image

支持的参数共有如下:

  • pfxFile (pfx类型证书)
  • pfxPwd (pfx证书的密码)
  • authName 如果你要开启ja3proxy代理服务的basicauth认证,可以设置
  • authPwd (同上)
  • httpPort (ja3proxy代理的http端口,默认为8080)
  • httpsPort (ja3proxy代理的https端口,默认为8443)
  • certFile 非pfx类型证书可以设置
  • keyFile 同上

ja3proxy运行成功后,测试代码如下:

  var proxy = new WebProxy {     // 这就是我们的ja3proxy  Address = new Uri($"http://localhost:8080") };  var httpClientHandler = new HttpClientHandler {  Proxy = proxy, };  // 因为我们再上面把证书添加到本机受信任了 所以这行代码不需要,如果你不操作受信任证书的话,就需要 //httpClientHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;   var client2 = new HttpClient(handler: httpClientHandler, disposeHandler: true);  // 设置ja3指纹 client2.DefaultRequestHeaders.Add("tls-ja3","771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,17513-10-18-11-51-13-27-0-35-65281-43-16-45-5-23-21,29-23-24,0"); // 设置ja3proxy执行请求的超时 client2.DefaultRequestHeaders.Add("tls-timeout","10"); // 设置ja3proxy执行请求用代理,设置后请求目标服务器拿到的就是代理ip // client2.DefaultRequestHeaders.Add("tls-proxy","http://252.45.26.333:5543");  // 设置当前请求的useragent client2.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36");   var result = await client2.GetStringAsync("https://kawayiyi.com/tls"); Console.WriteLine(result);

执行后,校验ja3一致

{   "sni": "kawayiyi.com",   "tlsVersion": "Tls13",   "tcpConnectionId": "0HMQ8N2PQCRQE",   "random": "AwN2jHvxe/TKafrfmZ1KG2JWrD7u6M1N4dpeIGdYQwA=",   "sessionId": "FvNiwCLizsA2JZt0/8865tX2A5VsfbgjlCu4Qg4jPjg=",   "tlsHashOrigin": "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,17513-10-18-11-51-13-27-0-35-65281-43-16-45-5-23-21,29-23-24,0",   "tlsHashMd5": "05556c7568c3d3a65c4e35d42f102d78",   "cipherList": [     "TLS_AES_128_GCM_SHA256",     "TLS_AES_256_GCM_SHA384",     "TLS_CHACHA20_POLY1305_SHA256",     "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",     "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",     "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",     "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",     "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",     "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",     "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",     "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",     "TLS_RSA_WITH_AES_128_GCM_SHA256",     "TLS_RSA_WITH_AES_256_GCM_SHA384",     "TLS_RSA_WITH_AES_128_CBC_SHA",     "TLS_RSA_WITH_AES_256_CBC_SHA"   ],   "extentions": [     "extensionApplicationSettings",     "supported_groups",     "signed_certificate_timestamp",     "ec_point_formats",     "key_share",     "signature_algorithms",     "compress_certificate",     "server_name",     "session_ticket",     "renegotiation_info",     "supported_versions",     "application_layer_protocol_negotiation",     "psk_key_exchange_modes",     "status_request",     "extended_master_secret",     "padding"   ],   "supportedgroups": [     "X25519",     "CurveP256",     "CurveP384"   ],   "ecPointFormats": [     "uncompressed"   ],   "proto": "HTTP/2",   "h2": {     "SETTINGS": {       "1": "65536",       "3": "1000",       "4": "6291456",       "5": "16384",       "6": "262144"     },     "WINDOW_UPDATE": "15663105",     "HEADERS": [       ":method",       ":authority",       ":scheme",       ":path"     ]   },   "user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36",   "clientIp": "103.219.192.197" }

nodejs测试

const request = require('request');  const options = {     url:'https://kawayiyi.com/tls',     method: 'GET',     headers: {         'tls-ja3':'771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,17513-10-18-11-51-13-27-0-35-65281-43-16-45-5-23-21,29-23-24,0',         'tls-timeout':'10',         'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36', // 设置请求头中的 User-Agent     },     proxy: 'http://localhost:8080',     strictSSL:false };  request.get(options, (error, response, body) => {     if (error) {         console.error(error);         return;     }     console.log('body:', body); });
突破tls/ja3新轮子
image

h2的header顺序:m,a,s,p 和chrome保持一致

原理

突破tls/ja3新轮子
image

ja3proxy(是一个中间人)接管你的请求,然后自己去目标建立tls,clienthello就用你指定的ja3参数

 

突破tls/ja3新轮子

发表评论

评论已关闭。

相关文章