嗅探器的实现.docx

上传人:b****1 文档编号:2590195 上传时间:2023-05-04 格式:DOCX 页数:16 大小:197.42KB
下载 相关 举报
嗅探器的实现.docx_第1页
第1页 / 共16页
嗅探器的实现.docx_第2页
第2页 / 共16页
嗅探器的实现.docx_第3页
第3页 / 共16页
嗅探器的实现.docx_第4页
第4页 / 共16页
嗅探器的实现.docx_第5页
第5页 / 共16页
嗅探器的实现.docx_第6页
第6页 / 共16页
嗅探器的实现.docx_第7页
第7页 / 共16页
嗅探器的实现.docx_第8页
第8页 / 共16页
嗅探器的实现.docx_第9页
第9页 / 共16页
嗅探器的实现.docx_第10页
第10页 / 共16页
嗅探器的实现.docx_第11页
第11页 / 共16页
嗅探器的实现.docx_第12页
第12页 / 共16页
嗅探器的实现.docx_第13页
第13页 / 共16页
嗅探器的实现.docx_第14页
第14页 / 共16页
嗅探器的实现.docx_第15页
第15页 / 共16页
嗅探器的实现.docx_第16页
第16页 / 共16页
亲,该文档总共16页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

嗅探器的实现.docx

《嗅探器的实现.docx》由会员分享,可在线阅读,更多相关《嗅探器的实现.docx(16页珍藏版)》请在冰点文库上搜索。

嗅探器的实现.docx

嗅探器的实现

 

计算机通信网络实验

 

嗅探器的实现

 

学院:

通信工程学院

班级:

011291班

学号:

01129030

姓名:

丁翔宇

 

2015年5月22日

一、实验目的

掌握基于Libpcap/Winpcap的协议分析器的设计方法

二、原理介绍

嗅探器程序一般包括内核部分和用户分析部分。

1)内核部分负责从网络中捕获和过滤数据。

2)用户分析部分负责界面、数据转化与处理、格式化、协议分析,如果在内核没有过滤数据包,在这里还要对数据进行过滤。

一个较为完整的基于网络监听和过滤的程序一般包括以下步骤:

1)数据包捕获

2)数据包过滤与分解

3)数据分析

数据包捕获常用的方法有两种:

1)通过设置硬路由器的监听端口;

2)利用以太网络的广播特性。

这种方式必须将网卡设置为混杂(promiscuous)模式。

监听程序工作在网络环境的底三层,可以拦截所有经过该机器的网络上传送的数据,然后将这些数据做相应处理,可以实时分析这些数据的内容,进而分析网络当前状态和整体布局。

基于windows的数据包捕获方案有以下几种:

1)使用原始套接字(rowsocket)机制。

方法简单,但功能有限,只能捕获较高层的数据包;

2)直接连接调用NDIS库函数,这种方法功能非常强大,但是比较危险,很可能导致系统崩溃和网络瘫痪;

基于windows的数据包捕获方案有以下几种:

1)使用或者自行编写中间层驱动程序,这是微软公司推荐使用的一种方法,微软提供的win2000DDK中也提供了几个这样的驱动程序。

在具体的实现方式上可分为用户级和内核级两类。

其中内核级主要是TDI捕获过滤驱动程序,NDIS中间层捕获过滤驱动程序,NDIS捕获过滤钩子驱动程序等,它们都是利用网络驱动来实现的;而用户级的包括SPI接口,Windows2000包捕获过滤接口等;

2)使用或自行编写协议驱动程序;

3)使用第三方捕获组件或者库,比如Winpcap。

捕获数据包后要进行的工作是对其进行包过滤与分解,就是在海量的数据里面找我们感兴趣的内容。

一些基础的过滤规则如下:

1)站过滤:

专门筛选出来自一台主机或者服务器的数据;

2)协议过滤:

根据不同的协议来筛选数据,例如:

选择TCP数据而非UDP数据;

3)服务过滤:

根据端口号来选择特定数据包;

4)通用过滤:

通过数据包中某一特定位置开始,选择具有某些共同数据特征的数据包;

过滤完成后,必须进行数据分析,这一部分就是对已经捕获的数据包进行各种分析,比如:

网络流量分析、数据包中信息、分析敏感信息提取分析等,功能取决于系统要达到的目的。

WinPcap是Windows平台下一个专业网络数据包捕获开发包,是为Libpcap在Windows平台下实现数据包的捕获而设计的。

Libcap(Winpcap是其windows版本)可以提供与平台无关的接口,而且操作简单,它是基于改进的BPF(BerkeleyPacketFilter),该软件来自Berkeley的LawrenceNationalLaboratory研究院。

使用Winpcap包过程比较规范。

基于Libcap/Winpcap库的基本使用流程比较规范,一般为:

1)使用pcap_lookupdev获取设备;

2)使用pcap_lookupnet获取网络地址和子网掩码;

3)使用pcap_open_live打开设备;

4)使用pcap_complile编译过滤规则;

5)使用pcap_setfilter设置过滤规则;

6)使用pcap_loop循环捕获数据包,在其中调用相应处理函数;

7)使用pcap_close关闭设备句柄。

三、实验环境

Windows2000以上版本,WinPcap3.0。

四、实验思路

1、根据TCP/IP协议中各层的数据包格式编写数据头部的结构体,便于存储调用各层数据头部信息;

IP数据报:

 

TCP报文格式:

2、以老师给出的参考代码为基础编写基于Winpcap的监听过程,为了过滤出登录FTP服务器的帐号和密码,将过滤规则设置为“port21”,即只过滤出端口号为21的传输数据;

3、在回调函数中对捕获到的数据包进行分析,打印出每条数据包的时间、源地址和目的地址,并找出关键字“USER”和“PASS”,过滤出FTP服务器的帐号和密码。

五、实验步骤

参考代码编写基于WinPcap的监听程序。

参考给出的代码,实现一个监听程序能够自动过滤FTP的用户名和密码。

1.代码:

//FTPsniffer.cpp:

定义控制台应用程序的入口点。

//by01121094zc

//

#include"stdafx.h"

#include"pcap.h"

#include"stdio.h"

#pragmacomment(lib,"wpcap.lib")

#pragmacomment(lib,"wsock32.lib")

#pragmacomment(lib,"ws2_32.lib")//WINSOCKAPI连接库文件

#pragmawarning(disable:

4996)

#pragmawarning(disable:

4390)

u_charuser[20];//存放用户名

u_charpass[20];//存放密码

FILE*fp=NULL;

/*TCPheader*/

typedefstructtcp_header{

u_shortsport;//Sourceport16bits

u_shortdport;//Destinationport16bits

u_intseq;//序列号32bits

u_intack_num;//确认号32bits

u_charihl;//Internetheaderlength(4bits)+4bits保留

u_charframe;//2bits保留+URG+ACK+PSH+RST+SYN+FIN

u_shortwsize;//windowsize16bits

u_shortcrc;//Headerchecksum首部校验和(16bits)

u_shorturg;//urgentframe16bits

}tcp_header;

/*4bytesIPaddress*/

typedefstructip_address{

u_charbyte1;

u_charbyte2;

u_charbyte3;

u_charbyte4;

}ip_address;

/*IPv4header*/

typedefstructip_header{

u_charver_ihl;//Version(4bits)+Internetheaderlength(4bits)版本+首部长度

u_chartos;//Typeofservice区分服务(8bits)

u_shorttlen;//Totallength总长度(16bits)

u_shortidentification;//Identification标识(16bits)

u_shortflags_fo;//Flags(3bits)+Fragmentoffset(13bits)标志和片偏移

u_charttl;//Timetolive生存时间(8bits)

u_charproto;//Protocol协议(8bits)

u_shortcrc;//Headerchecksum首部校验和(16bits)

ip_addresssaddr;//Sourceaddress(32bits)

ip_addressdaddr;//Destinationaddress(32bits)

u_intop_pad;//Option+Padding

}ip_header;

/*prototypeofthepackethandler*/

voidpacket_handler(u_char*param,conststructpcap_pkthdr*header,constu_char*pkt_data);

intmain()

{

pcap_if_t*alldevs,*d;

intinum;

inti=0;//网络设备个数

pcap_t*adhandle;//网卡描述符

charerrbuf[PCAP_ERRBUF_SIZE];

unsignedintnetmask;

charpacket_filter[]="port21";//过滤规则

structbpf_programfcode;

/*Retrievethedevicelist获取网络设备列表*/

if(pcap_findalldevs(&alldevs,errbuf)==-1)

{

fprintf(stderr,"Errorinpcap_findalldevs:

%s\n",errbuf);

exit

(1);

}

/*Printthelist*/

for(d=alldevs;d;d=d->next)

{

printf("%d.%s",++i,d->name);

if(d->description)

printf("(%s)\n",d->description);

else

printf("(Nodescriptionavailable)\n");

}

if(i==0)//没有获取到网络设备时,显示提示

{

printf("\nNointerfacesfound!

MakesureWinPcapisinstalled.\n");

return-1;

}

printf("Entertheinterfacenumber(1-%d):

",i);

scanf("%d",&inum);

if(inum<1||inum>i)

{

printf("\nInterfacenumberoutofrange.\n");

pcap_freealldevs(alldevs);/*Freethedevicelist*/

return-1;

}

/*Jumptotheselectedadapter*/

for(d=alldevs,i=0;inext,i++);

/*Opentheadapter*/

if((adhandle=pcap_open_live(d->name,//nameofthedevice

65536,//portionofthepackettocapture.

1,//promiscuousmode混杂模式

1000,//readtimeout,单位ms

errbuf//errorbuffer

))==NULL)

{

fprintf(stderr,"\nUnabletoopentheadapter.%sisnotsupportedbyWinPcap\n");

pcap_freealldevs(alldevs);/*Freethedevicelist*/

return-1;

}

/*Checkthelinklayer.WesupportonlyEthernetforsimplicity.*/

if(pcap_datalink(adhandle)!

=DLT_EN10MB)

//返回链路层的类型,DLT_EN10MB是以太网

{

fprintf(stderr,"\nThisprogramworksonlyonEthernetnetworks.\n");

pcap_freealldevs(alldevs);/*Freethedevicelist*/

return-1;

}

if(d->addresses!

=NULL)

/*Retrievethemaskofthefirstaddressoftheinterface获取子网掩码*/

netmask=((structsockaddr_in*)(d->addresses->netmask))->sin_addr.S_un.S_addr;

else

/*IftheinterfaceiswithoutaddresseswesupposetobeinaCclassnetwork*/

netmask=0xffffff;

//compilethefilter编译过滤规则,packet_filter->fcode(内核认识的格式),charpacket_filter[]="port21"

if(pcap_compile(adhandle,&fcode,packet_filter,1,netmask)<0){

fprintf(stderr,"\nUnabletocompilethepacketfilter.Checkthesyntax.\n");

/*Freethedevicelist*/

pcap_freealldevs(alldevs);

return-1;

}

//setthefilter所有的一致的数据包将被复制给应用程序

if(pcap_setfilter(adhandle,&fcode)<0){

fprintf(stderr,"\nErrorsettingthefilter.\n");

pcap_freealldevs(alldevs);/*Freethedevicelist*/

return-1;

}

printf("\nlisteningon%s...\n\n",d->description);

/*Atthispoint,wedon'tneedanymorethedevicelist.Freeit*/

pcap_freealldevs(alldevs);

if(fp=fopen(".//result.txt","w"));//打开文件,等待嗅探结果输入

pcap_loop(adhandle,40,packet_handler,NULL);

/*startthecapture抓取40个包,回调函数packet_handler*/

printf("checktheresult!

\n\t\tuser:

%s\n\t\tpwd:

%s\n",user,pass);

fclose(fp);//关闭文件

system("pause");//控制台窗口暂停

return0;

}

/*Callbackfunctioninvokedbylibpcapforeveryincomingpacket*/

voidpacket_handler(u_char*param,conststructpcap_pkthdr*header,constu_char*pkt_data)

{

structtmltime;

chartimestr[16];

ip_header*ih;//指向ip数据报

tcp_header*th;//指向tcp报文

u_char*pdata;//指向传输数据

u_intip_len;//IP数据报头部长度

u_inttcp_len;//TCP报文头部长度

u_shortsport,dport;//源端口和目的端口地址

u_intdata_len;//数据长度

u_inti;

time_tlocal_tv_sec;

/*convertthetimestamptoreadableformat*/

local_tv_sec=header->ts.tv_sec;

localtime_s(<ime,&local_tv_sec);

strftime(timestr,sizeoftimestr,"%H:

%M:

%S",<ime);

/*printtimestampandlengthofthepacket*/

//printf("%s.%.6dlen:

%d",timestr,header->ts.tv_usec,header->len);1

fprintf(fp,"%s.%.6dlen:

%d\n",timestr,header->ts.tv_usec,header->len);//输出到文件result.txt2

/*retirevethepositionoftheipheader*/

ih=(ip_header*)(pkt_data+14);//lengthofethernetheader

/*retirevethepositionoftheudpheader*/

ip_len=(ih->ver_ihl&0xf)*4;

//ver_ihl是8bit,位与0xf,高4位清零,后4位是首部长度,单位:

4字节

th=(tcp_header*)((u_char*)ih+ip_len);

/*convertfromnetworkbyteordertohostbyteorder*/

sport=ntohs(th->sport);

dport=ntohs(th->dport);

/*printipaddressesandudpports*/

//printf("%d.%d.%d.%d.%d->%d.%d.%d.%d.%d\n",ih->saddr.byte1,ih->saddr.byte2,

//ih->saddr.byte3,ih->saddr.byte4,//源ip地址

//sport,//源地址的端口

//ih->daddr.byte1,ih->daddr.byte2,ih->daddr.byte3,ih->daddr.byte4,//目的ip地址

//dport);//目的地址的端口

fprintf(fp,"src:

%d.%d.%d.%dport:

%d\n",ih->saddr.byte1,ih->saddr.byte2,

ih->saddr.byte3,ih->saddr.byte4,sport);

fprintf(fp,"dst:

%d.%d.%d.%dport:

%d\n",ih->daddr.byte1,ih->daddr.byte2,

ih->daddr.byte3,ih->daddr.byte4,dport);//输出到文件result.txt

tcp_len=((th->ihl&0xf0)>>4)*4;//tcp报文头部长度

pdata=(u_char*)th+tcp_len;

data_len=header->len-ip_len-tcp_len-16;

//计算传输数据的长度,16包含帧头部和尾部

//过滤USER信息

if(*pdata=='U'&&*(pdata+1)=='S'&&*(pdata+2)=='E'&&*(pdata+3)=='R')

{

memset(user,0,sizeof(user));

pdata+=5;

for(i=0;i

{

user[i]=*pdata;

pdata++;

}

}

//过滤PASSWORD信息

if(*pdata=='P'&&*(pdata+1)=='A'&&*(pdata+2)=='S'&&*(pdata+3)=='S')

{

memset(pass,0,sizeof(pass));

pdata+=5;

for(i=0;i

{

pass[i]=*pdata;

pdata++;

}

}

fprintf(fp,"**User:

%s\n**Password:

%s",user,pass);

fprintf(fp,"\n++++++++++++++++01121094zc++++++++++++++++\n");

}

2、实验结果

客户端:

ftp服务器的地址是ftp:

//222.25.162.196

客户端在浏览器地址栏中输入服务器地址,首先出现如下对话框,客户输入用户名和密码后即可登录。

用户名:

dell

密码:

yl253631

登录后界面如下,网页上所显示的文件均是ftp服务器上的文件,可以查看和下载。

服务器:

程序运行后的doc界面:

从上图可以看出,本主机有3个网络设备,用户可以选择任何一个监听,现在选择的是第一个网络设备接口进行监听。

随后,嗅探器捕获了30个数据包,并过滤出了用户名和密码,可以看到,与客户端登陆时所用用户名密码相同,表明该程序满足了设计要求。

六、实验心得

在本次实验中我们通过用C语言编写基于winpcap的简易嗅探器,成功捕获了ftp数据包,过滤出了用户名和密码。

在本次编程过程中,我们遇到了不少困难,也学到了不少知识。

首先是刚开始尝试编译老师给的参考代码使发现有错误,后来发现是如果我们要使用winpcap中的各种函数和结构体,就必须在vc环境中进行一些部署。

其次是由于TCP/IP协议的各层数据格式虽然都学习过,但已经有些遗忘了,所以编程的时候我们重新学习了TCP/IP协议的相关知识,也掌握了对各层数据头部地址的计算和提取地址等信息。

此外,我们还学习到了网络字节顺序和本机字节顺序的不同。

读取的时候如果不注意,会出现不少混乱。

针对这一现象,可以用函数htons()和ntohs()解决。

总之,本次实验不管在理论还是实践上都让我受益颇多,我希望以后能学习更多相关的知识。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 人文社科 > 法律资料

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2