• 突破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, disposeHandlertrue);
    
    // 设置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参数

     

  • 相关阅读:
    opencv-python读写中文路径问题的解决
    【MySQL】内置函数——数学函数+其他函数
    脚手架cli快速创建Vue2/Vue3项目
    Linux内核镜像拷贝至树莓派并启动新内核
    项目经理如何全过程实时跟踪项目进度
    P3743 kotori的设备
    【用户登录】模块之登录认证+鉴权业务逻辑
    Helm安装Kafka集群(保姆级教程)
    buuctf刷题记录
    2.2 Pycharm 的使用
  • 原文地址:https://www.cnblogs.com/yudongdong/p/17368353.html