Skip to content

Commit

Permalink
[~] fix GREASE ja3 (#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
Noooste authored Mar 13, 2024
1 parent 8621d88 commit 5d0c120
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 29 deletions.
60 changes: 33 additions & 27 deletions ja3.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"errors"
"fmt"
tls "github.com/Noooste/utls"
"github.com/Noooste/utls/dicttls"
"strconv"
"strings"
)
Expand All @@ -22,7 +21,7 @@ type TlsSpecifications struct {
RenegotiationSupport tls.RenegotiationSupport
}

func DefaultTlsSpecifications() TlsSpecifications {
func DefaultTlsSpecifications(navigator string) TlsSpecifications {
signatureAlg := []tls.SignatureScheme{
tls.ECDSAWithP256AndSHA256,
tls.PSSWithSHA256,
Expand All @@ -34,13 +33,26 @@ func DefaultTlsSpecifications() TlsSpecifications {
tls.PKCS1WithSHA512,
}

return TlsSpecifications{
AlpnProtocols: []string{"h2", "http/1.1"},
SignatureAlgorithms: signatureAlg,
SupportedVersions: []uint16{tls.VersionTLS13,
var supportedVersions []uint16

switch navigator {
case Chrome:
supportedVersions = []uint16{
tls.GREASE_PLACEHOLDER,
tls.VersionTLS13,
tls.VersionTLS12,
tls.VersionTLS11,
},
}
default:
supportedVersions = []uint16{
tls.VersionTLS13,
tls.VersionTLS12,
}
}

return TlsSpecifications{
AlpnProtocols: []string{"h2", "http/1.1"},
SignatureAlgorithms: signatureAlg,
SupportedVersions: supportedVersions,
CertCompressionAlgos: []tls.CertCompressionAlgo{tls.CertCompressionBrotli},
DelegatedCredentialsAlgorithmSignatures: []tls.SignatureScheme{
tls.ECDSAWithP256AndSHA256,
Expand Down Expand Up @@ -70,7 +82,7 @@ func DefaultTlsSpecifications() TlsSpecifications {
//
// Any absent field in the client hello will raise an error.
func (s *Session) ApplyJa3(ja3, navigator string) error {
return s.ApplyJa3WithSpecifications(ja3, DefaultTlsSpecifications(), navigator)
return s.ApplyJa3WithSpecifications(ja3, DefaultTlsSpecifications(navigator), navigator)
}

// ApplyJa3WithSpecifications applies JA3 settings to the session from a fingerprint.
Expand All @@ -89,10 +101,11 @@ func (s *Session) ApplyJa3(ja3, navigator string) error {
//
// Any absent field in the client hello will raise an error.
func (s *Session) ApplyJa3WithSpecifications(ja3 string, specifications TlsSpecifications, navigator string) error {
_, err := stringToSpec(ja3, DefaultTlsSpecifications(), navigator)
_, err := stringToSpec(ja3, DefaultTlsSpecifications(navigator), navigator)
if err != nil {
return err
}

s.GetClientHelloSpec = func() *tls.ClientHelloSpec {
specs, _ := stringToSpec(ja3, specifications, navigator)
return specs
Expand Down Expand Up @@ -147,6 +160,13 @@ func stringToSpec(ja3 string, specifications TlsSpecifications, navigator string
//extensions
if information[2] != "" {
extensions, _, maxVers, err = getExtensions(rawExtensions, &specifications, pointFormats, curves, navigator)

if navigator == Chrome {
last := extensions[len(extensions)-1]
extensions[len(extensions)-1] = &tls.UtlsGREASEExtension{}
extensions = append(extensions, last)
}

} else {
extensions, _, maxVers, err = []tls.TLSExtension{}, 0, tls.VersionTLS13, nil
if information[3] != "" {
Expand Down Expand Up @@ -180,9 +200,11 @@ func stringToSpec(ja3 string, specifications TlsSpecifications, navigator string
}

extensions = append(extensions, &tls.SupportedPointsExtension{SupportedPoints: pf})

specs.CompressionMethods = pf
}
}

if err != nil {
return nil, err
}
Expand Down Expand Up @@ -422,23 +444,7 @@ func getExtensions(extensions []string, specifications *TlsSpecifications, defau
break

case "65037":
builtExtensions = append(builtExtensions, &tls.GREASEEncryptedClientHelloExtension{
CandidateCipherSuites: []tls.HPKESymmetricCipherSuite{
{
KdfId: dicttls.HKDF_SHA256,
AeadId: dicttls.AEAD_AES_128_GCM,
},
{
KdfId: dicttls.HKDF_SHA256,
AeadId: dicttls.AEAD_AES_256_GCM,
},
{
KdfId: dicttls.HKDF_SHA256,
AeadId: dicttls.AEAD_CHACHA20_POLY1305,
},
},
CandidatePayloadLens: []uint16{128, 160},
})
builtExtensions = append(builtExtensions, tls.BoringGREASEECH())

case "65281":
builtExtensions = append(builtExtensions, &tls.RenegotiationInfoExtension{Renegotiation: specifications.RenegotiationSupport})
Expand Down
4 changes: 2 additions & 2 deletions test/ja3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func TestChrome(t *testing.T) {
func TestSession_ApplyJa3(t *testing.T) {
session := azuretls.NewSession()

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

if err := session.ApplyJa3(ja3Origin, azuretls.Chrome); err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -131,7 +131,7 @@ func TestSession_ApplyJa3(t *testing.T) {
t.Fatal("Expected "+splitOrigin[1]+", got ", split[1])
}

if split[2] != splitOrigin[2] {
if split[2] != splitOrigin[2] && strings.TrimSuffix(splitOrigin[2], "-21") != split[2] {
t.Fatal("Expected "+splitOrigin[2]+", got ", split[2])
}

Expand Down

0 comments on commit 5d0c120

Please sign in to comment.