目录
1.虚拟机服务器搭建网站,本机访问用Burp Suite抓包获取头信息。
2.Wireshark和Burp Suite处理HTTPS的过程与技术实现过程原理
-
目的
了解HTTPS是如何加密,SSL加密过程。
-
内容
1.虚拟机服务器搭建网站,本机访问用Burp Suite抓包获取头信息。
2.描述Wireshark和Burp Suite处理HTTPS的过程和两者的技术实现过程原理。
3.在QT中编写HTTP程序并运行。
-
器材(设备、元器件)
Wireshark、Burp Suite、IIS搭建网站的虚拟机windows2003系统
-
步骤
1.虚拟机服务器搭建网站,本机访问用Burp Suite抓包获取头信息。
①在虚拟机中搭建了网站,在本机中用火狐浏览器访问IP并用Burp Suite抓包。
②关闭抓包后,网站可访问
2.Wireshark和Burp Suite处理HTTPS的过程与技术实现过程原理
(1)Wireshark
原理:
HTTPS(Hypertext TransferProtocol over Secure Socket Layer,基于SSL的HTTP协议),端口443,需要向CA申请证书,通过SSL握手建立安全通道,利用协商密钥对数据进行对称加密通信。
SSL协议栈位置介于TCP和应用层之间,分为SSL记录协议层和SSL握手协议层。
SSL握手:
1、 初始化阶段。客户端创建随机数,发送ClientHello 将随机数连同自己支持的协议版本、加密算法和压缩算法发送给服务器。服务器回复ServerHello将自己生成的随机数连同选择的协议版本、加密算法和压缩算法给客户端。
2、 认证阶段。服务器发送ServerHello的同时可能将包含自己公钥的证书发送给客户端(Certificate),并请求客户端的证书(Certificate Request)。
3、 密钥协商阶段。客户端验证证书,如果收到Certificate Request则发送包含自己公钥的证书,同时对此前所有握手消息进行散列运算,并使用加密算法进行加密发送给服务器。同时,创建随机数pre-master-secret并使用服务器公钥进行加密发送。服务器收到这个ClientKeyExchange之后解密得到pre-master-secret。服务器和客户端利用1阶段的随机数,能够计算得出master-secret。
4、 握手终止。服务器和客户端分别通过ChangeCipherSpec消息告知伺候使用master-secret对连接进行加密和解密,并向对方发送终止消息(Finished)。
抓包分析:
使用wireshark过滤ssl流量,可以看到有几个明显的ssl会话建立包,例如client hello,server hello等;
①蓝色的就是我们客户端向服务器发送hello ,即浏览器向服务器请求一个安全的网页。
然后双击这个Client Hello看下传输的内容:
②服务器就把它的证书和公匙发回来,同时向服务端发送ACK报文以便服务端确认数据是否无误。
server hello包里能看到服务端选择的加密算法;
服务器发送ServerHello的同时可能将包含自己公钥的证书发送给客户端(Certificate);
③客户端验证证书,如果收到Certificate Request则发送包含自己公钥的证书,同时对此前所有握手消息进行散列运算,并使用加密算法进行加密发送给服务器;
④服务器端发送change_cipher_spec和finished消息。到这里握手结束。
(2)Burp Suite
原理:
BurpSuite的基本思路是伪装成目标https服务器,让浏览器(client)相信BurpSuite就是目标站点。
为了达成目标,BurpSuite必须:(1)生成一对公私钥,并将公钥和目标域名绑定并封装为证书;(2)让浏览器相信此证书,即通过证书验证。所以, BurpSuite需要在操作系统添加一个根证书,这个根证书可以让浏览器信任所有BurpSuite颁发的证书。具体流程如下:
之后,BurpSuite拥有了两套对称密钥,一套用于与client交互,另外一套与server交互,而在BurpSuite处可以获得https明文。
抓包分析:
①打开Burp Suite,连接百度:
②在Target中只查看baidu
③过滤显示:
④
3.在QT中编写HTTP程序并运行。
在pro文件中配置:
LIBS=-lpcap -lnet -lnids
代码
(C语言,源自《网络数据与协议分析》)
#include "nids.h"
#include "pcap.h"
#include "libnet.h"
char ascii_string[10000];
char *char_to_ascii(char ch)
/* 此函数的功能主要用于把协议数据进行显示 */
{
char *string;
ascii_string[0] = 0;
string = ascii_string;
if (isgraph(ch))
/* 可打印字符 */
{
*string++ = ch;
}
else if (ch == ' ')
/* 空格 */
{
*string++ = ch;
}
else if (ch == '\n' || ch == '\r')
/* 回车和换行 */
{
*string++ = ch;
}
else
/* 其它字符以点"."表示 */
{
*string++ = '.';
}
*string = 0;
return ascii_string;
}
void parse_client_data(char content[],int number)
{
char temp[1024];
char str1[1024];
char str2[1024];
char str3[1024];
int i,j,k;
char entity_content[1024];
if(content[0]!='H' && content[1]!='T' && content[2]!='T' && content[3]!='P')
{
printf("实体内容为(续):\n");
for(i=0;i<number;i++)
{
printf("%s",char_to_ascii(content[i]));
}
printf("\n");
}
else
{
for(i=0;i<strlen(content);i++)
{
if(content[i]!='\n')
{
k++;
continue;
}
for(j=0;j<k;j++)
{
temp[j]=content[j+i-k];
}
temp[j]='\0';
if(strstr(temp,"HTTP"))
{
printf("状态行为:");
printf("%s\n",temp);
sscanf(temp,"%s%s",str1,str2);
printf("HTTP协议为:%s\n",str1);
printf("状态代码为:%s\n",str2);
}
if(strstr(temp,"Date"))
{
printf("当前的时间为(Date):%s\n",temp+strlen("Date:"));
printf("%s\n",temp);
}
if(strstr(temp,"Server"))
{
printf("服务器为(Server):%s\n",temp+strlen("Server:"));
printf("%s\n",temp);
}
if(strstr(temp,"Cache-Control"))
{
printf("缓存机制为(Cache-Control):%s\n",temp+strlen("Cache-control:"));
printf("%s",temp);
}
if(strstr(temp,"Expires"))
{
printf("资源期限为(Expires):%s\n",temp+strlen("Expires:"));
printf("%s",temp);
}
if(strstr(temp,"Last-Modified"))
{
printf("最后一次修改的时间为(Last-Modifid):%s\n",temp+strlen("Last-Modifid:"));
printf("%s",temp);
}
if(strstr(temp,"ETag"))
{
printf("ETag为(ETag):%s\n",temp+strlen("ETag:"));
printf("%s",temp);
}
if(strstr(temp,"Accept-Ranges"))
{
printf("Accept-Ranges(Accept-Ranges):%s\n",temp+strlen("Accept-Ranges:"));
printf("%s",temp);
}
if(strstr(temp,"Content-Length"))
{
printf("内容长度为(Content-Length):%s\n",temp+strlen("Content-Length:"));
printf("%s",temp);
}
if(strstr(temp,"Connection"))
{
printf("连接状态为(Connection):%s\n",temp+strlen("Connection:"));
printf("%s",temp);
}
if(strstr(temp,"Content-Type"))
{
printf("内容类型为(Content-Type):%s\n",temp+strlen("Content-Type:"));
printf("%s",temp);
}
if((content[i]=='\n') && (content[i+1]='\r'))
{
if(i+3==strlen(content))
{
printf("无实体内容\n");
break;
}
for(j=0;j<number-i-3;j++)
{
entity_content[j]=content[i+3+j];
}
entity_content[j]='\0';
printf("实体内容为:\n");
for(i=0;j<j;i++)
{
printf("%s",char_to_ascii(entity_content[i]));
}
printf("\n");
break;
}
k=0;
}
}
}
void parse_server_data(char content[],int number)
{
char temp[1024];
char str1[1024];
char str2[1024];
char str3[1024];
int i,j,k;
char entity_content[1024];
for(i=0;i<strlen(content);i++)
{
if(content[i]!='\n')
{
k++;
continue;
}
for(j=0;j<k;j++)
{
temp[j]=content[j+i-k];
}
temp[j]='\0';
if(strstr(temp,"GET"))
{
printf("请求行为:");
printf("%s\n",temp);
sscanf(temp,"%s%s%s",str1,str2,str3);
printf("使用的命令为:%s\n",str1);
printf("获得的资源为:%s\n",str2);
printf("HTTP协议类型为:%s\n",str3);
}
if(temp,"Accept:")
{
printf("接收的文件包括(Accept):%s",temp+strlen("Accept:"));
printf("%s\n",temp);
}
if(temp,"Referer:")
{
printf("转移地址为(Referer):%s",temp+strlen("Referer:"));
printf("%s\n",temp);
}
if(temp,"Accept-Language:")
{
printf("使用的语言为(Accept-Language):%s",temp+strlen("Accept-Language:"));
printf("%s\n",temp);
}
if(temp,"Accept-Encoding:")
{
printf("接收的编码方式为(Accept-Encoding):%s",temp+strlen("Accept-Encoding:"));
printf("%s\n",temp);
}
if(temp,"If-Modified-Since:")
{
printf("上次修改的时间为(If-Modified-Since):%s",temp+strlen("If-Modified-Since:"));
printf("%s\n",temp);
}
if(temp,"If-None-Match:")
{
printf("If-None-Match为(If-Modified-Since):%s",temp+strlen("If-None-Match:"));
printf("%s\n",temp);
}
if(temp,"User-Agent:")
{
printf("用户的浏览器信息为(User-Agent):%s",temp+strlen("User-Agent:"));
printf("%s\n",temp);
}
if(temp,"Host:")
{
printf("访问的主机为(Host):%s",temp+strlen("Host:"));
printf("%s\n",temp);
}
if(temp,"Connection:")
{
printf("连接状态为(Connection):%s",temp+strlen("Connection:"));
printf("%s\n",temp);
}
if(temp,"Cookie:")
{
printf("Cookie为(Cookie):%s",temp+strlen("Cookie:"));
printf("%s\n",temp);
}
if((content[i]=='\n') && (content[i+1]='\r') && (content[i+2=='\n']))
{
if(i+3==strlen(content))
{
printf("无实体内容\n");
break;
}
for(j=0;j<strlen(content);j++)
{
entity_content[j]=content[i+3+j];
}
entity_content[j]='\0';
printf("实体内容为:\n");
printf("%s",entity_content);
printf("\n");
break;
}
k=0;
}
}
void http_protocol_callback(struct tcp_stream *tcp_http_connection,void **param)
{
char address_content[1024];
char content[65535];
char content_urgent[65535];
struct tuple4 ip_and_port=tcp_http_connection->addr;
strcpy(address_content,inet_ntoa(*((struct in_addr*)&(ip_and_port.saddr))));
sprintf(address_content+strlen(address_content),":%i",ip_and_port.source);
strcat(address_content,"<----->");
strcat(address_content,inet_ntoa(*((struct in_addr*)&(ip_and_port.daddr))));
sprintf(address_content+strlen(address_content),"%i:",ip_and_port.dest);
strcat(address_content,"\n");
if(tcp_http_connection->nids_state==NIDS_JUST_EST)
{
if(tcp_http_connection->addr.dest!=80)
{
return;
}
tcp_http_connection->client.collect++;
tcp_http_connection->server.collect++;
printf("\n\n\n\==============================\n");
printf("%s建立连接...\n",address_content);
return;
}
if(tcp_http_connection->nids_state==NIDS_CLOSE)
{
printf("-------------------------------\n");
printf("%s连接正常关闭...\n",address_content);
return;
}
if(tcp_http_connection->nids_state==NIDS_RESET)
{
printf("--------------------------------\n");
printf("%s连接被RST关闭...\n",address_content);
return;
}
if(tcp_http_connection->nids_state==NIDS_DATA)
{
struct half_stream *hlf;
if(tcp_http_connection->client.count_new)
{
hlf=&tcp_http_connection->client;
strcpy(address_content,inet_ntoa(*((struct in_addr*)&(ip_and_port.saddr))));
sprintf(address_content+strlen(address_content),":%i",ip_and_port.source);
strcat(address_content,"<-----");
strcat(address_content,inet_ntoa(*((struct in_addr*)&(ip_and_port.daddr))));
sprintf(address_content+strlen(address_content),"%i:",ip_and_port.dest);
strcat(address_content,"\n");
printf("\n");
printf("%s",address_content);
printf("浏览器接收数据...\n");
printf("\n");
memcpy(content,hlf->data,hlf->count_new);
content[hlf->count_new]='\0';
parse_client_data(content,hlf->count_new);
}
else
{
hlf=&tcp_http_connection->server;
strcpy(address_content,inet_ntoa(*((struct in_addr*)&(ip_and_port.saddr))));
sprintf(address_content+strlen(address_content),":%i",ip_and_port.source);
strcat(address_content,"<-----");
strcat(address_content,inet_ntoa(*((struct in_addr*)&(ip_and_port.daddr))));
sprintf(address_content+strlen(address_content),"%i:",ip_and_port.dest);
strcat(address_content,"\n");
printf("\n");
printf("%s",address_content);
printf("服务器接收数据...\n");
printf("\n");
memcpy(content,hlf->data,hlf->count_new);
content[hlf->count_new]='\0';
parse_server_data(content,hlf->count_new);
}
}
return;
}
int main()
{
//close xiaoyanhe
struct nids_chksum_ctl temp;
temp.netaddr = 0;
temp.mask = 0;
temp.action = 1;
nids_register_chksum_ctl(&temp,1);
if(!nids_init())
{
printf("出现错误:%s\n",nids_errbuf);
exit(1);
}
nids_register_tcp(http_protocol_callback);
nids_run();
return 0;
}