1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Top100 Vote Bot Issues (With Code/Logs) 25$ Bounty!

Discussion in 'C, C++, C#' started by TwitchTime, Jul 3, 2017.

  1. TwitchTime

    TwitchTime Newbie

    Joined:
    Apr 3, 2014
    Messages:
    10
    Likes Received:
    0
    Hello, I'm trying to write a xtremetop100 vote bot. I have a moderate amount of programming experience and some with working on bots for websites but I'm struggling with this one. If you're just here to take code, be aware it doesn't work and is not well structured. I'm hoping a member here can point me towards what I'm doing wrong because I'm basing all of my requests off of direct packet logs of a working vote bot so it SHOULD be correct.

    As you will see below, I have all of my research done and I (mostly) know what I'm doing. I'm still not able to process votes though so if you know what I'm doing wrong, PM me an answer and if it solves the problem I'll paypal you 25$ as thanks. Not a huge reward but an incentive to offer some advice.


    The Packet Logs

    There is a working xtremetop100 bot but it is paid after a 3 day trial and has.... issues of its own. I'm using it to log all the webrequests to confirm I'm sending the proper information in the proper sequence. This is the full voting sequence from this bot for a vote that successfully processed.

    Code:
    //Initial in page is requested
    PV)!E*@qfhwP}H"PR4GET /in.php?site=1936233192 HTTP/1.1
    Host: www.xtremetop100.com
    User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_4_11; ru-ru) AppleWebKit/525.18 (KHTML, like Gecko) Version/3.1.1 Safari/525.18
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip, deflate
    Connection: close
    Referer: http://www.xtremetop100.com/in.php?site=1936233192
    
    //Wireshark doesnt want me to copy paste the uncompressed body. This is just the in page from which the values are pulled.
    )!PVEl5fhqPwH-X:PY.eQ..on^{hR*2JVs_EyIRyX8
    l8    `VJQA8M|`Ybg1+Jm'}T{2THUh !-P
    )H&b
    :y_3C+sxeBMYkh`HtT+GNp0M*/*rt==xALqSjri(`&}9AUlu4CcS%-<NJp.ZMMg1VL3m)h
    FnmC%|1HWp"[email protected](a4Ag*qiS4evNnI"nZkOiLMk}Id~PH5j?clR$W%AEB[%#&fO    vvaLhis0&V?rv0VU=}qrHu}bllji#E[{w
    SlfjKz^\RWAR816}M5%W+k)Da;#"LV^[email protected]}`LAM_Cyw84oB&#|vs6;[email protected]|\:AT1(4wJyNg4UloeZv:t+)x|Gp]qAVKWE^;EKnTsRSo    9hwZBL:I:[email protected]    /;Dt{/c6I&|_C"85+SZ<WHr6"E$"TP/:zLo_d6c\M;(5y_`JD/
    0
    
    //Request is sent to 2captcha to solve it using the google key and page we pulled [I've commented out my api key and changed it after]
    PV)!Es*@qYluxPIIPPOST /in.php HTTP/1.1
    Host: 2captcha.com
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip, deflate
    Connection: close
    Referer: http://2captcha.com/in.php
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 192
    
    key=--ThisIsmyAPIKeyRemoved--&soft_id=1831&method=userrecaptcha&googlekey=6Lf3v8wSAAAAABVuu8qFKDtsvc0ILPoyUBVRToA9&pageurl=http%3a%2f%2fwww.xtremetop100.com%2fin.php%3fsite%3d1936233192
    
    //2Captcha replies with a token I can use to request the solve
    )!PVE6>vYluqPxIIPPHTTP/1.1 200 OK
    Server: nginx/1.10.1
    Date: Mon, 03 Jul 2017 15:25:33 GMT
    Content-Type: text/html; charset=utf-8
    Transfer-Encoding: chunked
    Connection: close
    X-Powered-By: HPHP
    
    d
    OK|3412834454
    0
    
    //It requests a solve every 3 seconds using the token above. This is the final solve
    PV)!E+>@qYluPw7P)GET /res.php?key=--ThisIsmyAPIKeyRemoved--&action=get&id=3412834454 HTTP/1.1
    Host: 2captcha.com
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip, deflate
    Connection: close
    Referer: http://2captcha.com/res.php?key=--ThisIsmyAPIKeyRemoved--&action=get&id=3412834454
    
    
    //2Captcha replies that its been solved and with the g-recaptcha-response solve data
    )!PVETFYluqPw7PDHTTP/1.1 200 OK
    Server: nginx/1.10.1
    Date: Mon, 03 Jul 2017 15:26:14 GMT
    Content-Type: text/html; charset=utf-8
    Transfer-Encoding: chunked
    Connection: close
    X-Powered-By: HPHP
    
    167
    OK|03AEHxwux6cgi9pnyQp-6AOzU2tQxg6zGJk-WnT42c-GQAKlZ9ynzCqoJLRHgAn5hL0TEfQwEkBwnVXpSE1TYzYcmtzvngyYE4oMQjCdSbb5B7_rBdMJn2j5jfx_wHTJcA5e4s_THu4IORTybOh4WThTRfCDPYHd3PXNGDY9Y0qztzB9ySRmirYHPfQubftmpflGHjlkuRMbotxw96454t7PolWLW1aFMTSN4KtRKoGNnvy-E_jZY9WZE8yqzHtg-3mAZ-tms8vzNpSwFAaQQiVihh7pT3PW31FSWm_pp-bCUwHUyEnkZuTf9kL0_S1cfgawuAKDkoESz8tsNuLeANnmsaQsLi-9-tGw
    0
    
    //It submits the vote to the in-post.php page. Post values are site id, captcha check, ticki value and recaptcha response
    PV)[email protected]\+"PTcPOST /in-post.php?site=1936233192 HTTP/1.1
    Host: www.xtremetop100.com
    User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_4_11; ru-ru) AppleWebKit/525.18 (KHTML, like Gecko) Version/3.1.1 Safari/525.18
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip, deflate
    Connection: keep-alive
    Referer: http://www.xtremetop100.com/in.php?site=1936233192
    Cookie: flowridaoookie=1
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 452
    
    site=1936233192&secure_captcha_check=3882&ticki=This-is-ticki-value-from-in.php&g-recaptcha-response=03AEHxwux6cgi9pnyQp-6AOzU2tQxg6zGJk-WnT42c-GQAKlZ9ynzCqoJLRHgAn5hL0TEfQwEkBwnVXpSE1TYzYcmtzvngyYE4oMQjCdSbb5B7_rBdMJn2j5jfx_wHTJcA5e4s_THu4IORTybOh4WThTRfCDPYHd3PXNGDY9Y0qztzB9ySRmirYHPfQubftmpflGHjlkuRMbotxw96454t7PolWLW1aFMTSN4KtRKoGNnvy-E_jZY9WZE8yqzHtg-3mAZ-tms8vzNpSwFAaQQiVihh7pT3PW31FSWm_pp-bCUwHUyEnkZuTf9kL0_S1cfgawuAKDkoESz8tsNuLeANnmsaQsLi-9-tGw
    
    //It then auto forwards me to the next page successfully (not important. I just use this in my bot to 'guess' if the vote was successful or not.)
    )!PVEUG+fhqP+"8_P&OHTTP/1.1 302 Found
    location: http://www.xtremetop100.com/eudemons-online
    Content-Type: text/html; charset=UTF-8
    Content-Length: 0
    Date: Mon, 03 Jul 2017 15:26:15 GMT
    Accept-Ranges: bytes
    Server: LiteSpeed
    Cache-Control: no-cache, no-store, must-revalidate, max-age=0
    Connection: Keep-Alive
    
    
    It certainly seems like I should be sending the same data but I've tried plenty of votes and none count where this bot does work... I'm a bit stumped on what to do.

    USER_AGENT doesn't match because their bot chooses a random one each request from a list of a bunch to avoid detection. That's a smart idea I guess but not really applicable when I'm testing 1 vote at a time.

    Also be aware I've anonymized a few pieces of information. This is just to hide which server I voted for and my api key. Its batch replaced so its the same sequence of info.

    The Code

    This is the code I am currently using to try to generate a single vote. It has a lot of hardcoded values and is very messy so I'll annotate what its doing and how logic flows so its easier to read.

    Code:
        public class Bot
        {
            const string USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0";
            const string ACCEPT_HEADER = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
            const string URL_IN = "http://www.xtremetop100.com/in.php";
            const string URL_POST = "http://www.xtremetop100.com/in-post.php";
    
            public bool IsVoteSuccessful;
    
            private DateTime _solveStartedAt;
            private string _siteId;
            private string _proxyDetails;
            private CookieContainer _cookies;
            private string _captchaKey;
            private string _googleKey;
            private string _scc;
            private string _ticki;
            private string _captchaSolution;
    
            /// <summary>
            /// Initialize the bot so we know who we're voting for, what captcha solver api key to use and what proxy to use (if any)
            /// </summary>
            /// <param name="siteId"></param>
            /// <param name="captchaKey"></param>
            /// <param name="proxyDetails"></param>
            public Bot(string siteId, string captchaKey, string proxyDetails)
            {
                _siteId = siteId;
                _cookies = new CookieContainer();
                _captchaKey = captchaKey;
                _proxyDetails = proxyDetails;
            }
    
            /// <summary>
            /// Handles all vote logic. Call after initializing the bot.
            /// </summary>
            public void Vote()
            {
                GetInData();
                SolveCaptcha();
                PostInData();
            } 
    
            /// <summary>
            /// Simple formatting to get the URL we request initial details from.
            /// </summary>
            string GetInURL()
            {
                return URL_IN + "?site=" + _siteId;
            }
    
            /// <summary>
            /// Simple formatting to get the URL we send final data to.
            /// </summary>
            string GetPostURL()
            {
                return URL_POST + "?site=" + _siteId;
            }
    
            /// <summary>
            /// Request the top100 in.php page to get the recaptcha info and other details needed for when vote is submitted
            /// </summary>
            private void GetInData()
            {          
                //We're sending a GET request for the page using a proxy. We need to GZip decompress the result
                var wr = GetWebRequest(GetInURL(), "www.xtremetop100.com", true);
                wr.Method = "GET";
                wr.AutomaticDecompression = DecompressionMethods.GZip;
                wr.Referer = GetInURL();
    
                Console.Title = "Requesting vote page...";
                //Get all of the response HTML
                string html;
                using (var r = new StreamReader(wr.GetResponse().GetResponseStream()))
                    html = r.ReadToEnd();
    
                //Format it into a HTML Document to query element details easily
                var document = new HtmlDocument();
                document.LoadHtml(html);
               
                //scc is submitted with the result.
                var scc = document.DocumentNode.SelectSingleNode("//input[@name='secure_captcha_check']");
                //ticki is submitted with the result (literally the text in the submit button)
                var ticki = document.DocumentNode.SelectSingleNode("//input[@name='ticki']");
                //Get the grecaptcha element
                var grecaptcha = document.DocumentNode.SelectSingleNode("//div[@class='g-recaptcha']");            
    
                //scc is submitted with the vote. It changes sometimes, do not hard code it.
                _scc = scc.GetAttributeValue("value", "");
                //ticki value is the text in the submit button. It's submitted with the final vote
                _ticki = WebUtility.UrlEncode(ticki.GetAttributeValue("value", ""));
                //the google key is needed for the captcha solver
                _googleKey = grecaptcha.GetAttributeValue("data-sitekey", "");
    
                Console.Title = "Vote page received";
            }
    
            /// <summary>
            /// Submit the captcha for solving, wait for it to be solved and get the solution.
            /// </summary>
            private void SolveCaptcha()
            {
                dynamic response;
                var result = SubmitCaptcha(_googleKey);
                Console.Title = "Captcha request submitted";
                var parts = result.Split('|');
                ulong captchaId;
                if (parts.Count() < 2 || !ulong.TryParse(parts[1], out captchaId))            
                    throw new Exception("Invalid Captcha Response: " + result);  
                do
                {
                    Thread.Sleep(3000);
                    response = RequestCaptchaSolve(captchaId);
                    string status = response.status;
                    if (status == "1")
                    {
                        Console.Title = "Captcha answer received";
                        break;
                    }
                    else
                        Console.Title = "Waiting on captcha answer....";
                }
                while (true);
               
                string solution = response.request;
                if (solution == null)
                    solution = response.solution.text;
                _captchaSolution = solution;
            }
    
            /// <summary>
            /// Submit the captcha to be solved through 2captcha
            /// </summary>
            /// <param name="googleKey">googleKey is retreived from the top100 in.php page and is used to solve the captcha</param>
            /// <returns></returns>
            private string SubmitCaptcha(string googleKey)
            {
                dynamic result;        
                //Create the web request. We dont need any proxy for it.
                var wr = GetWebRequest("http://2captcha.com/in.php", "2captcha.com", false);          
                wr.Referer = "http://2captcha.com/in.php";
                wr.AutomaticDecompression = DecompressionMethods.GZip;
    
                //Encode the avtual POST values. The captcha key, google key and the url that the captcha was found on.
                var postData = "key=" + _captchaKey + "&method=userrecaptcha&googlekey=" + googleKey + "&pageurl=" + GetInURL();
                var data = Encoding.ASCII.GetBytes(postData);
                wr.ContentLength = data.Length;
                wr.Method = "POST";
                wr.ContentType = "application/x-www-form-urlencoded";
                using (var stream = wr.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
                _solveStartedAt = DateTime.UtcNow;
                //Get the response value from which we can pull the token to query for successful solve.
                result = new StreamReader(wr.GetResponse().GetResponseStream()).ReadToEnd();
                return result;
            }
    
            /// <summary>
            /// Triggered every 5-10 seconds, we want to know if the captcha is solved yet and if so we need the solution value
            /// </summary>
            /// <param name="captchaId">This is the token from SubmitCaptcha(googleKey). Used incase of multi threading so we know which token we're looking for solution to</param>
            /// <returns></returns>
            private dynamic RequestCaptchaSolve(ulong captchaId)
            {
                string resultJson;
                dynamic result;
                var wr = WebRequest.CreateHttp("http://2captcha.com/res.php?key=" + _captchaKey + "&action=get&id=" + captchaId + "&json=1");  
                resultJson = new StreamReader(wr.GetResponse().GetResponseStream()).ReadToEnd();
                try
                {
                    result = JsonConvert.DeserializeObject(resultJson);
    
                    int? errorId, errorCode;
                    string errorDesc;
    
                    errorId = result.errorId;
                    errorCode = result.errorCode;
                    errorDesc = result.errorDesciption;
    
                    if (errorId != null && errorId != 0)
                        throw new InvalidOperationException($"2Captcha: {errorId} - {errorCode} - " + errorDesc);
                }
                catch
                {
                    result = null;
                }
                return result;
            }
    
    
            /// <summary>
            /// Submit the final vote to top100 using the captcha solve info and details we got from in.php
            /// </summary>
            private void PostInData()
            {
                //Initialize the webrequest and make sure its using the same proxy as the in.php request.
                var wr = GetWebRequest(GetPostURL(), "www.xtremetop100.com", true);          
                wr.Referer = GetInURL();
    
                //Populate the post data. SiteID we're voting for, the scc value, ticki value and the captcha solve value
                wr.Method = "POST";
                var postData = "site=" + _siteId + "&secure_captcha_check="+ _scc + "&ticki=" + _ticki + "&g-recaptcha-response=" + _captchaSolution;
                var data = Encoding.ASCII.GetBytes(postData);
                wr.ContentType = "application/x-www-form-urlencoded";
                wr.ContentLength = data.Length;
                using (var stream = wr.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
               
                Console.Title = "Submitting Vote...";
    
                //Get the response page. If its a blank/empty page we're blocked or it failed. If its long then its the proper forwarded page (it will send to homepage)
                string responseHtml;
                using (var sr = new StreamReader(wr.GetResponse().GetResponseStream()))
                    responseHtml = sr.ReadToEnd();
    
                Console.Title = "Vote Submitted";
    
                IsVoteSuccessful = responseHtml.Length > 1000;
                Console.WriteLine("Submitted vote at: " + DateTime.Now.ToShortTimeString() + " Success: " + IsVoteSuccessful);
                Console.WriteLine("Seconds to solve: " + (DateTime.UtcNow - _solveStartedAt).TotalSeconds);
                if(!IsVoteSuccessful)
                {
                    Console.WriteLine("Vote Failed: Response HTML is....");
                    Console.WriteLine(responseHtml);
                }
            }
    
    
            HttpWebRequest GetWebRequest(string url, string host,bool useProxy = false)
            {
                var request = WebRequest.CreateHttp(GetPostURL());
                if (useProxy)
                    request.Proxy = new WebProxy(_proxyDetails);
                request.CookieContainer = _cookies;
                request.Host = host;
                request.UserAgent = USER_AGENT;
                request.Accept = ACCEPT_HEADER;
                request.AllowAutoRedirect = true;
                request.Headers["Accept-Language"] = "en-us,en;q=0.5";
                request.Headers["Accept-Encoding"] = "gzip, deflate";
                return request;
            }
        }