Skip to content

The uTLS fingerprint parroting does not work #135

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

Closed
4 tasks done
ZeroAnarchy opened this issue Oct 7, 2022 · 6 comments
Closed
4 tasks done

The uTLS fingerprint parroting does not work #135

ZeroAnarchy opened this issue Oct 7, 2022 · 6 comments
Labels
bug Something isn't working

Comments

@ZeroAnarchy
Copy link

Welcome

  • Yes, I'm using the latest major release. Only such installations are supported.
  • Yes, I'm using the latest Golang release. Only such installations are supported.
  • Yes, I've searched similar issues on GitHub and didn't find any.
  • Yes, I've included all information below (version, config, log, etc).

Description of the problem

wireshark

Tested on latest dev-next commit. All tests are TLS 1.2, capture in Wireshark. The screenshot shows the TLS Client Hello packets.

  1. In the first window uTLS is disabled, all parameters (cipher suites, signature hash algorithms and extensions) are the same as the "crypto/tls" fingerprint.
  2. In the second window, uTLS is enabled with the "fingerprint": "chrome".
  3. In the third window, the request from the real Chrome browser, all parameters match the fingerprint.

sing-box uses uTLS version 1.1.2, which is the latest at the moment, it has the "Chrome 102" fingerprint, which matches the third window.

The "gfw-report" community recently released a fork of trojan-go with "crypto/tls" replaced by uTLS 1.1.2. I personally have not tested this version, but I think the authors of the fork checked the functionality before the release.

I don't know which side has the problem (utls or sing-box) but according to the screenshot we can say that the uTLS function in sing-box doesn't work at all.

Version of sing-box

$ sing-box version
sing-box version 1.1-beta9

Environment: go1.19.1 linux/amd64
Tags: with_utls
Revision: 5158bd7923fda2e67f8522053f20ce41f49440a0
CGO: disabled

Server and client configuration file

{
  "log": {
            "disabled":     false,
            "level":        "debug",
            "timestamp":    true
        },
  "inbounds": [
        {
            "tag":          "IN-SOCKS-HEROKU-EU",
            "listen":       "127.0.0.1",
            "listen_port":  15000,
            "type":         "socks"
        }
  ],
  "outbounds": [
        {
            "tag":          "OUT-VMESS-HEROKU-EU",
            "server":       "example.herokuapp.com",
            "server_port":  443,
            "type":         "vmess",
            "security":     "chacha20-poly1305",
            "uuid":         "",
            "authenticated_length": true,
            "global_padding":       true,
            "alter_id":             0,
            "multiplex": {
                "enabled":          true,
                "protocol":         "smux",
                "max_connections":  8,
                "min_streams":      4,
                "max_streams":      16
            },
            "transport": {
                "type":                     "ws",
                "path":                     "/websocket",
                "max_early_data":           2048,
                "early_data_header_name":   "Sec-WebSocket-Protocol",
                "headers": {
                    "User-Agent":           "Mozilla/5.0 (X11; Linux x86_64; rv:105.0) Gecko/20100101 Firefox/105.0"
                }
            },
            "tls": {
                "enabled":      true,
                "server_name":  "example.herokuapp.com",
                "min_version":  "1.2",
                "max_version":  "1.2",
                "utls": {
                   "enabled":     true,
                   "fingerprint": "chrome" 
                }
            }
        }
  ],
  "route": {
    "rules": [
        {   "inbound":      "IN-SOCKS-HEROKU-EU",
            "outbound":     "OUT-VMESS-HEROKU-EU"
        }
    ]
  }
}

Server and client log file

// no error
@nekohasekai
Copy link
Member

I didn't find the difference in using uTLS. Parameters such as max version and alpn will cause fingerprint modification.

@ZeroAnarchy
Copy link
Author

I didn't find the difference in using uTLS.

Do you mean that you checked yourself through Wireshark? Is that important. I want to understand if the problem is only on my side or yours too.
Or don't you see the difference between window (2) and (3) in the screenshot?

Parameters such as max version and alpn will cause fingerprint modification.

In my real config (not in the example above) I don't use min_version, max_version, or alpn. Only server_name. I rechecked on two servers (without min/max in config), one supports TLS 1.3, the other only supports TLS 1.2. The result is in the screenshot below. By default sing-box and Chrome use TLS 1.2 as the minimum version allowed. Why then does sing-box allow TLS 1.0 (in the screenshot)? I didn't use min_version.

Also, I only see 9 extensions in the Client Hello packet, and it should be ~16-17, like in the Chrome fingerprint.

wireshark_2

@nekohasekai
Copy link
Member

Try 8a53846

@nekohasekai nekohasekai added bug Something isn't working and removed need more information labels Oct 8, 2022
@ZeroAnarchy
Copy link
Author

Try 8a53846

Fixed ( : ౦ ‸ ౦ : )


Also noticed a couple of things:

  1. Parameters min_version, max_version and alpn are ignored when uTLS is enabled (which is basically correct).

  2. WebSocket (and possibly HTTP) transport is mostly incompatible with Chrome and Firefox fingerprints. They both send the alpn: "h2" extension, and modern web servers understand this extension and send it back. The result is that the connection becomes an HTTP/2 version, but WebSocket uses HTTP/1.1, which ends up being an error:

    ERROR [2691225450] inbound/socks[IN-SOCKS]: process connection from 127.0.0.1:40708: unexpected EOF

    or

    ERROR [1335030103] inbound/socks[IN-SOCKS]: process connection from 127.0.0.1:48772: malformed HTTP response "\x00\x00\x12\.........\x00\x00\x00\x01"

    If the web server ignores the alpn extension, the connection is successful.

  3. Using Chrome fingerprint always ends with an error:

    ERROR [2115457551] inbound/socks[IN-SOCKS]: process connection from 127.0.0.1:56734: tls: CurvePreferences includes unsupported curve

    Since TLS 1.3 encrypts most of the extensions I can't see what the problem is, maybe it's not even a sing-box problem but a "crypto/tls" problem.


Maybe you should add this information to the documentation as a warning in case someone runs into this problem in the future.

@nekohasekai
Copy link
Member

tls: CurvePreferences includes unsupported curve

Please send issue to upstream, they are based on very old crypto/tls and almost unmaintained.

@ZeroAnarchy
Copy link
Author

Probably found what the problem is. I made a fork where I applied Sync upstream crypto/tls #120 pull request and my fix.

I also made a separate branch where I additionally updated "crypto/tls" to the latest version (2022.09.30);
due to the commit crypto/ecdh: new package only supports Go 1.20 and higher.

I will test both versions for now.


P.S. Upstream has been slow to accept the new changes. Consider creating a temporary fork 'SagerNet/utls' until upstream updates...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants