3

突破tls/ja3新轮子 - 俞正东

 1 year ago
source link: https://www.cnblogs.com/yudongdong/p/17368353.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

突破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即可

具体效果可以往下看

image

image

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

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

(测试加我要)

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

image

证书密码为123456

image

image

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

image

image

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


ja3proxy.exe -pfxFile=localhost_root.pfx -pfxPwd=123456
image

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);
});
image

image

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

image

image

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

472365-20230502214142895-1165831798.png

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK