美文网首页
《某大型社交网站投票软件》

《某大型社交网站投票软件》

作者: 海阔天空的博客 | 来源:发表于2021-10-28 15:35 被阅读0次

一、起因

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

1.png
于是仔细研究了下这个网站投票,抓包发现,其所为的投票就是一个普通的HTTP GET 请求,没有缓存,没有认证,没有限制,我真无语了,这还是新浪网站做的网页呢,这尼玛是实习生做的吧?最基本的验证、防刷票都没有。

而前面几名小跑团竟然都跟我XX大跑团差距几十万的投票量了,这些明显都是在刷票!而且是软件自动刷的!太气愤了。

2.png

二、行动

于是决定做个投票器,刷!刷!刷!帮助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只接收一次。

好了,挂了一夜,票数直线上升,将近升了一半。

相关文章

网友评论

      本文标题:《某大型社交网站投票软件》

      本文链接:https://www.haomeiwen.com/subject/pvvdaltx.html