@@ -2,6 +2,7 @@ package main
22
33import (
44 "context"
5+ "crypto/md5"
56 "crypto/sha256"
67 "encoding/base64"
78 "encoding/hex"
@@ -10,12 +11,13 @@ import (
1011 "io"
1112 "log"
1213 "math/rand"
13- "net/http"
1414 neturl "net/url"
1515 "regexp"
1616 "strconv"
1717 "strings"
1818 "time"
19+
20+ tlsclient "github.com/bogdanfinn/tls-client"
1921)
2022
2123type vkCaptchaError struct {
@@ -66,8 +68,13 @@ func solveVkCaptcha(ctx context.Context, captchaErr *vkCaptchaError, resolver *p
6668 return "" , fmt .Errorf ("no session_token in redirect_uri" )
6769 }
6870 log .Printf ("Solving VK Smart Captcha automatically..." )
71+ client , err := resolver .newTLSHTTPClient (profile , 20 * time .Second )
72+ if err != nil {
73+ return "" , fmt .Errorf ("failed to initialize tls client: %w" , err )
74+ }
75+ defer client .CloseIdleConnections ()
6976
70- powInput , difficulty , err := fetchPowInput (ctx , captchaErr .RedirectURI , resolver , profile )
77+ powInput , difficulty , err := fetchPowInput (ctx , captchaErr .RedirectURI , client , profile )
7178 if err != nil {
7279 return "" , fmt .Errorf ("failed to fetch PoW input: %w" , err )
7380 }
@@ -77,7 +84,7 @@ func solveVkCaptcha(ctx context.Context, captchaErr *vkCaptchaError, resolver *p
7784 return "" , fmt .Errorf ("failed to solve PoW" )
7885 }
7986
80- successToken , err := callCaptchaNotRobot (ctx , captchaErr .SessionToken , hash , resolver , profile )
87+ successToken , err := callCaptchaNotRobot (ctx , captchaErr .SessionToken , hash , client , profile )
8188 if err != nil {
8289 return "" , fmt .Errorf ("captchaNotRobot API failed: %w" , err )
8390 }
@@ -86,16 +93,13 @@ func solveVkCaptcha(ctx context.Context, captchaErr *vkCaptchaError, resolver *p
8693 return successToken , nil
8794}
8895
89- func fetchPowInput (ctx context.Context , redirectURI string , resolver * protectedResolver , profile Profile ) (string , int , error ) {
90- req , err := http . NewRequestWithContext (ctx , "GET" , redirectURI , nil )
96+ func fetchPowInput (ctx context.Context , redirectURI string , client tlsclient. HttpClient , profile Profile ) (string , int , error ) {
97+ req , err := newFHTTPRequest (ctx , "GET" , redirectURI , nil )
9198 if err != nil {
9299 return "" , 0 , err
93100 }
94- applyBrowserProfile (req , profile )
101+ applyBrowserProfileFhttp (req , profile )
95102 req .Header .Set ("Accept" , "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" )
96-
97- client := resolver .newHTTPClient (20 * time .Second )
98- defer client .CloseIdleConnections ()
99103 resp , err := client .Do (req )
100104 if err != nil {
101105 return "" , 0 , err
@@ -145,22 +149,19 @@ func callCaptchaNotRobot(
145149 ctx context.Context ,
146150 sessionToken string ,
147151 hash string ,
148- resolver * protectedResolver ,
152+ client tlsclient. HttpClient ,
149153 profile Profile ,
150154) (string , error ) {
151155 vkReq := func (method string , postData string ) (map [string ]interface {}, error ) {
152156 reqURL := "https://api.vk.ru/method/" + method + "?v=5.131"
153- req , err := http . NewRequestWithContext (ctx , "POST" , reqURL , strings . NewReader (postData ))
157+ req , err := newFHTTPRequest (ctx , "POST" , reqURL , [] byte (postData ))
154158 if err != nil {
155159 return nil , err
156160 }
157- applyBrowserProfile (req , profile )
161+ applyBrowserProfileFhttp (req , profile )
158162 req .Header .Set ("Content-Type" , "application/x-www-form-urlencoded" )
159163 req .Header .Set ("Origin" , "https://vk.ru" )
160164 req .Header .Set ("Referer" , "https://vk.ru/" )
161-
162- client := resolver .newHTTPClient (20 * time .Second )
163- defer client .CloseIdleConnections ()
164165 httpResp , err := client .Do (req )
165166 if err != nil {
166167 return nil , err
@@ -192,8 +193,11 @@ func callCaptchaNotRobot(
192193 }
193194 time .Sleep (200 * time .Millisecond )
194195
195- browserFp := fmt .Sprintf ("%032x" , rand .Int63 ())
196- deviceJSON := `{"screenWidth":1920,"screenHeight":1080,"screenAvailWidth":1920,"screenAvailHeight":1032,"innerWidth":1920,"innerHeight":945,"devicePixelRatio":1,"language":"en-US","languages":["en-US"],"webdriver":false,"hardwareConcurrency":16,"deviceMemory":8,"connectionEffectiveType":"4g","notificationsPermission":"denied"}`
196+ browserFp := generateBrowserFp (profile )
197+ deviceJSON := fmt .Sprintf (
198+ `{"screenWidth":1920,"screenHeight":1080,"screenAvailWidth":1920,"screenAvailHeight":1040,"innerWidth":1920,"innerHeight":969,"devicePixelRatio":1,"language":"en-US","languages":["en-US"],"webdriver":false,"hardwareConcurrency":8,"deviceMemory":8,"connectionEffectiveType":"4g","notificationsPermission":"default","userAgent":"%s","platform":"Win32"}` ,
199+ profile .UserAgent ,
200+ )
197201 componentDoneData := baseParams + fmt .Sprintf (
198202 "&browser_fp=%s&device=%s" ,
199203 browserFp ,
@@ -205,9 +209,15 @@ func callCaptchaNotRobot(
205209 }
206210 time .Sleep (200 * time .Millisecond )
207211
208- cursorJSON := `[{"x":950,"y":500},{"x":945,"y":510},{"x":940,"y":520},{"x":938,"y":525},{"x":938,"y":525}]`
212+ cursorJSON := generateFakeCursor ()
209213 answer := base64 .StdEncoding .EncodeToString ([]byte ("{}" ))
210- debugInfo := "d44f534ce8deb56ba20be52e05c433309b49ee4d2a70602deeb17a1954257785"
214+ debugInfoBytes := md5 .Sum ([]byte (profile .UserAgent + strconv .FormatInt (time .Now ().UnixNano (), 10 )))
215+ debugInfo := hex .EncodeToString (debugInfoBytes [:])
216+ connectionDownlinkSamples := make ([]string , 0 , 16 )
217+ for i := 0 ; i < 16 ; i ++ {
218+ connectionDownlinkSamples = append (connectionDownlinkSamples , fmt .Sprintf ("%.1f" , 8.5 + rand .Float64 ()* 2.0 ))
219+ }
220+ connectionDownlink := "[" + strings .Join (connectionDownlinkSamples , "," ) + "]"
211221 checkData := baseParams + fmt .Sprintf (
212222 "&accelerometer=%s&gyroscope=%s&motion=%s&cursor=%s&taps=%s&connectionRtt=%s&connectionDownlink=%s&browser_fp=%s&hash=%s&answer=%s&debug_info=%s" ,
213223 neturl .QueryEscape ("[]" ),
@@ -216,7 +226,7 @@ func callCaptchaNotRobot(
216226 neturl .QueryEscape (cursorJSON ),
217227 neturl .QueryEscape ("[]" ),
218228 neturl .QueryEscape ("[]" ),
219- neturl .QueryEscape ("[9.5,9.5,9.5,9.5,9.5,9.5,9.5,9.5,9.5,9.5,9.5,9.5,9.5,9.5,9.5,9.5]" ),
229+ neturl .QueryEscape (connectionDownlink ),
220230 browserFp ,
221231 hash ,
222232 answer ,
0 commit comments