TwitchTime
Newbie
- Apr 3, 2014
- 10
- 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.
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.
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"96?iG~AqwG@(a4Ag*qiS4evNnI"nZkOiLMk}Id~PH5j?clR$W%AEB[%#&fO vvaLhis0&V?rv0VU=}qrHu}bllji#E[{w
SlfjKz^\RWAR816}M5%W+k)Da;#"LV^a9c@cx74j}`LAM_Cyw84oB&#|vs6;xRh@d0|\: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)!E+D@qfhP8\+"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;
}
}