Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
V4NSH4J
GitHub Repository: V4NSH4J/discord-mass-DM-GO
Path: blob/main/client/utils.go
310 views
1
package client
2
3
import (
4
"bytes"
5
"compress/gzip"
6
"compress/zlib"
7
"crypto/sha256"
8
"encoding/base64"
9
"encoding/json"
10
"io/ioutil"
11
"strconv"
12
"strings"
13
14
utls "github.com/Danny-Dasilva/utls"
15
"github.com/andybalholm/brotli"
16
)
17
18
const (
19
chrome = "chrome" //chrome User agent enum
20
firefox = "firefox" //firefox User agent enum
21
)
22
23
func parseUserAgent(userAgent string) string {
24
switch {
25
case strings.Contains(strings.ToLower(userAgent), "chrome"):
26
return chrome
27
case strings.Contains(strings.ToLower(userAgent), "firefox"):
28
return firefox
29
default:
30
return chrome
31
}
32
33
}
34
35
// DecompressBody unzips compressed data
36
func DecompressBody(Body []byte, encoding []string, content []string) (parsedBody string) {
37
if len(encoding) > 0 {
38
if encoding[0] == "gzip" {
39
unz, err := gUnzipData(Body)
40
if err != nil {
41
return string(Body)
42
}
43
return string(unz)
44
} else if encoding[0] == "deflate" {
45
unz, err := enflateData(Body)
46
if err != nil {
47
return string(Body)
48
}
49
return string(unz)
50
} else if encoding[0] == "br" {
51
unz, err := unBrotliData(Body)
52
if err != nil {
53
return string(Body)
54
}
55
return string(unz)
56
}
57
} else if len(content) > 0 {
58
decodingTypes := map[string]bool{
59
"image/svg+xml": true,
60
"image/webp": true,
61
"image/jpeg": true,
62
"image/png": true,
63
"application/pdf": true,
64
}
65
if decodingTypes[content[0]] {
66
return base64.StdEncoding.EncodeToString(Body)
67
}
68
}
69
parsedBody = string(Body)
70
return parsedBody
71
72
}
73
74
func gUnzipData(data []byte) (resData []byte, err error) {
75
gz, err := gzip.NewReader(bytes.NewReader(data))
76
if err != nil {
77
return []byte{}, err
78
}
79
defer gz.Close()
80
respBody, err := ioutil.ReadAll(gz)
81
return respBody, err
82
}
83
func enflateData(data []byte) (resData []byte, err error) {
84
zr, err := zlib.NewReader(bytes.NewReader(data))
85
if err != nil {
86
return []byte{}, err
87
}
88
defer zr.Close()
89
enflated, err := ioutil.ReadAll(zr)
90
return enflated, err
91
}
92
func unBrotliData(data []byte) (resData []byte, err error) {
93
br := brotli.NewReader(bytes.NewReader(data))
94
respBody, err := ioutil.ReadAll(br)
95
return respBody, err
96
}
97
98
// StringToSpec creates a ClientHelloSpec based on a JA3 string
99
func StringToSpec(ja3 string, userAgent string) (*utls.ClientHelloSpec, error) {
100
parsedUserAgent := parseUserAgent(userAgent)
101
extMap := genMap()
102
tokens := strings.Split(ja3, ",")
103
104
version := tokens[0]
105
ciphers := strings.Split(tokens[1], "-")
106
extensions := strings.Split(tokens[2], "-")
107
curves := strings.Split(tokens[3], "-")
108
if len(curves) == 1 && curves[0] == "" {
109
curves = []string{}
110
}
111
pointFormats := strings.Split(tokens[4], "-")
112
if len(pointFormats) == 1 && pointFormats[0] == "" {
113
pointFormats = []string{}
114
}
115
// parse curves
116
var targetCurves []utls.CurveID
117
targetCurves = append(targetCurves, utls.CurveID(utls.GREASE_PLACEHOLDER)) //append grease for Chrome browsers
118
for _, c := range curves {
119
cid, err := strconv.ParseUint(c, 10, 16)
120
if err != nil {
121
return nil, err
122
}
123
targetCurves = append(targetCurves, utls.CurveID(cid))
124
// if cid != uint64(utls.CurveP521) {
125
// CurveP521 sometimes causes handshake errors
126
// }
127
}
128
extMap["10"] = &utls.SupportedCurvesExtension{Curves: targetCurves}
129
130
// parse point formats
131
var targetPointFormats []byte
132
for _, p := range pointFormats {
133
pid, err := strconv.ParseUint(p, 10, 8)
134
if err != nil {
135
return nil, err
136
}
137
targetPointFormats = append(targetPointFormats, byte(pid))
138
}
139
extMap["11"] = &utls.SupportedPointsExtension{SupportedPoints: targetPointFormats}
140
141
// set extension 43
142
vid64, err := strconv.ParseUint(version, 10, 16)
143
if err != nil {
144
return nil, err
145
}
146
vid := uint16(vid64)
147
// extMap["43"] = &utls.SupportedVersionsExtension{
148
// Versions: []uint16{
149
// utls.VersionTLS12,
150
// },
151
// }
152
153
// build extenions list
154
var exts []utls.TLSExtension
155
//Optionally Add Chrome Grease Extension
156
if parsedUserAgent == chrome {
157
exts = append(exts, &utls.UtlsGREASEExtension{})
158
}
159
for _, e := range extensions {
160
te, ok := extMap[e]
161
if !ok {
162
// eAsint, err := strconv.Atoi(e)
163
// if err != nil {
164
// return nil, err
165
// }
166
// te = &utls.GenericExtension{Id: uint16(eAsint)}
167
continue
168
// return nil, raiseExtensionError(e)
169
}
170
// //Optionally add Chrome Grease Extension
171
if e == "21" && parsedUserAgent == chrome {
172
exts = append(exts, &utls.UtlsGREASEExtension{})
173
}
174
exts = append(exts, te)
175
}
176
//Add this back in if user agent is chrome and no padding extension is given
177
// if parsedUserAgent == chrome {
178
// exts = append(exts, &utls.UtlsGREASEExtension{})
179
// exts = append(exts, &utls.UtlsPaddingExtension{GetPaddingLen: utls.BoringPaddingStyle})
180
// }
181
// build SSLVersion
182
// vid64, err := strconv.ParseUint(version, 10, 16)
183
// if err != nil {
184
// return nil, err
185
// }
186
187
// build CipherSuites
188
var suites []uint16
189
//Optionally Add Chrome Grease Extension
190
if parsedUserAgent == chrome {
191
suites = append(suites, utls.GREASE_PLACEHOLDER)
192
}
193
for _, c := range ciphers {
194
cid, err := strconv.ParseUint(c, 10, 16)
195
if err != nil {
196
return nil, err
197
}
198
suites = append(suites, uint16(cid))
199
}
200
_ = vid
201
return &utls.ClientHelloSpec{
202
// TLSVersMin: vid,
203
// TLSVersMax: vid,
204
CipherSuites: suites,
205
CompressionMethods: []byte{0},
206
Extensions: exts,
207
GetSessionID: sha256.Sum256,
208
}, nil
209
}
210
211
func genMap() (extMap map[string]utls.TLSExtension) {
212
extMap = map[string]utls.TLSExtension{
213
"0": &utls.SNIExtension{},
214
"5": &utls.StatusRequestExtension{},
215
// These are applied later
216
// "10": &tls.SupportedCurvesExtension{...}
217
// "11": &tls.SupportedPointsExtension{...}
218
"13": &utls.SignatureAlgorithmsExtension{
219
SupportedSignatureAlgorithms: []utls.SignatureScheme{
220
utls.ECDSAWithP256AndSHA256,
221
utls.ECDSAWithP384AndSHA384,
222
utls.ECDSAWithP521AndSHA512,
223
utls.PSSWithSHA256,
224
utls.PSSWithSHA384,
225
utls.PSSWithSHA512,
226
utls.PKCS1WithSHA256,
227
utls.PKCS1WithSHA384,
228
utls.PKCS1WithSHA512,
229
utls.ECDSAWithSHA1,
230
utls.PKCS1WithSHA1,
231
},
232
},
233
"16": &utls.ALPNExtension{
234
AlpnProtocols: []string{"h2", "http/1.1"},
235
},
236
"17": &utls.GenericExtension{Id: 17}, // status_request_v2
237
"18": &utls.SCTExtension{},
238
"21": &utls.UtlsPaddingExtension{GetPaddingLen: utls.BoringPaddingStyle},
239
"22": &utls.GenericExtension{Id: 22}, // encrypt_then_mac
240
"23": &utls.UtlsExtendedMasterSecretExtension{},
241
"27": &utls.CompressCertificateExtension{
242
Algorithms: []utls.CertCompressionAlgo{utls.CertCompressionBrotli},
243
},
244
"28": &utls.FakeRecordSizeLimitExtension{}, //Limit: 0x4001
245
"35": &utls.SessionTicketExtension{},
246
"34": &utls.GenericExtension{Id: 34},
247
"41": &utls.GenericExtension{Id: 41}, //FIXME pre_shared_key
248
"43": &utls.SupportedVersionsExtension{Versions: []uint16{
249
utls.GREASE_PLACEHOLDER,
250
utls.VersionTLS13,
251
utls.VersionTLS12,
252
utls.VersionTLS11,
253
utls.VersionTLS10}},
254
"44": &utls.CookieExtension{},
255
"45": &utls.PSKKeyExchangeModesExtension{Modes: []uint8{
256
utls.PskModeDHE,
257
}},
258
"49": &utls.GenericExtension{Id: 49}, // post_handshake_auth
259
"50": &utls.GenericExtension{Id: 50}, // signature_algorithms_cert
260
"51": &utls.KeyShareExtension{KeyShares: []utls.KeyShare{
261
{Group: utls.CurveID(utls.GREASE_PLACEHOLDER), Data: []byte{0}},
262
{Group: utls.X25519},
263
264
// {Group: utls.CurveP384}, known bug missing correct extensions for handshake
265
}},
266
"30032": &utls.GenericExtension{Id: 0x7550, Data: []byte{0}}, //FIXME
267
"13172": &utls.NPNExtension{},
268
"17513": &utls.ApplicationSettingsExtension{
269
SupportedALPNList: []string{
270
"h2",
271
},
272
},
273
"65281": &utls.RenegotiationInfoExtension{
274
Renegotiation: utls.RenegotiateOnceAsClient,
275
},
276
}
277
return
278
279
}
280
281
func PrettyStruct(data interface{}) (string, error) {
282
val, err := json.MarshalIndent(data, "", " ")
283
if err != nil {
284
return "", err
285
}
286
return string(val), nil
287
}
288
289