1、嗅探器的实现计算机通信网络实验嗅探器的实现 学院:通信工程学院班级:011291班学号:01129030姓名:丁翔宇2015年5月22日一、 实验目的掌握基于Libpcap/Winpcap的协议分析器的设计方法二、 原理介绍嗅探器程序一般包括内核部分和用户分析部分。1) 内核部分负责从网络中捕获和过滤数据。2) 用户分析部分负责界面、数据转化与处理、格式化、协议分析,如果在内核没有过滤数据包,在这里还要对数据进行过滤。一个较为完整的基于网络监听和过滤的程序一般包括以下步骤:1) 数据包捕获2) 数据包过滤与分解3) 数据分析数据包捕获常用的方法有两种:1) 通过设置硬路由器的监听端口;2) 利
2、用以太网络的广播特性。这种方式必须将网卡设置为混杂(promiscuous)模式。监听程序工作在网络环境的底三层,可以拦截所有经过该机器的网络上传送的数据,然后将这些数据做相应处理,可以实时分析这些数据的内容,进而分析网络当前状态和整体布局。基于windows的数据包捕获方案有以下几种:1) 使用原始套接字(row socket)机制。方法简单,但功能有限,只能捕获较高层的数据包;2) 直接连接调用NDIS库函数,这种方法功能非常强大,但是比较危险,很可能导致系统崩溃和网络瘫痪;基于windows的数据包捕获方案有以下几种:1) 使用或者自行编写中间层驱动程序,这是微软公司推荐使用的一种方法,
3、微软提供的win2000 DDK中也提供了几个这样的驱动程序。在具体的实现方式上可分为用户级和内核级两类。其中内核级主要是TDI捕获过滤驱动程序,NDIS中间层捕获过滤驱动程序,NDIS捕获过滤钩子驱动程序等,它们都是利用网络驱动来实现的;而用户级的包括SPI接口,Windows2000包捕获过滤接口等;2) 使用或自行编写协议驱动程序;3) 使用第三方捕获组件或者库,比如Winpcap。捕获数据包后要进行的工作是对其进行包过滤与分解,就是在海量的数据里面找我们感兴趣的内容。一些基础的过滤规则如下:1) 站过滤:专门筛选出来自一台主机或者服务器的数据;2) 协议过滤:根据不同的协议来筛选数据,
4、例如:选择TCP数据而非UDP数据;3) 服务过滤:根据端口号来选择特定数据包;4) 通用过滤:通过数据包中某一特定位置开始,选择具有某些共同数据特征的数据包;过滤完成后,必须进行数据分析,这一部分就是对已经捕获的数据包进行各种分析,比如:网络流量分析、数据包中信息、分析敏感信息提取分析等,功能取决于系统要达到的目的。WinPcap是Windows平台下一个专业网络数据包捕获开发包,是为Libpcap在Windows平台下实现数据包的捕获而设计的。Libcap(Winpcap是其windows版本)可以提供与平台无关的接口,而且操作简单,它是基于改进的BPF(Berkeley Packet F
5、ilter),该软件来自Berkeley的Lawrence National Laboratory研究院。使用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关闭设备句柄。三、 实验环境Wind
6、ows 2000以上版本,WinPcap3.0。四、 实验思路1、根据TCP/IP协议中各层的数据包格式编写数据头部的结构体,便于存储调用各层数据头部信息;IP数据报:TCP报文格式:2、以老师给出的参考代码为基础编写基于Winpcap的监听过程,为了过滤出登录FTP服务器的帐号和密码,将过滤规则设置为“port 21”,即只过滤出端口号为21的传输数据;3、在回调函数中对捕获到的数据包进行分析,打印出每条数据包的时间、源地址和目的地址,并找出关键字“USER”和“PASS”,过滤出FTP服务器的帐号和密码。五、 实验步骤参考代码编写基于WinPcap的监听程序。参考给出的代码,实现一个监听程
7、序能够自动过滤FTP的用户名和密码。1. 代码:/ FTPsniffer.cpp : 定义控制台应用程序的入口点。/by01121094 zc/#include stdafx.h#include pcap.h#include stdio.h#pragma comment(lib, wpcap.lib)#pragma comment(lib, wsock32.lib)#pragma comment(lib, ws2_32.lib) /WINSOCK API连接库文件#pragma warning(disable: 4996)#pragma warning(disable: 4390)u_char
8、 user20; /存放用户名u_char pass20; /存放密码FILE *fp = NULL;/* TCP header*/typedef struct tcp_header u_short sport; / Source port 16bits u_short dport; / Destination port 16bits u_int seq; /序列号 32bits u_int ack_num; /确认号 32bits u_char ihl; /Internet header length (4 bits)+4bits保留 u_char frame; / 2bits保留+URG+
9、ACK+PSH+RST+SYN+FIN u_short wsize; /window size 16bits u_short crc; /Header checksum 首部校验和(16 bits) u_short urg; /urgent frame 16bitstcp_header;/* 4 bytes IP address */typedef struct ip_address u_char byte1; u_char byte2; u_char byte3; u_char byte4;ip_address;/* IPv4 header */typedef struct ip_heade
10、r u_char ver_ihl; / Version (4 bits) + Internet header length (4 bits)版本+首部长度 u_char tos; / Type of service 区分服务(8 bits) u_short tlen; / Total length 总长度(16 bits) u_short identification; / Identification 标识(16 bits) u_short flags_fo; / Flags (3 bits) + Fragment offset (13 bits)标志和片偏移 u_char ttl; / T
11、ime to live 生存时间(8 bits) u_char proto; / Protocol 协议(8 bits) u_short crc; / Header checksum 首部校验和(16 bits) ip_address saddr; / Source address(32 bits) ip_address daddr; / Destination address(32 bits) u_int op_pad; / Option + Paddingip_header;/* prototype of the packet handler */void packet_handler(u
12、_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);int main() pcap_if_t *alldevs, *d; int inum; int i = 0; /网络设备个数 pcap_t *adhandle; /网卡描述符 char errbufPCAP_ERRBUF_SIZE; unsigned int netmask; char packet_filter = port 21; /过滤规则 struct bpf_program fcode; /* Retrieve the device lis
13、t 获取网络设备列表*/ if (pcap_findalldevs(&alldevs, errbuf) = -1) fprintf(stderr, Error in pcap_findalldevs: %sn, errbuf); exit(1); /* Print the list */ for (d = alldevs; d; d = d-next) printf(%d. %s, +i, d-name); if (d-description) printf( (%s)n, d-description); else printf( (No description available)n); i
14、f (i = 0) /没有获取到网络设备时,显示提示 printf(nNo interfaces found! Make sure WinPcap is installed.n); return -1; printf(Enter the interface number (1-%d):, i); scanf(%d, &inum); if (inum i) printf(nInterface number out of range.n); pcap_freealldevs(alldevs); /* Free the device list */ return -1; /* Jump to the
15、 selected adapter */ for (d = alldevs, i = 0; inext, i+); /* Open the adapter */ if (adhandle = pcap_open_live(d-name, / name of the device 65536, / portion of the packet to capture. 1, / promiscuous mode 混杂模式 1000, / read timeout,单位ms errbuf / error buffer ) = NULL) fprintf(stderr, nUnable to open
16、the adapter. %s is not supported by WinPcapn); pcap_freealldevs(alldevs); /* Free the device list */ return -1; /* Check the link layer. We support only Ethernet for simplicity. */ if (pcap_datalink(adhandle) != DLT_EN10MB) /返回链路层的类型,DLT_EN10MB是以太网 fprintf(stderr, nThis program works only on Etherne
17、t networks.n); pcap_freealldevs(alldevs); /* Free the device list */ return -1; if (d-addresses != NULL) /* Retrieve the mask of the first address of the interface 获取子网掩码*/ netmask = (struct sockaddr_in *)(d-addresses-netmask)-sin_addr.S_un.S_addr; else /* If the interface is without addresses we su
18、ppose to be in a C class network */ netmask = 0xffffff; /compile the filter 编译过滤规则,packet_filter-fcode(内核认识的格式),char packet_filter = port 21 if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) 0) fprintf(stderr, nUnable to compile the packet filter. Check the syntax.n); /* Free the device
19、list */ pcap_freealldevs(alldevs); return -1; /set the filter 所有的一致的数据包将被复制给应用程序 if (pcap_setfilter(adhandle, &fcode)description); /* At this point, we dont need any more the device list. Free it */ pcap_freealldevs(alldevs); if(fp = fopen(./result.txt, w);/打开文件,等待嗅探结果输入 pcap_loop(adhandle, 40, pack
20、et_handler, NULL);/* start the capture 抓取40个包,回调函数packet_handler*/ printf(check the result!nttuser:%snttpwd:%sn,user,pass); fclose(fp);/关闭文件 system(pause);/控制台窗口暂停 return 0;/* Callback function invoked by libpcap for every incoming packet */void packet_handler(u_char *param, const struct pcap_pkthdr
21、 *header, const u_char *pkt_data) struct tm ltime; char timestr16; ip_header *ih; /指向ip数据报 tcp_header *th; /指向tcp报文 u_char *pdata; /指向传输数据 u_int ip_len; /IP数据报头部长度 u_int tcp_len; /TCP报文头部长度 u_short sport, dport; /源端口和目的端口地址 u_int data_len; /数据长度 u_int i; time_t local_tv_sec; /* convert the timestamp
22、 to readable format */ local_tv_sec = header-ts.tv_sec; localtime_s(<ime, &local_tv_sec); strftime(timestr, sizeof timestr, %H:%M:%S, <ime); /* print timestamp and length of the packet */ printf(%s.%.6d len:%d , timestr, header-ts.tv_usec, header-len); 1 fprintf(fp, %s.%.6d len:%d n, timestr, he
23、ader-ts.tv_usec, header-len);/输出到文件result.txt 2 /* retireve the position of the ip header */ ih = (ip_header *)(pkt_data + 14); /length of ethernet header /* retireve the position of the udp header */ ip_len = (ih-ver_ihl & 0xf) * 4; /ver_ihl是8bit,位与0xf,高4位清零,后4位是首部长度,单位:4字节 th = (tcp_header *)(u_ch
24、ar*)ih + ip_len); /* convert from network byte order to host byte order */ sport = ntohs(th-sport); dport = ntohs(th-dport); /* print ip addresses and udp ports */ printf(%d.%d.%d.%d.%d - %d.%d.%d.%d.%dn, ih-saddr.byte1, ih-saddr.byte2,/ ih-saddr.byte3, ih-saddr.byte4,/源ip地址/ sport, /源地址的端口/ ih-dadd
25、r.byte1, ih-daddr.byte2, ih-daddr.byte3, ih-daddr.byte4,/目的ip地址/ dport); /目的地址的端口 fprintf(fp, src:%d.%d.%d.%d port:%dn, ih-saddr.byte1, ih-saddr.byte2, ih-saddr.byte3, ih-saddr.byte4,sport); fprintf(fp, dst:%d.%d.%d.%d port:%dn,ih-daddr.byte1, ih-daddr.byte2, ih-daddr.byte3, ih-daddr.byte4, dport);/
26、输出到文件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; id
27、ata_len - 5; i+) useri = *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; idata_len - 5; i+) passi = *pdata; pdata+; fprintf(fp, *User:%sn*Password:%s, user, pass); fprintf(fp, n+01121094zc+n)
28、;2、实验结果客户端:ftp服务器的地址是ftp:/222.25.162.196客户端在浏览器地址栏中输入服务器地址,首先出现如下对话框,客户输入用户名和密码后即可登录。用户名:dell密码: yl253631 登录后界面如下,网页上所显示的文件均是ftp服务器上的文件,可以查看和下载。服务器:程序运行后的doc界面:从上图可以看出,本主机有3个网络设备,用户可以选择任何一个监听,现在选择的是第一个网络设备接口进行监听。随后,嗅探器捕获了30个数据包,并过滤出了用户名和密码,可以看到,与客户端登陆时所用用户名密码相同,表明该程序满足了设计要求。六、 实验心得在本次实验中我们通过用C语言编写基于
29、winpcap的简易嗅探器,成功捕获了ftp数据包,过滤出了用户名和密码。在本次编程过程中,我们遇到了不少困难,也学到了不少知识。首先是刚开始尝试编译老师给的参考代码使发现有错误,后来发现是如果我们要使用winpcap中的各种函数和结构体,就必须在vc环境中进行一些部署。其次是由于TCP/IP协议的各层数据格式虽然都学习过,但已经有些遗忘了,所以编程的时候我们重新学习了TCP/IP协议的相关知识,也掌握了对各层数据头部地址的计算和提取地址等信息。此外,我们还学习到了网络字节顺序和本机字节顺序的不同。读取的时候如果不注意,会出现不少混乱。针对这一现象,可以用函数htons()和ntohs()解决。总之,本次实验不管在理论还是实践上都让我受益颇多,我希望以后能学习更多相关的知识。
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2