private string _GenerateDeviceFingerPrintRaw(RandomDeviceInfo randomDeviceInfo) { var fingerPrintList = new List <string>() { randomDeviceInfo.userAgent, // User agent "zh-CN", // Language randomDeviceInfo.colorDepth, // Color depth randomDeviceInfo.screenRes, // Screen resolution "-480", // Timezone offset (Let's pretend to be in China lol) "true", // (Pretend to have) session storage "true", // (Pretend to have) local storage "true", // (Pretend to have) indexed database "undefined", // typeof document.body.addBehavior "function", // typeof window.openDatabase() "undefined", // navigator.cpuClass randomDeviceInfo.platform, // navigator.platform "1", // "Do Not Track" flag (but the Big Brother is still watching you anyway...) // List of browser plugin, just make a FAKE NEWS and return. "Widevine Content Decryption Module::Enables Widevine " + "licenses for playback of HTML audio/video content. (ver" + "sion: 1.4.8.970)::application/x-ppapi-widevine-cdm~;" + "Chrome PDF Viewer::::application/pdf~pdf;Native Client:" + ":::application/x-nacl~,application/x-pnacl~;Chrome PDF " + "Viewer::Portable Document Format::application/x-google-chrome-pdf~pdf" }; // Encode the string to UTF-8 Base64 string and return. var fingerPrintBytes = Encoding.UTF8.GetBytes(string.Join("###", fingerPrintList.ToArray())); return(Convert.ToBase64String(fingerPrintBytes)); }
public async Task <DeviceFingerPrint> GenerateDeviceFingerPrint(RandomDeviceInfo randomDeviceInfo) { string deviceFingerPrintRaw = _GenerateDeviceFingerPrintRaw(randomDeviceInfo); return(new DeviceFingerPrint(deviceFingerPrintRaw, await _GetFingerPrintSignature(deviceFingerPrintRaw, randomDeviceInfo), LoginUtils.GetMD5(deviceFingerPrintRaw))); }
public async Task <string> _GetFingerPrintSignature(string fingerPrint, RandomDeviceInfo randomDeviceInfo) { // Initialize HTTP client and set base URL var httpClient = new HttpClient() { BaseAddress = new Uri("https://login.xunlei.com"), }; // Set the fake user-agent and referrer httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(randomDeviceInfo.userAgent); httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Referer", randomDeviceInfo.referrer); // Get the Javascript to string string magicJavaScript = await httpClient.GetStringAsync( string.Format("/risk?cmd=algorithm&t={0}", DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString())); // Parse and run this magic JavaScript... var javaScriptMethod = new Engine().Execute(magicJavaScript); var javaScriptResult = javaScriptMethod.Invoke("xl_al", fingerPrint); // Return the signature return(javaScriptResult.AsString()); }
private async Task <InitialCsrfToken> _GetCsrfToken(DeviceFingerPrint deviceFingerPrint, RandomDeviceInfo randomDeviceInfo) { // Declare HttpClient var httpHandler = new HttpClientHandler() { CookieContainer = _cookieContainer }; var httpClient = new HttpClient(httpHandler) { BaseAddress = new Uri("https://login.xunlei.com") }; // Prepare the header httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(randomDeviceInfo.userAgent); httpClient.DefaultRequestHeaders.Add("Referer", randomDeviceInfo.referrer); // Prepare the signature and submit string stringContent = string.Format("xl_fp_raw={0}&xl_fp={1}&xl_fp_sign={2}&cachetime={3}", deviceFingerPrint.DeviceFingerPrintRaw, deviceFingerPrint.DeviceFingerPrintChecksum, deviceFingerPrint.DeviceFingerPrintSingature, DateTimeOffset.Now.ToUnixTimeMilliseconds()); // Merge into a POST content var postContent = new StringContent(stringContent, Encoding.UTF8, "text/plain"); // Fire the hole! var httpResponse = await httpClient.PostAsync(string.Format("/risk?cmd=report", DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString()), postContent); // If not successful, return an empty string (to shut up the compiler!) if (!httpResponse.IsSuccessStatusCode) { httpClient.Dispose(); return(new InitialCsrfToken() { ErrorMessage = string.Format("HTTP {0} - {1}", ((int)httpResponse.StatusCode).ToString(), httpResponse.ReasonPhrase), IsSuccessful = false }); } // Get device ID from cookie container // The device ID will be granted by Thunder's server (https://login.xunlei.com/risk?cmd=report) // The format of a device ID is something like this: // wdi10.abcabcabcabcabbabcabccabcabceeabcabcaabcabcabcaabcabcaaabcabcabc string deviceId = LoginUtils.FindCookieValue(_cookieContainer, "deviceid", "http://xunlei.com"); // Then we need to get its MD5 hash, substring from it with length 32 (i.e. get the first 32 chars) string csrfToken = LoginUtils.GetMD5(deviceId.Substring(0, 32)); // Dispose the http client and return httpClient.Dispose(); return(new InitialCsrfToken() { IsSuccessful = true, CsrfToken = csrfToken, ErrorMessage = string.Empty }); }