这篇文章讲述如何利用C++编写一个自动登陆到PHPChina中文开发者社区的程序!
首先需要工具:
1.IE
2.HttpWatch
3.C/C++集成开发环境
1.首先打开IE然后在IE上方的地址栏中输入“http://www.phpchina.com/”
2.然后在点击右上方的工具菜单下拉找到HttpWatch Professional选项 开启HttpWatch抓包功能
3.会看到弹出的HttpWatch抓包程序界面,HttpWatch抓包程序是嵌入到IE中的但不是IE自带的需要自行到互联网中下载!
4.点击网页右上方的登录会跳转到登录页面!
5.跳转到登录页面后先输入你的账号和密码!
6.开启HttpWatch抓包功能(Recorn按钮)在点击登录!
7.开启抓包功能后点击登录,登录完成之后点击Stop按钮停止抓包!
8.停止之后会发现很多HTTP协议请求其中包含post请求和get请求然后我们开始分析到底哪一个请求协议是提交登录信息的!
因为在登录的时候浏览器会向服务器发送一或两个请求,我们只需要分析前两个http协议首先单击第一个POST协议在Overview表项中可以查到第一个POST请求协议的概要信息
如上图所示可以
URL:http://www.phpchina.com/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=LtOdv&inajax=1
Result:200
请求的URL是http://www.phpchina.com/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=LtOdv&inajax=1
返回的Http请求状态码Result:200代表成功!
Action可以看到访问信息!
这个时候把表项切换到POST data查看具体请求数据看一下有没有我们的用户名和密码
username里找到了用户名 password里找到了加密的密码!formhash里的数据是请求校验码(这个重要也就是请求数据时服务器会根据formhash的值来判断请求数据的合法性)
从这些数据表明第一条POST协议是真正的提交用户名和密码协议,那么后面的GET数据则是其它浏览器请求数据和我们没有关系!所以就不分析其它GET数据了!
这里将POST data里的数据整合出来
根据POST提交协议 post提交数据时的顺序是formhash时放在第一位,referer第二位,username第三位,password第四位,questionid第五位,answer第六位,其次编码是按照URL编码方式来编码的,并且使用&来拼接!
整合出来的数据
formhash=ed6b2a1c&referer=http%3A%2F%2Fwww.phpchina.com%2F&username=17%E5%B2%81boy&password=fbdeef8e9db7f3716abaf023a52b9982&questionid=0&answer=
可以看到很多//和登录名的汉字都提换成了URL编码,这个编码算法可以在百度上找到,或者去下载编码转换工具都可以!
具体信息就得到了
请求地址URL
http://www.phpchina.com/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=Lfku7&inajax=1
请求协议:
POST /member.php?mod=logging&action=login&loginsubmit=yes&loginhash=LZKvG&inajax=1 HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Referer: http://www.phpchina.com/member.php?mod=logging&action=login
Accept-Language: zh-CN
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729)
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Host: www.phpchina.com
Content-Length: 137
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: CNZZDATA1260206835=395559444-1503368013-%7C1503372017; CNZZDATA1253686164=28344171-1503363672-%7C1503372847; tjpctrl=1503332250329; pgv_pvi=2444701901; UM_distinctid=15e0515a0bef1-0b6f2a02ea70a1-38732142-140000-15e0515a0bf10f; Hm_lvt_8c71400238561a42650208f8e318a121=1503323857,1503324916,1503327293; Hm_lpvt_8c71400238561a42650208f8e318a121=1503330538; pgv_info=ssi=s54400200; NXZu_3812_sid=Zu0N0I; NXZu_3812_noticeTitle=1; NXZu_3812_saltkey=utUStUHT; NXZu_3812_lastvisit=1503371200; NXZu_3812_lastact=1503374811%09member.php%09logging; NXZu_3812_sendmail=1
请求数据: formhash=ed6b2a1c&referer=http%3A%2F%2Fwww.phpchina.com%2F&username=17%E5%B2%81boy&password=fbdeef8e9db7f3716abaf023a52b9982&questionid=0&answer=
你也可以在STREAM表项里直接找到HTTP报文协议和POST提交数据!
左边是提交信息(左边内容框最后一行是POST提交数据上面的都是HTTP发送的报文协议) 组合在一起就是一个完整的HTTP请求协议,右边的内容框是服务器接受到我们提交的POST数据数据所返回的数据流!
在左上方可以看到该网站的IP地址和端口号
该网站的IP为139.129.162.140,端口是80 以后的文章会写一个用c语言动态解析域名得到IP地址和端口号!
有了这些数据就可以开始写C++代码了
1.首先打开集成开发IDE环境(我这里是codeblocks10.0)
注意在发送的时候必须把HTTP协议一并发送过去。
代码如下:
#include <iostream>
#include <winsock.h>
int main()
{
WSADATA wData;
int _ERROR = WSAStartup(MAKEWORD(2,2),&wData);
if(_ERROR){
cout << "初始化SOCKET失败!" << endl;
}
char *POST = "POST /member.php?mod=logging&action=login&loginsubmit=yes&loginhash=LZKvG&inajax=1 HTTP/1.1\r\n"\
"Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\n"\
"Referer: http://www.phpchina.com/member.php?mod=logging&action=login\r\n"\
"Accept-Language: zh-CN\r\n"\
"User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729)\r\n"\
"Content-Type: application/x-www-form-urlencoded\r\n"\
"Accept-Encoding: gzip, deflate\r\n"\
"Host: www.phpchina.com\r\n"\
"Content-Length: 137\r\n"\
"Connection: Keep-Alive\r\n"\
"Cache-Control: no-cache\r\n"\
"Cookie: CNZZDATA1260206835=395559444-1503368013-%7C1503372017; CNZZDATA1253686164=28344171-1503363672-%7C1503372847; tjpctrl=1503332250329; pgv_pvi=2444701901; UM_distinctid=15e0515a0bef1-0b6f2a02ea70a1-38732142-140000-15e0515a0bf10f; Hm_lvt_8c71400238561a42650208f8e318a121=1503323857,1503324916,1503327293; Hm_lpvt_8c71400238561a42650208f8e318a121=1503330538; pgv_info=ssi=s54400200; NXZu_3812_sid=Zu0N0I; NXZu_3812_noticeTitle=1; NXZu_3812_saltkey=utUStUHT; NXZu_3812_lastvisit=1503371200; NXZu_3812_lastact=1503374811%09member.php%09logging; NXZu_3812_sendmail=1\r\n\r\n"\
"\n"\
"formhash=ed6b2a1c&referer=http%3A%2F%2Fwww.phpchina.com%2F&username=17%E5%B2%81boy&password=fbdeef8e9db7f3716abaf023a52b9982&questionid=0&answer=";
SOCKET clientSocket=socket(AF_INET,1,0);
struct sockaddr_in ServerAddr={0};
ServerAddr.sin_addr.S_un.S_addr=inet_addr("139.129.162.140");//使用的是TCP通信所以必须给出网站IP地址!
ServerAddr.sin_port=htons(80);; //网站端口!
ServerAddr.sin_family=AF_INET;
char bufRecv[3104]={0};
int errNo=0;
errNo=connect(clientSocket,(sockaddr*)&ServerAddr,sizeof(ServerAddr));
if(errNo==0)
{
//如果发送成功,则返回发送成功的字节数
if(send(clientSocket,POST,strlen(POST),0)>0)
{
cout<<"已经成功向服务器提交post数据!\n";;
}
//如果接受成功,则返回接受的字节数
if(recv(clientSocket,bufRecv,3069,0)>0)
{
cout<<"服务器返回的post数据:"<<bufRecv<<endl;
}
}
}
返回信息:
这个数据是不是和HttpWatch里的服务器返回数据流长度一样?只不过某些数据变了!有了这个信息就代表我们刚刚发送的协议是正确的且post数据被服务器接受并处理了!
下面这张是发送失败的列子
我将发送post数据给屏蔽掉只发送http协议
下面是运行返回信息
可以看到服务器什么都没有返回TCP一直在等着服务器返回信息,但是服务器收到了你的HTTP协议请求信息但是不知道你的post数据是什么,不知道作何处理,所以就什么都不返回!有的网站可能会返回400 BAD 或者404信息这些信息在HTTP协议中是接受到了错误的参数,或者拒绝访问!
注意这里TCP仅仅得到的是服务器是否处理我们的post数据而不是响应信息响应信息是告诉我们处理结果比如登录成功或者密码错误之类的信息,下一篇文章我将用wininet来写登录程序,直接使用HTTP协议进行通信得到HTTP响应信息!