自动回帖技术
前言:2012.9月,由于某些原因,我开始编写一个基于Discuz论坛的自动回帖器,这次的小工作让我对Cookie有了进一步的认识,充分认识到,利用它实在可以做太多的事了~啊哈哈~话不多说~进入主题吧!
0.验证码识别
3年前想做的验证码识别已经ok了,参考博文:http://blog.csdn.net/xxxxxx91116/article/details/78942753
1. 自动登录
要实现自动回帖,第一个要解决的问题是自动登陆,不知道你上网的时候有没有想过,为什么每个网站可以记录我们的账户信息,知道你是谁?你在做什么操作?其实一切的一切,都是因为Cookie值,只要每次操作,都发送专属于你的cookie值,系统就能识别你。下面是可行的3种登陆方法:
A.给出账号密码自动登录
优点:最方便,最符合逻辑
缺点:难度较大,要解决识别图片验证码的问题
B.记录账号cookie值,利用cookie值自动登陆
优点:简单
缺点:cookie值有过期时间,每隔一段时间需要更新一次,每次更新需要人为输入账号密码并记录cookie值
C.每次注册一堆新账号
优点:简单,不需要手工操作
缺点:cookie值有过期时间,每隔一段时间需要重新申请一堆账号,可能会发生重复的账号
2. 分析
由上面可知A方法难度很大,那么在没有办法解决验证码识别的情况下如何进行自动登录呢?换个角度想,有2种可行的方法,第一种:我们可以手动登陆,然后通过浏览器得到cookie值,在程序中写死即可。第二种:通过观察,这个网站的账号申请不需要验证码,这样的话,我们就可以写程序申请一堆账号获取Cookie值,就不要手动检查浏览器了。
由于不同网站的架构不同,所以对每个网站有不同的处理,这里使用wireshark进行捕包分析,下面模拟各个步骤:
A. 自动登录
图2-1
Cookie: 3j9D_2132_saltkey=84RMtc5t;3j9D_2132_auth=4c4d3DGYNBfUBovTPBaXKSXWccS%2FRMgyy%2Bcvl1jAGskT7Q5Q0ZBvL8AJz%2FEpZfuzhP1rxvo5OKKQ%2BwSjmTFFDMDtvQ; 3j9D_2132_lastvisit=1346832644;3j9D_2132_visitedfid=305D75;3j9D_2132_smile=1D1;3j9D_2132_sid=9r1uC2;3j9D_2132_ulastactivity=f76eJegRfs3OW0hfDqcTSQcZf7vXIpdTQpG%2Frz8FycyH99yQpmIV;pgv_pvi=8475715224;pgv_info=ssi=s4413658656;CNZZDATA4398266=cnzz_eid=14352506-1346836061-&ntime=1347792018&cnzz_a=0&retime=1347792021741&sin=<ime=1347792021741&rtime=3;3j9D_2132_lastact=1347792033%09home.php%09misc; 3j9D_2132_connect_is_bind=0;3j9D_2132_sendmail=1; 3j9D_2132_noticeTitle=1; tjpctrl=1347793900462 |
图2-2
报文内容如上图,可以看到cookie的内容非常的多,由于使用的是第二种方法,所以手动记录那么多的cookie很麻烦,于是考虑找出必要的cookie,这里可以利用chrome浏览器来帮忙,打开浏览器的设置,显示高级设置,内容设置,所有cookie和网站数据,选择对应的网址,可以看到对应的cookie值,形式如下:
图2-3
我们可以删除一些cookie,来测试有哪些cookie是必须的,经过测试后,发现3j9D_2132_auth和3j9D_2132_saltkey是必须的2个cookie变量,也就是报文中只要有这两个cookie值服务器就可以识别我们的账户。
B.登陆目标帖子的过程
请求:
图2-4
由上图可以看出,我们在浏览http://www.*******.cn/forum.php?mod=viewthread&tid=54217这个URL的帖子时,各个参数如图2-4所示,我们只需要在代码中构造一个类似的报文即可,但是要注意加上3j9D_2132_auth和3j9D_2132_saltkey这两个cookie变量。
回复:
HTTP/1.1 200 OK Server: nginx/1.2.0 Date: Sun, 16 Sep 2012 12:08:57 GMT Content-Type: text/html; charset=gbk Transfer-Encoding: chunked Connection: keep-alive Set-Cookie: 3j9D_2132_lastact=1347797336%09forum.php%09viewthread; expires=Mon, 17-Sep-2012 12:08:56 GMT; path=/ Set-Cookie: 3j9D_2132_stats_qc_reg=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/ Set-Cookie: 3j9D_2132_cloudstatpost=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/ Set-Cookie: 3j9D_2132_connect_is_bind=0; expires=Mon, 16-Sep-2013 12:08:56 GMT; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Set-Cookie: xwb_tips_type=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT Set-Cookie: 3j9D_2132_sid=eeyVey; expires=Mon, 17-Sep-2012 12:08:56 GMT; path=/ Content-Encoding: gzip
48b8 }wSZNk|F4viIG##?HIoH1m^v6Iri(]yHGlLK:got~g_oSWv}}O{oJL>i$z^(~|CCCC=}7LmYoj6gwL>NW55NV#[,$.=chw$y {mQJ_5#(>jH)8;1>;s~7P3/~(/Zdf@i }bOj1 Gi'fL2/H}=AYCbB.B_23p29pZ>Nf=;|I[#r@TwOS5D*3uahi42xbL 4*5%hVO)2ZN5^w2+z^vZ0]jjZQ3qKO!= +m"g |
图2-5
上图2-5就是服务器给出的回复,主要要关心的是红色部分,Transfer-Encoding: chunked表示报文长度不固定,Content-Encoding:gzip表示报文内容使用gzip,在这句话后面的48b8表示报文长度,所以接下来的48b8(十六进制)个字节是报文的长度,那么整个网页信息就在下面的48b8个字节中了,获得报文以后,由于它使用gzip压缩,我们还要对其进行解压。
C.回帖的过程
请求:
图2-6
图2-7
由图2-6的request URI可以看出,我们需要知道fid,tid,extra,replysubmit等变量的值,这些值都可以在上一次的帖子源码中找到,由图2-7可以看出我们在回帖的时候包含的报文内容,需要message—回复内容,posttime---回复时间,formhash---可以有上一个页面的源码得到,subject为空即可。但是要注意这里的回帖内容需要进行url编码。
由上面一个部分可以看出,我们要将gzip格式的数据包解压缩,这样才能获得源码。下面是从chrome解析的源码中看到的需要的变量:
图2-8
这样我们就可以构造一个类似的报文发送到服务器,并且服务器将会显示我们的回复。