Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The library doesn't actually change ja3. #133

Open
svorasobak666 opened this issue Dec 25, 2024 · 6 comments
Open

The library doesn't actually change ja3. #133

svorasobak666 opened this issue Dec 25, 2024 · 6 comments

Comments

@svorasobak666
Copy link

svorasobak666 commented Dec 25, 2024

Hello everyone, sorry for the bad English.
I use this library to substitute ja3, I use a special site to test it. Using wireshark I saved several different ja3 fingerprints sent through different windows applications. By sending requests using the ja3_string= parameter I send different ja3, but the site detects them as the same. Below is a code sample, when executed we will see that whatever ja3_string we send, they will still be the same.

Translated with DeepL.com (free version)

`
import tls_client

ja3_list = ["771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0",
"771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,11-65281-18-27-5-13-51-65037-23-45-10-17513-35-0-43-16,4588-29-23-24,0",
"771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,5-43-18-13-51-17513-65281-35-0-65037-10-27-16-11-45-23,25497-29-23-24,0",
"771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,27-65281-43-17513-5-35-65037-51-18-45-11-13-0-10-16-23-41,25497-29-23-24,0",
"771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,45-5-18-51-43-65037-16-13-0-17513-23-11-27-35-10-65281-41,25497-29-23-24,0"]

for ja3_str in ja3_list:
session = tls_client.Session(
client_identifier="chrome_120",
ja3_string=ja3_str,
)
a = session.get('https://check.ja3.zone/')
ja3 = a.json()['fingerprint']
print(ja3)
`

@dream2333
Copy link

same issue

@Luna5829
Copy link

Luna5829 commented Jan 11, 2025

the "solution" is to put the argument random_tls_extension_order=True in tls_client.Session, which randomizes that
only other solution would be to literally edit the dll that it uses which is inside of the dependencies folder in the Lib/site-packages/tls_client/ python directory

@svorasobak666
Copy link
Author

svorasobak666 commented Jan 11, 2025 via email

@mheguy
Copy link

mheguy commented Jan 16, 2025

I took a quick look at the code: ja3_string is only used when client_identifier is None.

Image

That's why you're getting the same JA3.

@scarletrycca123
Copy link

I took a quick look at the code: ja3_string is only used when client_identifier is None.

Image

That's why you're getting the same JA3.

but if i set client_identifier to None i have this error
"```
attention our ja3 defines ExtensionCompressCertificate but you did not specify certCompression
attention our ja3 defines ExtensionCompressCertificate but you did not specify certCompression
Traceback (most recent call last):
File "c:\Users\wavvy\Desktop\test_tls.py", line 10, in
a = session.get('https://check.ja3.zone/')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\wavvy\AppData\Local\Programs\Python\Python311\Lib\site-packages\tls_client\sessions.py", line 459, in get
return self.execute_request(method="GET", url=url, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\wavvy\AppData\Local\Programs\Python\Python311\Lib\site-packages\tls_client\sessions.py", line 442, in execute_request
raise TLSClientExeption(response_object["body"])
tls_client.exceptions.TLSClientExeption: failed to do request: Get "https://check.ja3.zone/": tls: unknown ClientHelloID: Custom-1



my code
"

import tls_client

ja3_list = ["771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,17513-35-11-23-65281-45-0-5-16-27-65037-51-10-18-43-13,4588-29-23-24,0",]

for ja3_str in ja3_list:
session = tls_client.Session(
client_identifier=None,
ja3_string=ja3_str,
)
a = session.get('https://check.ja3.zone/')
ja3 = a.json()['fingerprint']
print(ja3)

"

@mheguy
Copy link

mheguy commented Jan 17, 2025

For this issue:
attention our ja3 defines ExtensionCompressCertificate but you did not specify certCompression
Remember that your JA3 and the other values you provide need to match.
If your JA3 says that you support a given cert compression, you need to provide the cert compression algo as input.

For this issue:
tls_client.exceptions.TLSClientExeption: failed to do request: Get "https://check.ja3.zone/": tls: unknown ClientHelloID: Custom-1
I ran into it as well and was unable to resolve it.

Here is a link the Go library, it provides a working example with a custom client: https://github.com/bogdanfinn/tls-client/blob/master/cffi_dist/example_python/example_custom_client.py
On L5, change the path as required.
On L97, you have the URL that the request is being sent to.

Below is some code I put together to demonstrate what seem to be issues in the Go library itself.

Code ``` # region config RELATIVE_PATH_TO_LIBRARY = ".venv/Lib/site-packages/tls_client/dependencies/tls-client-64.dll"

CUSTOM_TLS_CLIENT = {
"ja3String": "771,2570-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,2570-0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-2570-21,2570-29-23-24,0",
"h2Settings": {
"HEADER_TABLE_SIZE": 65536,
"MAX_CONCURRENT_STREAMS": 1000,
"INITIAL_WINDOW_SIZE": 6291456,
"MAX_HEADER_LIST_SIZE": 262144,
},
"h2SettingsOrder": [
"HEADER_TABLE_SIZE",
"MAX_CONCURRENT_STREAMS",
"INITIAL_WINDOW_SIZE",
"MAX_HEADER_LIST_SIZE",
],
"supportedSignatureAlgorithms": [
"ECDSAWithP256AndSHA256",
"PSSWithSHA256",
"PKCS1WithSHA256",
"ECDSAWithP384AndSHA384",
"PSSWithSHA384",
"PKCS1WithSHA384",
"PSSWithSHA512",
"PKCS1WithSHA512",
],
"supportedVersions": ["GREASE", "1.3", "1.2"],
"keyShareCurves": ["GREASE", "X25519"],
"certCompressionAlgo": "brotli",
"alpnProtocols": ["h2", "http/1.1"],
"alpsProtocols": ["h2"],
"pseudoHeaderOrder": [":method", ":authority", ":scheme", ":path"],
"connectionFlow": 15663105,
"priorityFrames": [],
"headerPriority": None,
}

URLS = [
"https://microsoft.com",
"https://example.com",
"https://google.com",
"https://scrapfly.io",
"https://browserleaks.com",
"https://tls.browserleaks.com",
]

endregion

region example logic

def main():
"""Run the example. Priority was given to making code compact, not readability."""
for url in URLS:
response = request(json.dumps(partial_request_payload.copy() | {"requestUrl": url}).encode("utf-8"))
response_object = json.loads(ctypes.string_at(response).decode("utf-8"))
if response_object["status"] == 0:
print(f"Error for url {url}: {response_object['body']}")
else:
print(f"Success for {url}. HTTP Code: {response_object['status']}")
print("---")

endregion

region load/setup library

import ctypes # noqa: E402
import json # noqa: E402

library = ctypes.cdll.LoadLibrary(RELATIVE_PATH_TO_LIBRARY)
request = library.request
request.argtypes = [ctypes.c_char_p]
request.restype = ctypes.c_char_p

partial_request_payload = {
"followRedirects": False,
"insecureSkipVerify": False,
"withoutCookieJar": False,
"withDefaultCookieJar": False,
"isByteRequest": False,
"forceHttp1": False,
"catchPanics": False,
"withDebug": False,
"withRandomTLSExtensionOrder": False,
"timeoutSeconds": 30,
"timeoutMilliseconds": 0,
"sessionId": "2my-session-id",
"certificatePinningHosts": {},
"customTlsClient": CUSTOM_TLS_CLIENT,
"proxyUrl": "",
"isRotatingProxy": False,
"headers": {
"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",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36",
"accept-encoding": "gzip, deflate, br",
"accept-language": "de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7",
},
"headerOrder": ["accept", "user-agent", "accept-encoding", "accept-language"],
"requestMethod": "GET",
"requestBody": "",
"requestCookies": [],
}

endregion

if name == "main":
main()

</details> 

tl;dr is that I wouldn't use this library with a custom tls client.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants