网络嗅探器的设计与实现.docx
《网络嗅探器的设计与实现.docx》由会员分享,可在线阅读,更多相关《网络嗅探器的设计与实现.docx(16页珍藏版)》请在冰点文库上搜索。
网络嗅探器的设计与实现
河南理工大学
计算机科学与技术学院
课程设计报告
2011—2012学年第二学期
课程名称计算机网络
设计题目网络嗅探器设计与实现
姓名
学号311009040625
专业班级网络10-6
指导教师刘琨
2012年6月22日
目录
一嗅探器
1.1嗅探器的设计原理…………………………………………1
1.2网络技术与设备简介及监听原理………………………1
1.3网络监听的目的………………………………………2
二嗅探器与网络安全
2.1计算机网络安全现状……………………………………5
2.2嗅探器开发的意义………………………………………6
三嗅探器的开发基础
3.1嗅探器的实现目标…………………………………………6
3.2嗅探器的技术支持简介……………………………………7
四网络嗅探器源代码
4.1网络嗅探器源代码及其说明…………………………7
4.2嗅探器运行状况分析…………………………………11
五总结…………………………………………………………12
六参考文献……………………………………………………13
一嗅探器
1.1嗅探器的设计原理
嗅探器作为一种网络通讯程序,也是通过对网卡的编程来实现网络通讯的,对网卡的编程也是使用通常的套接字(socket)方式来进行。
但是,通常的套接字程序只能响应与自己硬件地址相匹配的或是以广播形式发出的数据帧,对于其他形式的数据帧比如已到达网络接口但却不是发给此地址的数据帧,网络接口在验证投递地址并非自身地址之后将不引起响应,也就是说应用程序无法收取到达的数据包。
而网络嗅探器的目的恰恰在于从网卡接收所有经过它的数据包,这些数据包即可以是发给它的也可以是发往别处的。
显然,要达到此目的就不能再让网卡按通常的正常模式工作,而必须将其设置为混杂模式。
嗅探器最初由NetworkGeneral推出,由NetworkAssociates所有。
1.2网络技术与设备简介及监听原理
数据在网络上是以很小的称为帧(Frame)的单位传输的,帧由几部分组成,不同的部分执行不同的功能。
帧通过特定的称为网络驱动程序的软件进行成型,然后通过网卡发送到网线上,通过网线到达它们的目的机器,在
目的机器的一端执行相反的过程。
接收端机器的以太网卡捕获到这些帧,并告诉操作系统帧已到达,然后对其进行存储。
就是在这个传输和接收的过程中,存在安全方面的问题。
每一个在局域网(LAN)上的工作站都有其硬件地址,这些地址惟一地表示了网络上的机器。
当用户发送一个数据包时,这些数据包就会发送到LAN上所有可用的机器。
在一般情况下,网络上所有的机器都可以“听”到通过的流量,但对不属于自己的数据包则不予响应(换句话说,工作站A不会捕获属于工作站B的数据,而是简单地忽略这些数据)。
如果某个工作站的网络接口处于混杂模式,那么它就可以捕获网络上所有的数据包和帧。
Sniffor程序是一种利用以太网的特性把网络适配卡(NIC,一般为以太网卡)置为杂乱(promiscuous)模式状态的工具,一旦网卡设置为这种模式,它就能接收传输在网络上的每一个信息包。
普通的情况下,网卡只接收和自己的地址有关的信息包,即传输到本地主机的信息包。
要使Sniffer能接收并处理这种方式的信息,系统需要支持BPF,Linux下需要支持SOCKET-PACKET。
但一般情况下,网络硬件和TCP/IP堆栈不支持接收或者发送与本地计算机无关的数据包,所以,为了绕过标准的TCP/IP堆栈,网卡就必须设置为混杂模式。
一般情况下,要激活这种方式,内核必须支持这种伪设备BPFilter,而且需要root权限来运行这种程序,所以Sniffer需要root身份安装,如果只是以本地用户的身份进入了系统,那么不可能嗅探到root的密码,因为不能运行Sniffer。
基于Sniffer这样的模式,可以分析各种信息包并描述出网络的结构和使用的机器,由于它接收任何一个在同一网段上传输的数据包,所以也就存在着捕获密码、各种信息、秘密文档等一些没有加密的信息的可能性。
这成为黑客们常用的扩大战果的方法,用来夺取其他主机的控制权。
1.3网络监听的目的
当一个黑客成功地攻陷了一台主机,并拿到了root权限,而且还想利用这台主机去攻击同一网段上的其他主机时,他就会在这台主机上安装Sniffer软件,对以太网设备上传送的数据包进行侦听,从而发现感兴趣的包。
如果发现符合条件的包,就把它存到一个LOG文件中去。
通常设置的这些条件是包含字“username”或“password”的包,这样的包里面通常有黑客感兴趣的密码之类的东西。
一旦黑客截获得了某台主机的密码,他就会立刻进入这台主机。
Sniffer除了能得到口令或用户名外,还能得到更多的其他信息,比如一个重要的信息、在网上传送的金融信息等等。
Sniffer几乎能得到任何在以太网上传送的数据包。
Sniffer是一种比较复杂的攻击手段,一般只有黑客老手才有能力使用它,而对于一个网络新手来说,即使在一台主机上成功地编译并运行了Sniffer,一般也不会得到什么有用的信息,因为通常网络上的信息流量是相当大的,如果不加选择地接收所有的包,然后从中找到所需要的信息非常困难;而且,如果长时间进行监听,还有可能把放置Sniffer的机器的硬盘撑爆。
这种对网卡混杂模式的设置是通过原始套接字(rawsocket)来实现的,这也有别于通常经常使用的数据流套接字和数据报套接字。
在创建了原始套接字后,需要通过setsockopt()函数来设置IP头操作选项,然后再通过bind()函数将原始套接字绑定到本地网卡。
为了让原始套接字能接受所有的数据,还需要通过ioctlsocket()来进行设置,而且还可以指定是否亲自处理IP头。
至此,实际就可以开始对网络数据包进行嗅探了,对数据包的获取仍象流式套接字或数据报套接字那样通过recv()函数来完成。
但是与其他两种套接字不同的是,原始套接字此时捕获到的数据包并不仅仅是单纯的数据信息,而是包含有IP头、TCP头等信息头的最原始的数据信息,这些信息保留了它在网络传输时的原貌。
通过对这些在低层传输的原始信息的分析可以得到有关网络的一些信息。
由于这些数据经过了网络层和传输层的打包,因此需要根据其附加的帧头对数据包进行分析。
二嗅探器与网络安全
2.1计算机网络安全现状
近年来随着Internet的飞速发展,计算机网络的资源共享进一步加强,随之而来的信息安全问题日益突出。
据美国FBI统计,美国每年网络安全问题所造成的经济损失高达75亿美元。
而全球平均每20秒钟就发生一起Internet计算机侵入事件。
在Internet/Intranet的大量应用中,Internet/Intranet安全面临着重大的挑战,事实上,资源共享和安全历来是一对矛盾。
在一个开放的网络环境中,大量信息在网上流动,这为不法分子提供了攻击目标。
而且计算机网络组成形式多样性、终端分布广和网络的开放性、互联性等特征更为他们提供便利。
他们利用不同的攻击手段,获得访问或修改在网中流动的敏感信息,闯入用户或政府部门的计算机系统,进行窥视、窃取、篡改数据。
不受时间、地点、条件限制的网络诈骗,其“低成本和高收益”又在一定程度上刺激了犯罪的增长。
使得针对计算机信息系统的犯罪活动日益增多。
信息泄露:
信息泄露破坏了系统的保密性,他是指信息被透漏给非授权的实体。
常见的,能够导致信息泄露的威胁有:
网络监听、业务流分析、电磁、射频截获、人员的有意或无意、媒体清理、漏洞利用、授权侵犯、物理侵入、病毒、木马、后门、流氓软件、网络钓鱼。
完整性破坏:
可以通过漏洞利用、物理侵犯、授权侵犯、病毒,木马,漏洞来等方式实现。
拒绝服务攻击:
对信息或资源可以合法的访问却被非法的拒绝或者推迟与时间密切相关的操作。
网络滥用:
合法的用户滥用网络,引入不必要的安全威胁,包括非法外联、非法内联、移动风险、设备滥用、业务滥用。
常见的计算机网络络安全威胁的表现形式主要有:
窃听、重传、伪造、篡改、拒绝服务攻击、行为否认、电子欺骗、非授权访问、传播病毒。
窃听:
攻击者通过监视网络数据的手段获得重要的信息,从而导致网络信息的泄密。
重传:
攻击者事先获得部分或全部信息,以后将此信息发送给接收者。
篡改:
攻击者对合法用户之间的通讯信息进行修改、删除、插入,再将伪造的信息发送给接收者,这就是纯粹的信息破坏,这样的网络侵犯者被称为积极侵犯者。
积极侵犯者的破坏作用最大。
拒绝服务攻击:
攻击者通过某种方法使系统响应减慢甚至瘫痪,阻止合法用户获得服务。
行为否认:
通讯实体否认已经发生的行为。
电子欺骗:
通过假冒合法用户的身份来进行网络攻击,从而达到掩盖攻击者真实身份,嫁祸他人的目的.
非授权访问:
没有预先经过同意,就使用网络或计算机资源被看作非授权访问。
传播病毒:
通过网络传播计算机病毒,其破坏性非常高,而且用户很难防范。
2.2嗅探器开发的意义
本次设计只是对抓取到的本机在网络中的通信数据,比如说协议类型、源、目的地址和端口、数据包的大小等加以分析!
作为从事网络技术方面的人员来说,需要有效的利用、防范嗅探器,就要深入的学习、分析嗅探技术。
最为重要的是,对嗅探器的学习使我们对网络通信、数据传输和网络信息安全等有了更深的认识!
三嗅探器的开发基础
3.1嗅探器的实现目标
(1)实现网络嗅探器的界面。
(2)实现抓取数据包的功能。
(3)实现暂停抓取数据包功能。
(4)实现清空列表功能。
3.2嗅探器的技术支持简介
(1)TCP/IP协议分析
TCP/IP是供已连接因特网的计算机进行通信的通信协议。
TCP/IP定义了电子设备(比如计算机)如何连入因特网,以及数据如何在它们之间传输的标准。
TCP/IP是一个四层的分层体系结构。
高层为传输控制协议,它负责聚集信息或把文件拆分成更小的包。
这些包通过网络传送到接收端的TCP层,接收端的TCP层把包还原为原始文件。
低层是网际协议,它处理每个包的地址部分,使这些包正确的到达目的地。
网络上的网关计算机根据信息的地址来进行路由选择。
即使来自同一文件的分包路由也有可能不同,但最后会在目的地汇合。
TCP/IP使用客户端/服务器模式进行通信。
TCP/IP通信是点对点的,意思是通信是网络中的一台主机与另一台主机之间的。
TCP/IP与上层应用程序之间可以说是“没有国籍的”,因为每个客户请求都被看做是与上一个请求无关的。
正是它们之间的“无国籍的”释放了网络路径,才是每个人都可以连续不断的使用网络。
许多用户熟悉使用TCP/IP协议的高层应用协议。
众所周知,如今电脑上因特网都要作TCP/IP协议设置,显然该协议成了当今地球村“人与人”之间的“牵手协议”。
通俗而言:
TCP负责发现传输的问题,一有问题就发出信号,要求重新传输,直到所有数据安全正确地传输到目的地。
而IP是给因特网的每一台电脑规定一个地址。
(2)数据包简介
包是TCP/IP协议通信中的基本的数据单位之一,一般也叫数据包。
必须把内装产品的包装盒放到一个邮局指定的专用纸箱里,这样才能够邮寄。
这里,产品包装盒相当于数据包,里面放着的产品相当于可用的数据,而专用纸箱就相当于帧,且一个帧中只有一个数据包。
“包”听起来非常抽象,那么是不是不可见的呢?
通过一定技术手段,是可以感知到数据包的存在的。
通过数据包捕获软件,也可以将数据包捕获并加以分析。
就是用网络嗅探器捕获数据包,可以查看捕获到的数据包的MAC地址、IP地址、协议类型端口号等细节。
通过分析这些数据,网管员就可以知道网络中到底有什么样的数据包在活动了。
数据包的结构非常复杂,不是三言两语能够说清的,在这里主要了解一下它的关键构成就可以了,这对于理解TCP/IP协议的通信原理是非常重要的。
数据包主要由“目的IP地址”、“源IP地址”、“净载数据”等部分构成。
数据包的结构与我们平常写信非常类似,目的IP地址是说明这个数据包是要发给谁的,相当于收信人地址;源IP地址是说明这个数据包是发自哪里的,相当于发信人地址;而净载数据相当于信件的内容。
正是因为数据包具有这样的结构,安装了TCP/IP协议的计算机之间才能相互通信。
我们在使用基于TCP/IP协议的网络时,网络中其实传递的就是数据包。
比如说当你上网打开网页,这个简单的动作,就是你先发送数据包给网站,它接收到了之后,根据你发送的数据包的IP地址,返回给你网页的数据包,也就是说,网页的浏览,实际上就是数据包的交换。
理解数据包,对于网络管理的网络安全具有至关重要的意义
(3)C++语言
C++是一种编程语言,可用于编辑可执行程序,支持内嵌汇编,有C++/CLI(托管代码)和C++ISO/IEC(本机代码)两种标准。
四网络嗅探器源代码
4.1网络嗅探器源代码及其说明
#include/*windowssocket的头文件,系统定义的*/
#include
#include
#include
#include
#pragmacomment(lib,"ws2_32.lib")/*链接API相关连的Ws2_32.lib静态库*/
#defineMAX_HOSTNAME_LAN255
#defineSIO_RCVALL_WSAIOW(IOC_VENDOR,1)
#defineMAX_ADDR_LEN16
structipheader{
unsignedcharip_hl:
4;/*headerlength(报头长度)*/
unsignedcharip_v:
4;/*version(版本)*/
unsignedcharip_tos;/*typeosservice服务类型*/
unsignedshortintip_len;/*totallength(总长度)*/
unsignedshortintip_id;/*identification(标识符)*/
unsignedshortintip_off;/*fragmentoffsetfield(段移位域)*/
unsignedcharip_ttl;/*timetolive(生存时间)*/
unsignedcharip_p;/*protocol(协议)*/
unsignedshortintip_sum;/*checksum(校验和)*/
unsignedintip_src;/*sourceaddress(源地址)*/
unsignedintip_dst;/*destinationaddress(目的地址)*/
};/*totalipheaderlength:
20bytes(=160bits)*/
typedefstructtcpheader{
unsignedshortintsport;/*sourceport(源端口号)*/
unsignedshortintdport;/*destinationport(目的端口号)*/
unsignedintth_seq;/*sequencenumber(包的序列号)*/
unsignedintth_ack;/*acknowledgementnumber(确认应答号)*/
unsignedcharth_x:
4;/*unused(未使用)*/
unsignedcharth_off:
4;/*dataoffset(数据偏移量)*/
unsignedcharFlags;/*标志全*/
unsignedshortintth_win;/*windows(窗口)*/
unsignedshortintth_sum;/*checksum(校验和)*/
unsignedshortintth_urp;/*urgentpointer(紧急指针)*/
}TCP_HDR;
typedefstructudphdr{
unsignedshortsport;/*sourceport(源端口号)*/
unsignedshortdport;/*destinationport(目的端口号)*/
unsignedshortlen;/*udplength(udp长度)*/
unsignedshortcksum;/*udpchecksum(udp校验和)*/
}UDP_HDR;
voidmain(){
SOCKETsock;
WSADATAwsd;
DWORDdwBytesRet;
unsignedintoptval=1;
unsignedchar*dataudp,*datatcp;
inti,pCount=0,lentcp,lenudp;
SOCKADDR_INsa,saSource,saDest;
structhostentFAR*pHostent;
charFARname[MAX_HOSTNAME_LAN];
charszSourceIP[MAX_ADDR_LEN],szDestIP[MAX_ADDR_LEN],RecvBuf[65535]={0};
structudphdr*pUdpheader;
structipheader*pIpheader;
structtcpheader*pTcpheader;
WSAStartup(MAKEWORD(2,1),&wsd);
if((sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP))==SOCKET_ERROR)
exit
(1);
gethostname(name,MAX_HOSTNAME_LAN);
pHostent=gethostbyname(name);
sa.sin_family=AF_INET;
sa.sin_port=htons(6000);
memcpy(&sa.sin_addr.S_un.S_addr,pHostent->h_addr_list[0],pHostent->h_length);
bind(sock,(SOCKADDR*)&sa,sizeof(sa));/*bind()设定自己主机的IP地址和端口号*/
if((WSAGetLastError())==10013)
exit
(1);
WSAIoctl(sock,SIO_RCVALL,&optval,sizeof(optval),NULL,0,&dwBytesRet,NULL,NULL);
pIpheader=(structipheader*)RecvBuf;
pTcpheader=(structtcpheader*)(RecvBuf+sizeof(structipheader));
pUdpheader=(structudphdr*)(RecvBuf+sizeof(structipheader));
while
(1){
memset(RecvBuf,0,sizeof(RecvBuf));
recv(sock,RecvBuf,sizeof(RecvBuf),0);
saSource.sin_addr.s_addr=pIpheader->ip_src;
strncpy(szSourceIP,inet_ntoa(saSource.sin_addr),MAX_ADDR_LEN);
saDest.sin_addr.s_addr=pIpheader->ip_dst;
strncpy(szDestIP,inet_ntoa(saDest.sin_addr),MAX_ADDR_LEN);
lentcp=(ntohs(pIpheader->ip_len)-(sizeof(structipheader)+sizeof(structtcpheader)));
lenudp=(ntohs(pIpheader->ip_len)-(sizeof(structipheader)+sizeof(structudphdr)));
if((pIpheader->ip_p)==IPPROTO_TCP&&lentcp!
=0){
printf("*******************************************\n");
pCount++;
datatcp=(unsignedchar*)RecvBuf+sizeof(structipheader)+sizeof(structtcpheader);
printf("-TCP-\n");
printf("\n目的IP地址:
%s\n",szDestIP);
printf("\n目的端口:
%i\n",ntohs(pTcpheader->dport));
printf("datatcpaddress->%x\n",datatcp);
printf("sizeofipheader->%i\n",sizeof(structipheader));
printf("sizeoftcpheader->%i\n",sizeof(structtcpheader));
printf("sizeoftheholepacket->%i\n",ntohs(pIpheader->ip_len));
printf("\ncharPacket%i[%i]=\"",pCount,lentcp-1);
for(i=0;iprintf("\\x%.2x",*(datatcp+i));
if(i%10==0)
printf("\"\n\"");
}
printf("\";\n\n\n");
for(i=0;iif(*(datatcp+i)<=127&&*(datatcp+i)>=20)
printf("%c",*(datatcp+i));
else
printf(".");
}
printf("\n\n*******************************************\n");
}
if((pIpheader->ip_p)==IPPROTO_UDP&&lentcp!
=0){
pCount++;
dataudp=(unsignedchar*)RecvBuf+sizeof(structipheader)+sizeof(structudphdr);