一、起因
一到年底,各大网站又开始组织评选各种最佳XX,比如新浪组织的2015十大跑团投票。昨日在跑步群里,组织的领袖人物号召大家去投票,于是好多人都投了,后来又过了一会,领袖又出来无奈的说,大家每人投1000票吧,瞬间集体崩溃,原来投票还可以这么玩!

于是仔细研究了下这个网站投票,抓包发现,其所为的投票就是一个普通的HTTP GET 请求,没有缓存,没有认证,没有限制,我真无语了,这还是新浪网站做的网页呢,这尼玛是实习生做的吧?最基本的验证、防刷票都没有。
而前面几名小跑团竟然都跟我XX大跑团差距几十万的投票量了,这些明显都是在刷票!而且是软件自动刷的!太气愤了。

二、行动
于是决定做个投票器,刷!刷!刷!帮助XX大跑团刷!帮助XX大跑团刷!帮助XX大跑团刷!
首先下载libcurl,编译生成静态库。
其次在网上找了个基于libcurl的HttpClient源码,如下
#define __HTTP_CURL_H__
#include <string>
class CHttpClient
{
public:
CHttpClient(void);
~CHttpClient(void);
public:
int Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse);
int Get(const std::string & strUrl, std::string & strResponse);
int Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath = NULL);
int Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath = NULL);
public:
void SetDebug(bool bDebug);
private:
bool m_bDebug;
};
#endif
#include <string>
#include "stdafx.h"
#include "HttpClient.h"
#include "curl/curl.h"
#include "curl/easy.h"
CHttpClient::CHttpClient(void) : m_bDebug(false)
{
}
CHttpClient::~CHttpClient(void)
{
}
static int OnDebug(CURL *, curl_infotype itype, char * pData, size_t size, void *)
{
if (itype == CURLINFO_TEXT)
{
//printf("[TEXT]{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s\n", pData);
}
else if (itype == CURLINFO_HEADER_IN)
{
printf("[HEADER_IN]{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s\n", pData);
}
else if (itype == CURLINFO_HEADER_OUT)
{
printf("[HEADER_OUT]{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s\n", pData);
}
else if (itype == CURLINFO_DATA_IN)
{
printf("[DATA_IN]{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s\n", pData);
}
else if (itype == CURLINFO_DATA_OUT)
{
printf("[DATA_OUT]{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s\n", pData);
}
return 0;
}
static size_t OnWriteData(void* buffer, size_t size, size_t nmemb, void* lpVoid)
{
std::string* str = dynamic_cast<std::string*>((std::string *)lpVoid);
if (NULL == str || NULL == buffer)
{
return -1;
}
char* pData = (char*)buffer;
str->append(pData, size * nmemb);
return nmemb;
}
int CHttpClient::Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse)
{
CURLcode res;
CURL* curl = curl_easy_init();
if (NULL == curl)
{
return CURLE_FAILED_INIT;
}
if (m_bDebug)
{
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);
}
curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());
curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
return res;
}
int CHttpClient::Get(const std::string & strUrl, std::string & strResponse)
{
CURLcode res;
CURL* curl = curl_easy_init();
if (NULL == curl)
{
return CURLE_FAILED_INIT;
}
if (m_bDebug)
{
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);
}
curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);
/**
* 当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。
* 如果不设置这个选项,libcurl将会发信号打断这个wait从而导致程序退出。
*/
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
return res;
}
int CHttpClient::Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath)
{
CURLcode res;
CURL* curl = curl_easy_init();
if (curl == NULL)
{
return -1;
}
if (m_bDebug)
{
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);
}
curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());
curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
if (NULL == pCaPath)
{
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
}
else
{
//缺省情况就是PEM,所以无需设置,另外支持DER
//curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);
curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);
}
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
return res;
}
int CHttpClient::Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath)
{
CURLcode res;
CURL* curl = curl_easy_init();
if (NULL == curl)
{
return CURLE_FAILED_INIT;
}
if (m_bDebug)
{
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);
}
curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
if (NULL == pCaPath)
{
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
}
else
{
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);
curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);
}
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
return res;
}
///////////////////////////////////////////////////////////////////////////////////////////////
void CHttpClient::SetDebug(bool bDebug)
{
m_bDebug = bDebug;
}
#include "stdafx.h"
#include <windows.h>
#include "HttpClient.h"
int _tmain(int argc, _TCHAR* argv[])
{
long long int s_count = 0;
while (true)
{
Sleep(100);
CHttpClient client;
std::string url = "http://survey.sina.cn/aj/submit?poll_id=xxxx&q_xxx=xxx";
std::string respon;
client.Get(url, respon);
size_t pos = respon.find("true");
printf("You are vote to XXXTeam {b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}lld times.result:{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s\r\n", ++s_count, (pos == std::string::npos) ? "ERROR" : "OK");
printf("respon:{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s\r\n", respon.c_str());
printf("\r\n");
}
return 0;
}
三、放大招
OK,再写个小test程序,一秒刷10次。后来测试发现,不管一秒请求多少次,貌似服务器每秒只接收一次,或者是同一个ip只接收一次。
好了,挂了一夜,票数直线上升,将近升了一半。
网友评论