HTTP外挂的简单实现

      昨天晚上,在校内网狗狗应用上用按键精灵刷骨头,每五分钟还要验证一次。我突然想是不是可以直接用程序提交呢。先准备用sniff抓包的,结果装了两次都出错了。后来发现有一个叫HTTPLook的软件。于是直接拿它来看IE的操作,了解到每点击一次飞盘,就会提交一次。其中有一个内容code每次都在变化,而且还是16进制32位的字符。我觉得像MD5密文。我试着提交相同的包,结果发现没有反应,应该有防止重放攻击的可能。我将swf的flash下载下来,然后利用SWFDecompiler对其进行反编译。然后找到了内部的数据结构和相互关系。然后用perl写了个脚本。工作得不错,但是发现骨头上不去,老是失败。到论坛一看。郁闷,原来那个作者调高了失败的概率,得到骨头的平均概率变成了0%!!!也就是说扔100次,可能你的骨头也不会有多大的变化。引起了很多人的不满,这个游戏也就失去了意义。

      很气人吧。鄙视!!!

      没办法只好去刷老鼠了。捉老鼠是每10分钟可以吹一次号角,也就是撞一次事件。这个比原来的简单多了,不需要交互,只要每10分钟提交一次HTTP报文就可以了。

      好了下面说一下,如何做外挂。对于HTTP的外挂相对而言比较简单,就是要组织报文和提交,主要就是如何组织报文的问题。首先,你要知道IE发送了什么报文,又收到什么报文。很多内容,不是在IE上可以看到的,必须要工具。前面说到,一个工具就是HttpLook。这是一个非常简单的工具,在需要抓包时,点击绿色的开始按钮。然后操作IE。结束之后,点击红色(现在灰色)的结束按钮即可停止。

     右边的内容就是报文。

     下一步,就是多次提交某一个动作,比较报文的前后异同。有的有Cookie,有的有时间戳等,如果是动态的,那么就需要自己构造实时的内容,当然前提是你了解这些数据的含义和生成的机理。比较文件内容可以用编辑器自带的,也可以用专门的文件比较器Araxis Merge。比如捉老鼠就是很简单的内容,没有动态内容,那么就可以直接重放。而刷骨头就比较复杂,里面有不少参数,还有加密内容,需要正确构造,否则就失败了。

     接着就是写程序。我这里使用了Perl,因为前两天看到一些,所以拿来练手。先看捉老鼠,了解一些HTTP的程序实现。

#!/usr/bin/perl
#catch mouse every 10 minites


use LWP;

#GET /soundhorn.do HTTP/1.1
#header, copy from HttpLook

@headers = (
"Accept"=>"image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/x-silverlight, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, */*",
"Referer"=>"http://mouse.xiaonei.com/home.do",
"Accept-Language"=> "en-US",
"UA-CPU"=> "x86",
"Accept-Encoding"=>"gzip, deflate",
"User-Agent"=>"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648)",
"Host"=> "mouse.xiaonei.com",
"Connection"=> "Keep-Alive",
"Cookie"=> "[把抓的Cookie内容填在这里即可]",);

#Get URL
$url="http://mouse.xiaonei.com/soundhorn.do";

while(1)
{
#display time
$tt = localtime(time);
print $tt,"\n";

#Create Agent
$agent = LWP::UserAgent->new;

#Create Request
$request = HTTP::Request->new(GET=>$url);

#Add Headers
$request->header(@headers);

#Request
$res = $agent->request($request);

#Results
$res->is_success or die "error:", $res->message,"\n";
#$file = $res->content;
#print $file;

#wait 10min

sleep(600);
}

    上面的代码还是比较容易看懂的,有了这个模板就可以了,要仔细研究的话就去看Perl网络编程(Addison Wesley - Network.Programming.with.Perl.2000)。其他的刷屏,提交等动作,照上面改一改就行了。刷狗骨头就更加复杂了。还是我解析了SWF之后才知道如何处理数据。

#!/usr/bin/perl
#crack dog

use XML::Simple;
use Data::Dumper;
use Time::HiRes qw(gettimeofday);
use Digest::MD5  qw(md5_hex);
use LWP;

$pid=[PID];
$actor_Fid=[AID];
$method="pelt";
$appurl="http://dog.xiaonei.com/";
$xmlprourl="pet-profile.do?method=dogXML&";

$xmlurl=$appurl.$xmlprourl;
$xmlurl=$xmlurl."actor%5Fid=".$actor_Fid."&";
$xmlurl=$xmlurl."pid=".$pid."&";

(
$seconds, $microseconds= gettimeofday();
$milliseconds=int($microseconds/1000);

#load user info
$xmlurl=$xmlurl."t=".$seconds.$milliseconds;

$agent = LWP::UserAgent->new;
$request = HTTP::Request->new(GET=>$xmlurl);

#context
@headers = ([HEADER]);

$request->header(@headers);
$res = $agent->request($request);
$res->is_success or die "error:", $res->message,"\n";
#print $xmlurl;
$file = $res->content;

$xs1 = XML::Simple->new();
$doc = $xs1->XMLin($file);
#print Dumper($doc),"\n";
$pet = $doc->{'pet_id'}->{'content'};
$bone = $doc->{'num_bones_available'}->{'content'};
$key = $doc->{'key'};

print "init key:".$key."\tbone=".$bone."\n";

$xmlurl = $appurl."pet-profile.do";
@headers = ([Another Header]);

$catch=0;
$failed=0;
$maxtime = 1000;
for($i=0;$i<$maxtime;$i++)
{
  
$code = $key."#".$pet."#".$actor_Fid;
  
$code = md5_hex($code);
  
  
$content="code=".$code."&pid=".$pid."&actor%5Fid=".$actor_Fid."&method=".$method;
  
#print "URL: ".$content."\n";
  
  
$agent = LWP::UserAgent->new;
  
$request = HTTP::Request->new(POST=>$xmlurl);
  
  
$request->header(@headers);
  
$request->content($content);
  
$res = $agent->request($request);
  
$res->is_success or die "error:", $res->message,"\n";
  
#print $xmlurl;
  $file = $res->content;

  
#returns
  @rst=split(/[\|]/,$file);
  
$key=$rst[1];#new key
  $goal=$rst[0];#goal
  $num=$rst[2];#bone numbers
  
  
if($goal>0)
  {
    
$catch++;
  }
else
  {
    
$failed++;
  }
  
  
print $catch.":".$failed."\tgoal=".$goal."\tbone=".$num."\n";
  
  
#$range = 5;
  #$random_number = 5+int(rand($range));
  #sleep($random_number);

  sleep(5);#MUST WAIT at least 5 Sec
}

 

 

posted on 2008-10-15 19:27  逍遥子  阅读(3254)  评论(1编辑  收藏  举报

导航