← Back to all posts
Security Development19 min read

Anti-Crawler SSL/TLS Fingerprinting and Bypassing the JA3 Algorithm

This article explains how WAFs use JA3 and JA3S to identify TLS fingerprints and explores two ways to modify Python Requests behavior to avoid being blocked.

#crawler#SSL#algorithm
Read in Chinese→

0x00 Introduction

Sometimes you may encounter a situation where a website is accessible through a normal browser, but accessing the HTTPS site with a script or through a proxy immediately results in a 405 response denying access.

This may happen because your TLS fingerprint has been identified. In this case, randomly changing the User-Agent is of little use.

image-20220208160912763

After researching the issue, I found that the WAF was likely identifying my TLS fingerprint, flagging it as malicious, and blocking it outright. The detection algorithms primarily use JA3 and JA3S to implement TLS fingerprinting, so I decided to learn more about them.

0x01 Practical Testing

Test Code

First, let’s examine our fingerprint and test whether modifying the headers works. The following test code mainly sends requests repeatedly so that we can inspect their fingerprints.

There are three main variants: modified TLS, the default implementation, and modified headers.

# author: Zeo
# python: 3.7 
# software: PyCharm

"""
文件说明:
"""
import requests
import random
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context

ORIGIN_CIPHERS = (
    'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES')


class DESAdapter(HTTPAdapter):
    def __init__(self, *args, **kwargs):
        # 在请求中重新启用 3DES 支持的 TransportAdapter
        CIPHERS = ORIGIN_CIPHERS.split(":")
        random.shuffle(CIPHERS)
        # print("1:", CIPHERS)
        CIPHERS = ":".join(CIPHERS)
        # print("2:", CIPHERS)
        self.COPHERS = CIPHERS + ":!aNULL:!eNULL:!MD5"
        super(DESAdapter, self).__init__(*args, **kwargs)

    # 在一般情况下,当我们实现一个子类的时候,__init__的第一行应该是super().__init__(*args, **kwargs),
    # 但是由于init_poolmanager和proxy_manager_for是复写了父类的两个方法,
    # 这两个方法是在执行super().__init__(*args, **kwargs)的时候就执行的。
    # 所以,我们随机设置 Cipher Suits 的时候,需要放在super().__init__(*args, **kwargs)的前面。
    def init_poolmanager(self, *args, **kwargs):
        context = create_urllib3_context(ciphers=self.COPHERS)
        kwargs["ssl_context"] = context
        return super(DESAdapter, self).init_poolmanager(*args, **kwargs)

    def proxy_manager_for(self, *args, **kwargs):
        context = create_urllib3_context(ciphers=self.COPHERS)
        kwargs["ssl_context"] = context


if __name__ == '__main__':
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.67'}
    s = requests.Session()
    s.headers.update(headers)

    print("修改TSL 加密算发")
    for _ in range(3):
        # 其中,s.mount的第一个参数表示这个适配器只在https://ja3er.com开头的网址中生效
        s.mount("https://ja3er.com", DESAdapter())
        response = s.get("https://ja3er.com/json").json()
        print(response)

    print("原生 requests.get")
    for _ in range(3):
        res = requests.get(url="https://ja3er.com/json").json()
        print(res)
    print("修改 hearder requests.get")
    for _ in range(3):
        SignHeaders = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36',
            'Accept': 'application/json, text/plain, */*',
            'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
            'Accept-Encoding': 'gzip, deflate',
            'Connection': 'close',
            'Referer': 'https://www.baidu.com/',
        }
        res = requests.get(url="https://ja3er.com/json", headers=SignHeaders).json()
        print(res)
```The test results are shown below:

![image-20220208110639399](/images/5370e45bb13ae5a426e41ab9dbd514ba.png)

- In other words, modifying header fields such as User-Agent, Referer, and others does not affect this fingerprint because it is calculated from TLS within SSL.
- When sending requests with Python’s Requests library, the `ja3_hash` always remains fixed.
- 8896468359a279a05de2651c5021ac6f
- Therefore, we can fingerprint client applications using details from the TLS Client Hello packet. By using this as a rule, we can directly block scripts using Python’s default implementation.

After searching online, I found that this detection algorithm is called `JA3算法`.

# 0x02 The JA3 Algorithm

JA3 is a method for identifying TLS client fingerprints online.

The JA3 algorithm collects information from SSL requests, including but not limited to the SSL/TLS version, the number of `Cipher Suites`, the list of browser extensions, `elliptic curves`, and so on.

![image-20220208143328727](/images/d7fb6b2bd57918bcd4f9fa42abba7b17.png)

These fields are ordered as follows:

TLSVersion, Ciphers, Extensions, EllipticCurves, EllipticCurvePointFormats

For example:```
771,4866-4867-4865-49196-49200-49195-49199-52393-52392-159-158-52394-49327-49325-49326-49324-49188-49192-49187-49191-49162-49172-49161-49171-49315-49311-49314-49310-107-103-57-51-157-156-49313-49309-49312-49308-61-60-53-47-255,0-11-10-16-22-23-49-13-43-45-51-21,29-23-1035-25-24,0-1-2

If the Client Hello packet contains no TLS extensions, the values of these fields are left empty.

The MD5 hash of the resulting string is then calculated to generate an easy-to-use and easy-to-share 32-character fingerprint. This is the JA3 TLS client fingerprint.

ja3_hash = 8896468359a279a05de2651c5021ac6f

Because each client consistently generates the same result, its JA3 fingerprint is unique.

0x03 Packet Capture with Wireshark

A normal browser can access https://ja3er.com/json to view its own JA3 hash. You can see that each browser has a different one.

image-20220208111214685

Below are specific Wireshark packet captures for examining the details.

Chrome

Transport Layer Security
    TLSv1.2 Record Layer: Handshake Protocol: Client Hello
        Content Type: Handshake (22)
        Version: TLS 1.0 (0x0301)
        Length: 512
        Handshake Protocol: Client Hello
            Handshake Type: Client Hello (1)
            Length: 508
            Version: TLS 1.2 (0x0303)
            Random: eec68fa63c113f8ce38c2eb99a7731f47240f96a42e96f11148abcc2aefc1593
                GMT Unix Time: Dec 10, 2096 23:05:10.000000000 CST
                Random Bytes: 3c113f8ce38c2eb99a7731f47240f96a42e96f11148abcc2aefc1593
            Session ID Length: 32
            Session ID: acfa18829ca99b15a5aeed76ac5179f390ce296e9d7d8b426bf5b5a262014a58
            Cipher Suites Length: 32
            Cipher Suites (16 suites)
                Cipher Suite: Reserved (GREASE) (0xdada)
                Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)
                Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)
                Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 (0x1303)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
                Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
                Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
                Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
                Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
                Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
            Compression Methods Length: 1
            Compression Methods (1 method)
                Compression Method: null (0)
            Extensions Length: 403
            Extension: Reserved (GREASE) (len=0)
                Type: Reserved (GREASE) (47802)
                Length: 0
                Data: <MISSING>
            Extension: server_name (len=14)
                Type: server_name (0)
                Length: 14
                Server Name Indication extension
                    Server Name list length: 12
                    Server Name Type: host_name (0)
                    Server Name length: 9
                    Server Name: ja3er.com
            Extension: extended_master_secret (len=0)
                Type: extended_master_secret (23)
                Length: 0
            Extension: renegotiation_info (len=1)
                Type: renegotiation_info (65281)
                Length: 1
                Renegotiation Info extension
                    Renegotiation info extension length: 0
            Extension: supported_groups (len=10)
                Type: supported_groups (10)
                Length: 10
                Supported Groups List Length: 8
                Supported Groups (4 groups)
                    Supported Group: Reserved (GREASE) (0xdada)
                    Supported Group: x25519 (0x001d)
                    Supported Group: secp256r1 (0x0017)
                    Supported Group: secp384r1 (0x0018)
            Extension: ec_point_formats (len=2)
                Type: ec_point_formats (11)
                Length: 2
                EC point formats Length: 1
                Elliptic curves point formats (1)
                    EC point format: uncompressed (0)
            Extension: session_ticket (len=0)
                Type: session_ticket (35)
                Length: 0
                Data (0 bytes)
            Extension: application_layer_protocol_negotiation (len=14)
                Type: application_layer_protocol_negotiation (16)
                Length: 14
                ALPN Extension Length: 12
                ALPN Protocol
                    ALPN string length: 2
                    ALPN Next Protocol: h2
                    ALPN string length: 8
                    ALPN Next Protocol: http/1.1
            Extension: status_request (len=5)
                Type: status_request (5)
                Length: 5
                Certificate Status Type: OCSP (1)
                Responder ID list Length: 0
                Request Extensions Length: 0
            Extension: signature_algorithms (len=18)
                Type: signature_algorithms (13)
                Length: 18
                Signature Hash Algorithms Length: 16
                Signature Hash Algorithms (8 algorithms)
                    Signature Algorithm: ecdsa_secp256r1_sha256 (0x0403)
                        Signature Hash Algorithm Hash: SHA256 (4)
                        Signature Hash Algorithm Signature: ECDSA (3)
                    Signature Algorithm: rsa_pss_rsae_sha256 (0x0804)
                        Signature Hash Algorithm Hash: Unknown (8)
                        Signature Hash Algorithm Signature: SM2 (4)
                    Signature Algorithm: rsa_pkcs1_sha256 (0x0401)
                        Signature Hash Algorithm Hash: SHA256 (4)
                        Signature Hash Algorithm Signature: RSA (1)
                    Signature Algorithm: ecdsa_secp384r1_sha384 (0x0503)
                        Signature Hash Algorithm Hash: SHA384 (5)
                        Signature Hash Algorithm Signature: ECDSA (3)
                    Signature Algorithm: rsa_pss_rsae_sha384 (0x0805)
                        Signature Hash Algorithm Hash: Unknown (8)
                        Signature Hash Algorithm Signature: Unknown (5)
                    Signature Algorithm: rsa_pkcs1_sha384 (0x0501)
                        Signature Hash Algorithm Hash: SHA384 (5)
                        Signature Hash Algorithm Signature: RSA (1)
                    Signature Algorithm: rsa_pss_rsae_sha512 (0x0806)
                        Signature Hash Algorithm Hash: Unknown (8)
                        Signature Hash Algorithm Signature: Unknown (6)
                    Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
                        Signature Hash Algorithm Hash: SHA512 (6)
                        Signature Hash Algorithm Signature: RSA (1)
            Extension: signed_certificate_timestamp (len=0)
                Type: signed_certificate_timestamp (18)
                Length: 0
            Extension: key_share (len=43)
                Type: key_share (51)
                Length: 43
                Key Share extension
                    Client Key Share Length: 41
                    Key Share Entry: Group: Reserved (GREASE), Key Exchange length: 1
                        Group: Reserved (GREASE) (56026)
                        Key Exchange Length: 1
                        Key Exchange: 00
                    Key Share Entry: Group: x25519, Key Exchange length: 32
                        Group: x25519 (29)
                        Key Exchange Length: 32
                        Key Exchange: aa67c165af9f638e61122b18e646e664d62f0ea0f4cc82736528b0b1d1122c76
            Extension: psk_key_exchange_modes (len=2)
                Type: psk_key_exchange_modes (45)
                Length: 2
                PSK Key Exchange Modes Length: 1
                PSK Key Exchange Mode: PSK with (EC)DHE key establishment (psk_dhe_ke) (1)
            Extension: supported_versions (len=11)
                Type: supported_versions (43)
                Length: 11
                Supported Versions length: 10
                Supported Version: Reserved (GREASE) (0xfafa)
                Supported Version: TLS 1.3 (0x0304)
                Supported Version: TLS 1.2 (0x0303)
                Supported Version: TLS 1.1 (0x0302)
                Supported Version: TLS 1.0 (0x0301)
            Extension: compress_certificate (len=3)
                Type: compress_certificate (27)
                Length: 3
                Algorithms Length: 2
                Algorithm: brotli (2)
            Extension: application_settings (len=5)
                Type: application_settings (17513)
                Length: 5
                ALPS Extension Length: 3
                Supported ALPN List
                    Supported ALPN Length: 2
                    Supported ALPN: h2
            Extension: Reserved (GREASE) (len=1)
                Type: Reserved (GREASE) (35466)
                Length: 1
                Data: 00
            Extension: padding (len=202)
                Type: padding (21)
                Length: 202
                Padding Data: 000000000000000000000000000000000000000000000000000000000000000000000000…

Python Requests Library

Transport Layer Security
    TLSv1.2 Record Layer: Handshake Protocol: Client Hello
        Content Type: Handshake (22)
        Version: TLS 1.0 (0x0301)
        Length: 512
        Handshake Protocol: Client Hello
            Handshake Type: Client Hello (1)
            Length: 508
            Version: TLS 1.2 (0x0303)
            Random: 084798dbb21089e33b2654ccf48fa618a69a0a24d332e28bc63b3179423e9c9c
                GMT Unix Time: May 28, 1974 02:05:15.000000000 CST
                Random Bytes: b21089e33b2654ccf48fa618a69a0a24d332e28bc63b3179423e9c9c
            Session ID Length: 32
            Session ID: 72282eef35a39d03f55111dcbda2f2175bbf746ec8d9cd11aa70505104b18450
            Cipher Suites Length: 86
            Cipher Suites (43 suites)
                Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)
                Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 (0x1303)
                Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
                Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)
                Cipher Suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x009f)
                Cipher Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009e)
                Cipher Suite: TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xccaa)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 (0xc0af)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CCM (0xc0ad)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 (0xc0ae)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CCM (0xc0ac)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
                Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
                Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CCM_8 (0xc0a3)
                Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CCM (0xc09f)
                Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CCM_8 (0xc0a2)
                Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CCM (0xc09e)
                Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (0x006b)
                Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (0x0067)
                Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039)
                Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)
                Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
                Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
                Cipher Suite: TLS_RSA_WITH_AES_256_CCM_8 (0xc0a1)
                Cipher Suite: TLS_RSA_WITH_AES_256_CCM (0xc09d)
                Cipher Suite: TLS_RSA_WITH_AES_128_CCM_8 (0xc0a0)
                Cipher Suite: TLS_RSA_WITH_AES_128_CCM (0xc09c)
                Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d)
                Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)
                Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
                Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
                Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)
            Compression Methods Length: 1
            Compression Methods (1 method)
                Compression Method: null (0)
            Extensions Length: 349
            Extension: server_name (len=14)
                Type: server_name (0)
                Length: 14
                Server Name Indication extension
                    Server Name list length: 12
                    Server Name Type: host_name (0)
                    Server Name length: 9
                    Server Name: ja3er.com
            Extension: ec_point_formats (len=4)
                Type: ec_point_formats (11)
                Length: 4
                EC point formats Length: 3
                Elliptic curves point formats (3)
                    EC point format: uncompressed (0)
                    EC point format: ansiX962_compressed_prime (1)
                    EC point format: ansiX962_compressed_char2 (2)
            Extension: supported_groups (len=12)
                Type: supported_groups (10)
                Length: 12
                Supported Groups List Length: 10
                Supported Groups (5 groups)
                    Supported Group: x25519 (0x001d)
                    Supported Group: secp256r1 (0x0017)
                    Supported Group: x448 (0x001e)
                    Supported Group: secp521r1 (0x0019)
                    Supported Group: secp384r1 (0x0018)
            Extension: application_layer_protocol_negotiation (len=11)
                Type: application_layer_protocol_negotiation (16)
                Length: 11
                ALPN Extension Length: 9
                ALPN Protocol
                    ALPN string length: 8
                    ALPN Next Protocol: http/1.1
            Extension: encrypt_then_mac (len=0)
                Type: encrypt_then_mac (22)
                Length: 0
            Extension: extended_master_secret (len=0)
                Type: extended_master_secret (23)
                Length: 0
            Extension: post_handshake_auth (len=0)
                Type: post_handshake_auth (49)
                Length: 0
            Extension: signature_algorithms (len=48)
                Type: signature_algorithms (13)
                Length: 48
                Signature Hash Algorithms Length: 46
                Signature Hash Algorithms (23 algorithms)
                    Signature Algorithm: ecdsa_secp256r1_sha256 (0x0403)
                        Signature Hash Algorithm Hash: SHA256 (4)
                        Signature Hash Algorithm Signature: ECDSA (3)
                    Signature Algorithm: ecdsa_secp384r1_sha384 (0x0503)
                        Signature Hash Algorithm Hash: SHA384 (5)
                        Signature Hash Algorithm Signature: ECDSA (3)
                    Signature Algorithm: ecdsa_secp521r1_sha512 (0x0603)
                        Signature Hash Algorithm Hash: SHA512 (6)
                        Signature Hash Algorithm Signature: ECDSA (3)
                    Signature Algorithm: ed25519 (0x0807)
                        Signature Hash Algorithm Hash: Unknown (8)
                        Signature Hash Algorithm Signature: Unknown (7)
                    Signature Algorithm: ed448 (0x0808)
                        Signature Hash Algorithm Hash: Unknown (8)
                        Signature Hash Algorithm Signature: Unknown (8)
                    Signature Algorithm: rsa_pss_pss_sha256 (0x0809)
                        Signature Hash Algorithm Hash: Unknown (8)
                        Signature Hash Algorithm Signature: Unknown (9)
                    Signature Algorithm: rsa_pss_pss_sha384 (0x080a)
                        Signature Hash Algorithm Hash: Unknown (8)
                        Signature Hash Algorithm Signature: Unknown (10)
                    Signature Algorithm: rsa_pss_pss_sha512 (0x080b)
                        Signature Hash Algorithm Hash: Unknown (8)
                        Signature Hash Algorithm Signature: Unknown (11)
                    Signature Algorithm: rsa_pss_rsae_sha256 (0x0804)
                        Signature Hash Algorithm Hash: Unknown (8)
                        Signature Hash Algorithm Signature: SM2 (4)
                    Signature Algorithm: rsa_pss_rsae_sha384 (0x0805)
                        Signature Hash Algorithm Hash: Unknown (8)
                        Signature Hash Algorithm Signature: Unknown (5)
                    Signature Algorithm: rsa_pss_rsae_sha512 (0x0806)
                        Signature Hash Algorithm Hash: Unknown (8)
                        Signature Hash Algorithm Signature: Unknown (6)
                    Signature Algorithm: rsa_pkcs1_sha256 (0x0401)
                        Signature Hash Algorithm Hash: SHA256 (4)
                        Signature Hash Algorithm Signature: RSA (1)
                    Signature Algorithm: rsa_pkcs1_sha384 (0x0501)
                        Signature Hash Algorithm Hash: SHA384 (5)
                        Signature Hash Algorithm Signature: RSA (1)
                    Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
                        Signature Hash Algorithm Hash: SHA512 (6)
                        Signature Hash Algorithm Signature: RSA (1)
                    Signature Algorithm: SHA224 ECDSA (0x0303)
                        Signature Hash Algorithm Hash: SHA224 (3)
                        Signature Hash Algorithm Signature: ECDSA (3)
                    Signature Algorithm: ecdsa_sha1 (0x0203)
                        Signature Hash Algorithm Hash: SHA1 (2)
                        Signature Hash Algorithm Signature: ECDSA (3)
                    Signature Algorithm: SHA224 RSA (0x0301)
                        Signature Hash Algorithm Hash: SHA224 (3)
                        Signature Hash Algorithm Signature: RSA (1)
                    Signature Algorithm: rsa_pkcs1_sha1 (0x0201)
                        Signature Hash Algorithm Hash: SHA1 (2)
                        Signature Hash Algorithm Signature: RSA (1)
                    Signature Algorithm: SHA224 DSA (0x0302)
                        Signature Hash Algorithm Hash: SHA224 (3)
                        Signature Hash Algorithm Signature: DSA (2)
                    Signature Algorithm: SHA1 DSA (0x0202)
                        Signature Hash Algorithm Hash: SHA1 (2)
                        Signature Hash Algorithm Signature: DSA (2)
                    Signature Algorithm: SHA256 DSA (0x0402)
                        Signature Hash Algorithm Hash: SHA256 (4)
                        Signature Hash Algorithm Signature: DSA (2)
                    Signature Algorithm: SHA384 DSA (0x0502)
                        Signature Hash Algorithm Hash: SHA384 (5)
                        Signature Hash Algorithm Signature: DSA (2)
                    Signature Algorithm: SHA512 DSA (0x0602)
                        Signature Hash Algorithm Hash: SHA512 (6)
                        Signature Hash Algorithm Signature: DSA (2)
            Extension: supported_versions (len=9)
                Type: supported_versions (43)
                Length: 9
                Supported Versions length: 8
                Supported Version: TLS 1.3 (0x0304)
                Supported Version: TLS 1.2 (0x0303)
                Supported Version: TLS 1.1 (0x0302)
                Supported Version: TLS 1.0 (0x0301)
            Extension: psk_key_exchange_modes (len=2)
                Type: psk_key_exchange_modes (45)
                Length: 2
                PSK Key Exchange Modes Length: 1
                PSK Key Exchange Mode: PSK with (EC)DHE key establishment (psk_dhe_ke) (1)
            Extension: key_share (len=38)
                Type: key_share (51)
                Length: 38
                Key Share extension
                    Client Key Share Length: 36
                    Key Share Entry: Group: x25519, Key Exchange length: 32
                        Group: x25519 (29)
                        Key Exchange Length: 32
                        Key Exchange: 3fc6f2011e3b8c3d6a5728886dda249793d98739b968a6b14c70ae4929a4ee4a
            Extension: padding (len=163)
                Type: padding (21)
                Length: 163
                Padding Data: 000000000000000000000000000000000000000000000000000000000000000000000000…

Burp

TLSv1.2 Record Layer: Handshake Protocol: Client Hello
    Content Type: Handshake (22)
    Version: TLS 1.2 (0x0303)
    Length: 707
    Handshake Protocol: Client Hello
        Handshake Type: Client Hello (1)
        Length: 703
        Version: TLS 1.2 (0x0303)
        Random: 9c9c8d20358ad1f04427cb7f47b87a05cc7df36e9f8620e34189c7d9d7c4c394
            GMT Unix Time: Apr  6, 2053 06:37:20.000000000 CST
            Random Bytes: 358ad1f04427cb7f47b87a05cc7df36e9f8620e34189c7d9d7c4c394
        Session ID Length: 32
        Session ID: 936def16329bcf32ee79aec0d9df57df057fabef59bebe3c2fad454c8ae5956f
        Cipher Suites Length: 112
        Cipher Suites (56 suites)
            Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)
            Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)
            Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 (0x1303)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
            Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
            Cipher Suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x009f)
            Cipher Suite: TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xccaa)
            Cipher Suite: TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 (0x00a3)
            Cipher Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009e)
            Cipher Suite: TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 (0x00a2)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)
            Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (0x006b)
            Cipher Suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 (0x006a)
            Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (0x0067)
            Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 (0x0040)
            Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02e)
            Cipher Suite: TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 (0xc032)
            Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02d)
            Cipher Suite: TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 (0xc031)
            Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 (0xc026)
            Cipher Suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 (0xc02a)
            Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 (0xc025)
            Cipher Suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 (0xc029)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
            Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039)
            Cipher Suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA (0x0038)
            Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)
            Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA (0x0032)
            Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA (0xc005)
            Cipher Suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA (0xc00f)
            Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA (0xc004)
            Cipher Suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA (0xc00e)
            Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
            Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
            Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d)
            Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)
            Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
            Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc008)
            Cipher Suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (0xc012)
            Cipher Suite: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (0x0016)
            Cipher Suite: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA (0x0013)
            Cipher Suite: TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc003)
            Cipher Suite: TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA (0xc00d)
            Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)
            Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)
        Compression Methods Length: 1
        Compression Methods (1 method)
            Compression Method: null (0)
        Extensions Length: 518
        Extension: server_name (len=14)
            Type: server_name (0)
            Length: 14
            Server Name Indication extension
                Server Name list length: 12
                Server Name Type: host_name (0)
                Server Name length: 9
                Server Name: ja3er.com
        Extension: status_request (len=5)
            Type: status_request (5)
            Length: 5
            Certificate Status Type: OCSP (1)
            Responder ID list Length: 0
            Request Extensions Length: 0
        Extension: supported_groups (len=22)
            Type: supported_groups (10)
            Length: 22
            Supported Groups List Length: 20
            Supported Groups (10 groups)
                Supported Group: x25519 (0x001d)
                Supported Group: secp256r1 (0x0017)
                Supported Group: secp384r1 (0x0018)
                Supported Group: secp521r1 (0x0019)
                Supported Group: x448 (0x001e)
                Supported Group: ffdhe2048 (0x0100)
                Supported Group: ffdhe3072 (0x0101)
                Supported Group: ffdhe4096 (0x0102)
                Supported Group: ffdhe6144 (0x0103)
                Supported Group: ffdhe8192 (0x0104)
        Extension: ec_point_formats (len=2)
            Type: ec_point_formats (11)
            Length: 2
            EC point formats Length: 1
            Elliptic curves point formats (1)
                EC point format: uncompressed (0)
        Extension: signature_algorithms (len=46)
            Type: signature_algorithms (13)
            Length: 46
            Signature Hash Algorithms Length: 44
            Signature Hash Algorithms (22 algorithms)
                Signature Algorithm: ecdsa_secp256r1_sha256 (0x0403)
                    Signature Hash Algorithm Hash: SHA256 (4)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Algorithm: ecdsa_secp384r1_sha384 (0x0503)
                    Signature Hash Algorithm Hash: SHA384 (5)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Algorithm: ecdsa_secp521r1_sha512 (0x0603)
                    Signature Hash Algorithm Hash: SHA512 (6)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Algorithm: ed25519 (0x0807)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (7)
                Signature Algorithm: ed448 (0x0808)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (8)
                Signature Algorithm: rsa_pss_rsae_sha256 (0x0804)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: SM2 (4)
                Signature Algorithm: rsa_pss_rsae_sha384 (0x0805)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (5)
                Signature Algorithm: rsa_pss_rsae_sha512 (0x0806)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (6)
                Signature Algorithm: rsa_pss_pss_sha256 (0x0809)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (9)
                Signature Algorithm: rsa_pss_pss_sha384 (0x080a)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (10)
                Signature Algorithm: rsa_pss_pss_sha512 (0x080b)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (11)
                Signature Algorithm: rsa_pkcs1_sha256 (0x0401)
                    Signature Hash Algorithm Hash: SHA256 (4)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Algorithm: rsa_pkcs1_sha384 (0x0501)
                    Signature Hash Algorithm Hash: SHA384 (5)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
                    Signature Hash Algorithm Hash: SHA512 (6)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Algorithm: SHA256 DSA (0x0402)
                    Signature Hash Algorithm Hash: SHA256 (4)
                    Signature Hash Algorithm Signature: DSA (2)
                Signature Algorithm: SHA224 ECDSA (0x0303)
                    Signature Hash Algorithm Hash: SHA224 (3)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Algorithm: SHA224 RSA (0x0301)
                    Signature Hash Algorithm Hash: SHA224 (3)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Algorithm: SHA224 DSA (0x0302)
                    Signature Hash Algorithm Hash: SHA224 (3)
                    Signature Hash Algorithm Signature: DSA (2)
                Signature Algorithm: ecdsa_sha1 (0x0203)
                    Signature Hash Algorithm Hash: SHA1 (2)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Algorithm: rsa_pkcs1_sha1 (0x0201)
                    Signature Hash Algorithm Hash: SHA1 (2)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Algorithm: SHA1 DSA (0x0202)
                    Signature Hash Algorithm Hash: SHA1 (2)
                    Signature Hash Algorithm Signature: DSA (2)
                Signature Algorithm: MD5 RSA (0x0101)
                    Signature Hash Algorithm Hash: MD5 (1)
                    Signature Hash Algorithm Signature: RSA (1)
        Extension: signature_algorithms_cert (len=46)
            Type: signature_algorithms_cert (50)
            Length: 46
            Signature Hash Algorithms Length: 44
            Signature Hash Algorithms (22 algorithms)
                Signature Algorithm: ecdsa_secp256r1_sha256 (0x0403)
                    Signature Hash Algorithm Hash: SHA256 (4)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Algorithm: ecdsa_secp384r1_sha384 (0x0503)
                    Signature Hash Algorithm Hash: SHA384 (5)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Algorithm: ecdsa_secp521r1_sha512 (0x0603)
                    Signature Hash Algorithm Hash: SHA512 (6)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Algorithm: ed25519 (0x0807)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (7)
                Signature Algorithm: ed448 (0x0808)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (8)
                Signature Algorithm: rsa_pss_rsae_sha256 (0x0804)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: SM2 (4)
                Signature Algorithm: rsa_pss_rsae_sha384 (0x0805)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (5)
                Signature Algorithm: rsa_pss_rsae_sha512 (0x0806)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (6)
                Signature Algorithm: rsa_pss_pss_sha256 (0x0809)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (9)
                Signature Algorithm: rsa_pss_pss_sha384 (0x080a)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (10)
                Signature Algorithm: rsa_pss_pss_sha512 (0x080b)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (11)
                Signature Algorithm: rsa_pkcs1_sha256 (0x0401)
                    Signature Hash Algorithm Hash: SHA256 (4)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Algorithm: rsa_pkcs1_sha384 (0x0501)
                    Signature Hash Algorithm Hash: SHA384 (5)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
                    Signature Hash Algorithm Hash: SHA512 (6)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Algorithm: SHA256 DSA (0x0402)
                    Signature Hash Algorithm Hash: SHA256 (4)
                    Signature Hash Algorithm Signature: DSA (2)
                Signature Algorithm: SHA224 ECDSA (0x0303)
                    Signature Hash Algorithm Hash: SHA224 (3)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Algorithm: SHA224 RSA (0x0301)
                    Signature Hash Algorithm Hash: SHA224 (3)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Algorithm: SHA224 DSA (0x0302)
                    Signature Hash Algorithm Hash: SHA224 (3)
                    Signature Hash Algorithm Signature: DSA (2)
                Signature Algorithm: ecdsa_sha1 (0x0203)
                    Signature Hash Algorithm Hash: SHA1 (2)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Algorithm: rsa_pkcs1_sha1 (0x0201)
                    Signature Hash Algorithm Hash: SHA1 (2)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Algorithm: SHA1 DSA (0x0202)
                    Signature Hash Algorithm Hash: SHA1 (2)
                    Signature Hash Algorithm Signature: DSA (2)
                Signature Algorithm: MD5 RSA (0x0101)
                    Signature Hash Algorithm Hash: MD5 (1)
                    Signature Hash Algorithm Signature: RSA (1)
        Extension: status_request_v2 (len=9)
            Type: status_request_v2 (17)
            Length: 9
            Certificate Status List Length: 7
            Certificate Status Type: OCSP Multi (2)
            Certificate Status Length: 4
            Responder ID list Length: 0
            Request Extensions Length: 0
        Extension: extended_master_secret (len=0)
            Type: extended_master_secret (23)
            Length: 0
        Extension: session_ticket (len=208)
            Type: session_ticket (35)
            Length: 208
            Data (208 bytes)
        Extension: supported_versions (len=9)
            Type: supported_versions (43)
            Length: 9
            Supported Versions length: 8
            Supported Version: TLS 1.3 (0x0304)
            Supported Version: TLS 1.2 (0x0303)
            Supported Version: TLS 1.1 (0x0302)
            Supported Version: TLS 1.0 (0x0301)
        Extension: psk_key_exchange_modes (len=2)
            Type: psk_key_exchange_modes (45)
            Length: 2
            PSK Key Exchange Modes Length: 1
            PSK Key Exchange Mode: PSK with (EC)DHE key establishment (psk_dhe_ke) (1)
        Extension: key_share (len=107)
            Type: key_share (51)
            Length: 107
            Key Share extension
                Client Key Share Length: 105
                Key Share Entry: Group: x25519, Key Exchange length: 32
                    Group: x25519 (29)
                    Key Exchange Length: 32
                    Key Exchange: c8bec5524c23aeec01f4dc54f4f66d98f324033d7cb49bd962d43b3c80e93932
                Key Share Entry: Group: secp256r1, Key Exchange length: 65
                    Group: secp256r1 (23)
                    Key Exchange Length: 65
                    Key Exchange: 045596de0177e5db84f608492167e250e795cb511fb8f107487f6ba58964b211c71d014b…

Comparison

The Cipher Suites differ significantly.

image-20220208141211573

0x04 Solving the Problem

As a script kiddie, of course I have to bypass this; otherwise, I won’t be able to get anything done in the future. For now, I have found two methods:

  • Modify the logic of your own code
  • Directly modify the underlying dependency package

Method 1: Modify the Application-Level Code

This code is based on an example I found online. You can modify it as needed.

import random
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context

ORIGIN_CIPHERS = (
    'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM'
    ':RSA+AES:RSA+HIGH:RSA+3DES')


class DESAdapter(HTTPAdapter):
    def __init__(self, *args, **kwargs):
        # 在请求中重新启用 3DES 支持的 TransportAdapter
        CIPHERS = ORIGIN_CIPHERS.split(":")
        random.shuffle(CIPHERS)
        # print("1:", CIPHERS)
        CIPHERS = ":".join(CIPHERS)
        # print("2:", CIPHERS)
        self.COPHERS = CIPHERS + ":!aNULL:!eNULL:!MD5"
        super(DESAdapter, self).__init__(*args, **kwargs)

    # 在一般情况下,当我们实现一个子类的时候,__init__的第一行应该是super().__init__(*args, **kwargs),
    # 但是由于init_poolmanager和proxy_manager_for是复写了父类的两个方法,
    # 这两个方法是在执行super().__init__(*args, **kwargs)的时候就执行的。
    # 所以,我们随机设置 Cipher Suits 的时候,需要放在super().__init__(*args, **kwargs)的前面。
    def init_poolmanager(self, *args, **kwargs):
        context = create_urllib3_context(ciphers=self.COPHERS)
        kwargs["ssl_context"] = context
        return super(DESAdapter, self).init_poolmanager(*args, **kwargs)

    def proxy_manager_for(self, *args, **kwargs):
        context = create_urllib3_context(ciphers=self.COPHERS)
        kwargs["ssl_context"] = context


if __name__ == '__main__':
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.67'}
    s = requests.Session()
    s.headers.update(headers)

    print("修改TSL 加密算发")
    for _ in range(3):
        # 其中,s.mount的第一个参数表示这个适配器只在https://ja3er.com开头的网址中生效
        s.mount("https://ja3er.com", DESAdapter())
        response = s.get("https://ja3er.com/json").json()
        print(response)

Method 2: Modify the Underlying Requests Dependency

There is another problem: once you have written a lot of code, you cannot realistically modify every script individually. That would be exhausting. Unless you encapsulated the packet-sending function beforehand so that you only need to change it once, the best approach is to modify the underlying dependency package directly.

Requests is actually a wrapper around urllib3, so the key lies in the urllib library.

Debugging reveals the following location:

/usr/local/lib/python3.7/site-packages/urllib3/util/ssl_.py

image-20220208144845875

This is the original cipher suite list.

image-20220208145318097

According to the underlying principle, the fields are first processed in order and then hashed.

ja3': '771,4866-4867-4865-52394-49196-49200-49195-49199-159-158-52393-52

Therefore, to minimize changes and avoid affecting the code, we only need to rearrange the order of the encryption algorithms in Ciphers.

image-20220208145944869

Test Again with the Code

image-20220208154450669

修改前:
8896468359a279a05de2651c5021ac6f
修改后:
ab2825e283c7103e84b2c96ea54e41e3

0x05 Summary

There are actually many other methods based on these rules. As long as you are familiar with the protocol and understand the underlying principles, you can modify things gradually. Since I do not understand it that deeply, I chose the simplest method that works. If it gets too complicated, I am afraid I will only confuse myself.

This article only modifies the Python code, but the same principle applies to other languages.