入侵实验二网络数据包的捕获及协议的简单分析.docx
- 文档编号:28130724
- 上传时间:2023-07-08
- 格式:DOCX
- 页数:15
- 大小:293.75KB
入侵实验二网络数据包的捕获及协议的简单分析.docx
《入侵实验二网络数据包的捕获及协议的简单分析.docx》由会员分享,可在线阅读,更多相关《入侵实验二网络数据包的捕获及协议的简单分析.docx(15页珍藏版)》请在冰豆网上搜索。
入侵实验二网络数据包的捕获及协议的简单分析
实验二
网络数据包的捕获及协议的简单分析
实验目的
网络数据包的捕获及协议的简单分析。
网络数据包是基于网络的入侵检测系统的重要数据源,网络数据包的捕获是基于网络的入侵检测系统实现的第一步。
通过该实验,熟悉并掌握Linux环境下基于Lipbcap的网络数据包的捕获方法,理解和掌握基于网络入侵检测系统的源数据的捕获、协议分析的基本原理和实现方法。
能够熟练应用Libcap开发包中的函数完成网络环境下功能较为简单的网络捕获包和分析程序。
实验内容
1、学习libpcap开发包的功能,并在linux下配置好libpcap环境。
2、在linux系统下基于Libpcap编写C程序,实现对数据包的捕获、过滤和简单分析。
了解libpcap编程
Libpcap的抓包流程
1.查找网络设备:
目的是发现可用的网卡,实现的函数为pcap_lookupdev(),如果当前有多个网卡,函数就会返回一个网络设备名的指针列表。
2.打开网络设备:
利用上一步中的返回值,可以决定使用哪个网卡,通过函数pcap_open_live()打开网卡,返回用于捕捉网络数据包的秒数字。
3.获得网络参数:
这里是利用函数pcap_lookupnet(),可以获得指定网络设备的IP地址和子网掩码。
4.编译过滤策略:
Lipcap的主要功能就是提供数据包的过滤,函数pcap_compile()来实现。
5.设置过滤器:
在上一步的基础上利用pcap_setfilter()函数来设置。
6.利用回调函数,捕获数据包:
函数pcap_loop()和pcap_dispatch()来抓去数据包,也可以利用函数pcap_next()和pcap_next_ex()来完成同样的工作。
7.关闭网络设备:
pcap_close()函数关系设备,释放资源。
libpcap利用BPF来过滤数据包
过滤数据包需要完成3件事:
1.构造一个过滤表达式
2.编译这个表达式
3.应用这个过滤器
基于Libpcap实现一个网络数据包嗅探器
捕获所有流经本网卡的数据包实现流程:
1.查找网络设备
2.打开网络设备
3.查找设备信息
4.输入过滤规则
5.编译输入规则设置输入规则
6.开始捕获数据包
7.调用数据包分析模块
8.输出MAC,IP,协议以及数据帧
9.结束
libpcap安装
需要以下四个安装包:
先安装bison、flex、m4,最后安装libpcap
第一步:
解压:
tar-xvfbison-2.4.1.tar.gz.gz//因为都是.tar.gz的压缩包,使用tar解压命令
第二步:
检查:
./configure//检查计算机建立包所必须的完整性;根据需要改变默认的路径;激活/禁用编译程序中的各种选项;改变程序将要被安装的路径;
第三步:
编译:
(sudo)make//(有时候需要root权限)
第四步:
安装:
(sudo)makeinstall//(有时候需要root权限)
bison-2.4.1.tar.gz.gz、flex-2.5.35.tar.gz.gz、m4-1.4.13.tar.gz.gz都用上述方法安装,最后同样方法安装libpcap-1.5.3.tar.gz.gz
最后将解压到的libpcap-1.5.3目录下的pcap目录复制到根目录下的/usr/include里,再将/usr/lib目录下的libpcap.so.1.5.3复制一份改名为libpcap.so.1放到/usr/lib。
实验代码
标准的与上比对的简单实现代码:
#include
#include
intmain(intargc,char*argv[]){
pcap_t*handle;/*会议手柄*/
char*dev;/*嗅探装置*/
charerrbuf[PCAP_ERRBUF_SIZE];/*错误字符串*/
structbpf_programfp;/*编译过滤器*/
charfilter_exp[]="port80";/*过滤器表达式*/
bpf_u_int32mask;/*网络掩码*/
bpf_u_int32net;/*IP*/
structpcap_pkthdrheader;/*PCAP返回的头部*/
constu_char*packet;/*实际的数据包*/
/*查找网络设备*/
dev=pcap_lookupdev(errbuf);//如果当前有多个网卡,函数就会返回一个网络设备名的指针列表。
if(dev==NULL){
fprintf(stderr,"找不到默认的设备:
%s\n",errbuf);
return
(2);}
/*获得网络参数*/
if(pcap_lookupnet(dev,&net,&mask,errbuf)==-1){//获得指定网络设备的IP地址和子网掩码
fprintf(stderr,"无法获取网络掩码设备%s:
%s\n",dev,errbuf);
net=0;
mask=0;}
/*打开网络设备,混杂模式下打开会话*/
handle=pcap_open_live(dev,BUFSIZ,1,1000,errbuf);//利用第一步中的返回值,可以决定使用哪个网卡,打开网卡,返回用于捕捉网络数据包的秒数字。
if(handle==NULL){
fprintf(stderr,"无法打开设备%s:
%s\n",dev,errbuf);
return
(2);}
/*编译和应用过滤器*/
if(pcap_compile(handle,&fp,filter_exp,0,net)==-1)//数据包的过滤
{
fprintf(stderr,"无法解析过滤器%s:
%s\n",filter_exp,pcap_geterr(handle));
return
(2);}
/*设置过滤器*/
if(pcap_setfilter(handle,&fp)==-1){//在上一步的基础上利用pcap_setfilter()函数来设置
fprintf(stderr,"无法安装过滤器%s:
%s\n",filter_exp,pcap_geterr(handle));
return
(2);}
/*抓包*/
packet=pcap_next(handle,&header);//利用回调函数,捕获数据包
/*打印长度*/
printf("Jackedapacketwithlengthof[%d]\n",header.len);
/*关闭网络设备,关闭会话,释放资源*/
pcap_close(handle);
return(0);
}
实验结果:
这是没有联网或者断网时出现的结果。
完成进一步数据包分析的代码:
#include
#include
#include
#include
#include
#include
#include
//链路层数据包格式
typedefstruct{
u_charDestMac[6];
u_charSrcMac[6];
u_charEtype[2];
}ETHHEADER;
//IP层数据包格式
typedefstruct{
intheader_len:
4;
intversion:
4;
u_chartos:
8;
inttotal_len:
16;
intident:
16;
intflags:
16;
u_charttl:
8;
u_charproto:
8;
intchecksum:
16;
u_charsourceIP[4];
u_chardestIP[4];
}IPHEADER;
//协议映射表
char*Proto[]={
"Reserved","ICMP","IGMP","GGP","IP","ST","TCP"
};
//回调函数,分析数据包
voidpcap_handle(u_char*user,conststructpcap_pkthdr*header,constu_char*pkt_data){
//第一个参数是pcap_loop的最后一个参数,当收到足够数量的包后pcap_loop会调用pcap_handle回调函数,同时将pcap_loop()的user参数传递给它
//第二个参数是收到的数据包的pcap_pkthdr类型的指针
//第三个参数是收到的数据包数据
ETHHEADER*eth_header=(ETHHEADER*)pkt_data;
printf("---------------BeginAnalysis-----------------\n");
printf("----------------------------------------------\n");
printf("Packetlength:
%d\n",header->len);
//解析数据包IP头部
if(header->len>=14){
IPHEADER*ip_header=(IPHEADER*)(pkt_data+14);
//解析协议类型
charstrType[100];//协议类型
if(ip_header->proto>7)
strcpy(strType,"IP/UNKNWN");
else
strcpy(strType,Proto[ip_header->proto]);
//打印源物理地址,目的物理地址
printf("SourceMAC:
%02X-%02X-%02X-%02X-%02X-%02X==>",eth_header->SrcMac[0],eth_header->SrcMac[1],eth_header->SrcMac[2],eth_header->SrcMac[3],eth_header->SrcMac[4],eth_header->SrcMac[5]);
printf("DestMAC:
%02X-%02X-%02X-%02X-%02X-%02X\n",eth_header->DestMac[0],eth_header->DestMac[1],eth_header->DestMac[2],eth_header->DestMac[3],eth_header->DestMac[4],eth_header->DestMac[5]);
//打印源IP,目的IP
printf("SourceIP:
%d.%d.%d.%d==>",ip_header->sourceIP[0],ip_header->sourceIP[1],ip_header->sourceIP[2],ip_header->sourceIP[3]);
printf("DestIP:
%d.%d.%d.%d\n",ip_header->destIP[0],ip_header->destIP[1],ip_header->destIP[2],ip_header->destIP[3]);
//打印协议类型
printf("Protocol:
%s\n",strType);
//显示数据帧内容,十六位一行
for(inti=0;i<(int)header->len;++i){
printf("%02x",pkt_data[i]);
if((i+1)%16==0)
printf("\n");}
printf("\n\n");}
}
intmain(intargc,char**argv)
{
char*device="eth0";//默认网络接口
charerrbuf[1024];
pcap_t*phandle;
bpf_u_int32ipaddress,ipmask;
structbpf_programfcode;
intdatalink;
/*获取网络接口*/
if((device=pcap_lookupdev(errbuf))==NULL){//这个函数返回第一个合适的网络接口的字符串指针,如果出错,则errbuf存放出错信息字符串,errbuf至少应该是PCAP_ERRBUF_SIZE个字节长度的
perror(errbuf);
return1;
}
else
printf("device:
%s\n",device);
/*打开网络接口*/
phandle=pcap_open_live(device,200,0,500,errbuf);
//这个函数会返回指定接口的pcap_t类型指针,后面的所有操作都要使用这个指针。
//第一个参数是第一步获取的网络接口字符串,可以直接使用硬编码。
//第二个参数是对于每个数据包,从开头要抓多少个字节,我们可以设置这个值来只抓每个数据包的头部,而不关心具体的内容。
典型的以太网帧长度是1518字节,但其他的某些协议的数据包会更长一点,但任何一个协议的一个数据包长度都必然小于65535个字节。
//第三个参数指定是否打开混杂模式(PromiscuousMode),0表示非混杂模式,任何其他值表示混合模式。
如果要打开混杂模式,那么网卡必须也要打开混杂模式,可以使用如下的命令打开eth0混杂模式:
ifconfigeth0promisc
//第四个参数指定需要等待的毫秒数,超过这个数值后,第3步获取数据包的这几个函数就会立即返回。
0表示一直等待直到有数据包到来。
//第五个参数是存放出错信息的数组。
if(phandle==NULL){
perror(errbuf);
return1;
}
if(pcap_lookupnet(device,&ipaddress,&ipmask,errbuf)==-1){
perror(errbuf);
return1;
}
else{
charip[INET_ADDRSTRLEN],mask[INET_ADDRSTRLEN];
if(inet_ntop(AF_INET,&ipaddress,ip,sizeof(ip))==NULL)
perror("inet_ntoperror");
elseif(inet_ntop(AF_INET,&ipmask,mask,sizeof(mask))==NULL)
perror("inet_ntoperror");
printf("IPaddress:
%s,NetworkMask:
%s\n",ip,mask);
}
intflag=1;
while(flag){
//inputthedesignfilter
printf("InputpacketFilter:
");
charfilterString[1024];
scanf("%s",filterString);
/*编译*/
if(pcap_compile(phandle,&fcode,filterString,0,ipmask)==-1)
//fcode:
传出参数,存放编译后的bpf,filterString:
过滤表达式,0:
不需要优化过滤表达式,ipmask:
简单设置为0即可
fprintf(stderr,"pcap_compile:
%s,pleaseinputagain....\n",pcap_geterr(phandle));
else
flag=0;
}
/*设置这个规则*/
if(pcap_setfilter(phandle,&fcode)==-1){
//参数fp就是pcap_compile()的第二个参数,存放编译后的bpf
fprintf(stderr,"pcap_setfilter:
%s\n",pcap_geterr(phandle));
return1;
}
if((datalink=pcap_datalink(phandle))==-1){
fprintf(stderr,"pcap_datalink:
%s\n",pcap_geterr(phandle));
return1;
}
printf("datalink=%d\n",datalink);
/*获取数据包*/
pcap_loop(phandle,-1,pcap_handle,NULL);
//第一个参数是第2步返回的pcap_t类型的指针
//第二个参数是需要抓的数据包的个数,一旦抓到了cnt个数据包,pcap_loop立即返回。
负数的cnt表示pcap_loop永远循环抓包,直到出现错误。
//第三个参数是一个回调函数指针:
return0;
}
实验结果:
以root模式编译通过:
sudogcc2.c-o2-lpcap
打开网页:
以root模式运行:
sudo./2
显示网络接口,IP地址,子网掩码,要求输入捕捉限制(可输入"Reserved","ICMP","IGMP","GGP","IP","ST","TCP")
输入icmp回车后显示捕捉到的icmp包信息:
显示数据包的长度,发送方的物理地址,接收方的物理地址,源IP,目的IP,协议类型,可看出是符合过滤条件的。
重复上述步骤再次运行,输入TCP:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 入侵 实验 网络 数据包 捕获 协议 简单 分析