最近在学HTTP协议,发现我可以写一个程序,模拟用户的注册啊,发帖子之类的程序!! 上网搜了搜,原来这种程序叫网页注册机.可以疯狂地自注册用户,也可以疯狂发广告贴等,都是用程序直接完成的.其实本质就是模似浏览器提交注册的过程.
好,我就去写吧,我发现这注册机这玩意最难的就是怎么破解验证码的问题.算了,菜鸟就找个没有验证码的网站吧! 于是我瞄上了我们学校的论坛,看到注册时是不用验证码的,好吧就你了!(后来发现这论坛真让人蛋疼) . 学校论坛是用PHP写的.抓包分析我注册时的数据包,然后模拟这次的注册过程,但最后失败!!!最后发现是要与cookie里的资料相关的.看它都给我发了什么鬼玩意的COOKIE:
Set-Cookie: nP6q_2132_sid=33GRgH; expires=Wed, 09-May-2012 12:55:47 GMT; path=/
Set-Cookie: nP6q_2132_lastact=1336481747%09member.php%09register; expires=Wed, 09-May-2012 12:55:47 GMT; path=/
Set-Cookie: nP6q_2132_cloudstatpost=deleted; expires=Mon, 09-May-2011 12:55:46 GMT; path=/
Set-Cookie: nP6q_2132_sid=33GRgH; expires=Wed, 09-May-2012 12:55:47 GMT; path=/
还有一大堆,分析了这COOKIE很久,改了很多KEY值,还是不行,说我来路不明或表单错误. 我禁了COOKIE用浏览器注册也是这样的错误.搞不懂这COOKIE,而且这论坛同一IP3小时内只能注册一个用户!!太坑爹了,本想用代理搞定,但用了代理还是说我3小时后再注册吧,我当时就哭了,我跪下了不弄你了可以了吧!!
经过第一次失败之后热情退去了不少,但我还是坚持了下来,找找其他学校的论坛看看吧~~~于是我来到了华南理工大学的论坛,他娘的有十分变态的验证码和验证问答
算了,这些不是人类能弄的.工科院校的这么牛B,找个文科院校的吧!!于是我找到了广东某学院的论坛,是ASP写的,论坛十分冷清,都在开始叫卖了,我从whois上看到这域名2013才到期.
再看他注册页面时的验证码:
这验证码太简单了,可以下手.
抓包分析验证码文件,下载下来是code.asp文件,改成BMP文件后就看到了,用WINHEX打开后研究了好久BMP文件的二进制代码是怎么弄的
最后发现,从0-53(十进制) 是BMP文件头,54以下是图片内容,每三个字节为一个像素,那验证码的位图文件是40*10的,图片内容是 从54到1253,每个数字点用300字节.而且图像表示是从最后一行开始的.了解了这些后,就好容易破解了.
当收到验证码图片后,再对其进行去色,变成黑白色.
之后对其化简,因为每3个字节表示一个像素,所我就用一个二维数组存储,把3个字节变成1个字节的0101来表示.
typedef struct number{
char num[10][10];
}NUM;
然后再写一程序取得从0-9的数字10*10的表示:
//0
1,0,0,0,0,1,1,1,1,1,
0,1,1,1,1,0,1,1,1,1,
0,1,1,1,1,0,1,1,1,1,
0,1,1,1,1,0,1,1,1,1,
0,1,1,1,1,0,1,1,1,1,
0,1,1,1,1,0,1,1,1,1,
0,1,1,1,1,0,1,1,1,1,
0,1,1,1,1,0,1,1,1,1,
0,1,1,1,1,0,1,1,1,1,
1,0,0,0,0,1,1,1,1,1,
//1
1,1,0,1,1,1,1,1,1,1,
0,0,0,1,1,1,1,1,1,1,
1,1,0,1,1,1,1,1,1,1,
1,1,0,1,1,1,1,1,1,1,
1,1,0,1,1,1,1,1,1,1,
1,1,0,1,1,1,1,1,1,1,
1,1,0,1,1,1,1,1,1,1,
1,1,0,1,1,1,1,1,1,1,
1,1,0,1,1,1,1,1,1,1,
0,0,0,0,0,1,1,1,1,1,
//2
1,0,0,0,0,1,1,1,1,1,
0,1,1,1,1,0,1,1,1,1,
1,1,1,1,1,0,1,1,1,1,
1,1,1,1,1,0,1,1,1,1,
1,1,1,1,0,1,1,1,1,1,
1,1,1,0,1,1,1,1,1,1,
1,1,0,1,1,1,1,1,1,1,
1,0,1,1,1,1,1,1,1,1,
0,1,1,1,1,1,1,1,1,1,
0,0,0,0,0,0,1,1,1,1,
................下面还有略
把取得的验证码图片转换成上面的格式,再进行对比,就知道对应的验证码的数字了.基本代码如下:
- void getCode( char *buff,int recvSize){
- unsigned char *p,*pNum,*pBase;
- int board,flag=0,i,j;
- int h,l,n;//行,列,第几个数
- char mapbuff[40*10];
- p = (unsigned char *)buff;
- //4e6一个回车为分界,后面内容为图像文件
- for(board=1 ; board<recvSize+1; board++){
- if( (*p=='4') && (*(p+1)=='e') && (*(p+2)=='6') && (*(p+3)==0x0d) && (*(p+4)==0x0a) ){
- p = p+5;