sniffer设计与实现Word文件下载.docx
《sniffer设计与实现Word文件下载.docx》由会员分享,可在线阅读,更多相关《sniffer设计与实现Word文件下载.docx(12页珍藏版)》请在冰豆网上搜索。
//初始化对话框,把已经查找出来的网络设备显示在下拉列表中
virtualvoidOnCancel();
//弹出对话框,并退出程序
获取本地网卡列表所使用的函数以及代码在实验指导书中都有,这里就不过多介绍了。
主对话框:
主对话框中使用了checkbox控件,listcontrol控件,以及五个button控件。
在ClassWizard里定义变量:
listcontrol控件变量CListCtrlm_list,BOOL型的checkbox变量m_arpFilter;
m_icmpFilter;
m_ipFilter;
m_tcpFilter;
m_udpFilter。
在WincapaDlg.cpp中定义结构体:
structETHDR{//以太网头部
u_chareh_dst[6];
u_chareh_src[6];
u_shorteh_type;
//IP?
ARP?
};
typedefstructip_header{/*IPv4header*/
u_charver_ihl;
//Version(4bits)+Internetheaderlength(4bits)
u_chartos;
//Typeofservice
u_shorttlen;
//Totallength
u_shortidentification;
//Identification
u_shortflags_fo;
//Flags(3bits)+Fragmentoffset(13bits)
u_charttl;
//Timetolive
u_charproto;
//Protocol
u_shortcrc;
//Headerchecksum
u_intsaddr;
//Sourceaddress
u_intdaddr;
//Destinationaddress
u_intop_pad;
//Option+Padding
}ip_header;
structTCPPacketHead{/*TCPheader*/
u_shortSourPort;
u_shortDestPort;
u_intSeqNo;
u_intAckNo;
u_charHLen;
u_charFlag;
u_shortWndSize;
u_shortChkSum;
u_shortUrgPtr;
structUDPPacketHead{/*UDPheader*/
u_shortsport;
//Sourceport
u_shortdport;
//Destinationport
u_shortlen;
//Datagramlength
//Checksum
structICMPPacketHead{/*ICMPheader*/
u_chartype;
u_charcode;
u_shortchkSum;
typedefstructARP_header{//ARPheader
u_charhardware;
u_charproto;
u_shorthaddresslen;
u_shortpaddresslen;
u_charsmaddr[6];
//sourcemacaddress
u_intsaddr;
//soureipaddress
u_chardmaddr[6];
//destinationmacaddress
u_intdaddr;
//destinationipaddress
}ARP_header;
在ClassWizard里添加成员函数:
OnInitDialog(),OnSysCommand(UINTnID,LPARAMlParam),OnPaint(),HCURSOROnQueryDragIcon()等。
下面会做具体介绍:
BOOLCWincapaDlg:
:
OnInitDialog()函数中,对对话框进行初始化,主要是对listcontrol控件的初始化操作,添加“数据”,“大小”,“目的端口”,“目的MAC地址”,“目的地址”,“源端口”,“源MAC地址”,“源地址”,“序号”共十列。
主要代码如下:
m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
m_list.InsertColumn(0,"
数据"
LVCFMT_LEFT,335);
大小"
LVCFMT_LEFT,40);
…………
CFont*font=CFont:
FromHandle((HFONT):
GetStockObject(DEFAULT_GUI_FONT));
voidCWincapaDlg:
OnStart()函数是在ClassWizard对IDD_START按钮添加的响应函数,主要是进行数据包的捕获,因为MFC中对pcap_loop()函数不兼容,所以在工程中我使用了线程函数,如上代码所示,而在OnStart()函数中调用线程AfxBeginThread(threadFunc,(LPVOID)this);
即可是捕获数据包。
流程图中为wincap捕获数据包的流程:
线程函数
UINTthreadFunc(LPVOIDp)
{
CWincapaDlg*pDlg=static_cast<
CWincapaDlg*>
(p);
intres;
structpcap_pkthdr*header;
constu_char*pkt_data;
while(!
isStop&
&
(res=pcap_next_ex(adhandle,&
header,&
pkt_data))>
=0)
{
if(res==0)//Timeoutelapsed
continue;
u_chara='
s'
;
pDlg->
intepretPacket(&
a,header,pkt_data);
//解释报文
}
if(res==-1){
CStringtmp;
tmp.Format("
Errorreadingthepackets:
%s\n"
pcap_geterr(adhandle));
AfxMessageBox(tmp);
exit
(1);
}
pcap_close(adhandle);
return-1;
}
applyFilter(pcap_t*fp,char*packet_filter,bpf_u_int32NetMask,structbpf_programfcode)函数设置过滤规则。
在OnStart()函数中调用此函数。
通过m_arpFilter;
m_udpFilter,当选中其中某项时,变量的值变为TRUE型(默认为FALSE),把过滤表达式线程相应的网络协议类型。
比如,选中arp协议项,通过判断m_arpFilter==TRUE,strcpy(packet_filter,"
arp"
);
将过滤表达式设置为arp,使用pcap_compile(fp,&
fcode,packet_filter,1,NetMask)以及pcap_setfilter(fp,&
fcode)设置过滤规则。
intepretPacket(u_char*param,constpcap_pkthdr*header,constu_char*pkt_data)函数,主要是分析数据包,根据接收的数据包的字段类型进行分类。
如线程代码所示,在线程中调用此函数。
将分析出的数据包的协议,源MAC地址,目的MAC地址,源地址,源端口,目的地址,目的端口,大小,数据等信息都通过格式化xx.Format()函数转换为其对应的格式,添加到listcontrol列表中。
下面的流程图为区分四种协议的流程图。
ARP:
以太网的协议类型值为0x0806;
IP:
以太网的协议类型值为0x0800;
UDP:
IP的协议类型值为17;
TCP:
IP的协议类型值为6;
ICMPIP的协议类型值为1。
insertData(CStrings1,CStrings2,CStrings3,CStrings4,CStrings5,CStrings6,CStrings7,CStrings8,CStrings9,CStrings10)函数将分析出的数据包信息写入listcontrol列表,函数在intepretPacket()中调用。
部分代码如下:
intindex;
index=m_list.InsertItem(0,s1);
m_list.SetItem(index,1,LVIF_TEXT,s2,0,0,0,0);
……
OnStop()函数是在ClassWizard对IDD_STOP按钮添加的响应函数,停止捕获数据包,并显示已经捕获的不同协议数据包的数量。
在工程中定义4个staticint的全局变量,c_tcp,c_udp,c_icmp,c_arp,在OnStart函数中对其值初始化为0,在intepretPacket函数中在相应的协议中进行累加,最后用MessageBox把其值显示出来。
以下为设置ARP过滤的捕获停止的截图:
OnClear()函数是在ClassWizard对IDD_CLEAR按钮添加的响应函数,清除listcontrol列表中的数据内容,使用m_list.DeleteAllItems()。
OnSavelist()函数在ClassWizard对IDD_SAVELIST按钮添加的响应函数,用于将listcontrol列表中的数据内容存放在数据库中。
我所使用的数据库为MYSQL,在数据库中建立了命名为sniffer的表单,在安装数据库时,设定用户名为root,密码为123。
连接数据库使用的代码:
if(m_list.GetItemCount()==0){
MessageBox("
没有数据要存储!
!
"
return;
}
u_inti;
MYSQL*db;
db=mysql_init(0);
//初始化数据库
CStringstr1,str2,str3,str4,str5,str6,str7,str8,str9,str10,sqls;
if(mysql_real_connect(db,"
localhost"
"
root"
123"
sniffer"
3306,NULL,0))//连接数据库{
for(i=1;
i<
=num;
i++){
str1=m_list.GetItemText(num-i,0);
str2=m_list.GetItemText(num-i,1);
str3=m_list.GetItemText(num-i,2);
…………
//把列表中的数据插入数据库中
sqls="
INSERTINTOsnifferVALUES('
+str1+"
'
'
+str2+"
+str3+"
+str4+"
……)"
mysql_query(db,sqls);
}
存储成功!
截图如下:
存储显示
数据库内容:
OnExit()函数是在ClassWizard对IDD_EXIT按钮添加的响应函数,退出程序。
SendMessage(WM_CLOSE);
关闭对话框。
2.ARP欺骗
ARP工作原理
首先,每台主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址的对应关系。
当源主机需要将一个数据包要发送到目的主机时,会首先检查自己ARP列表中是否存在该IP地址对应的MAC地址,如果有﹐就直接将数据包发送到这个MAC地址;
如果没有,就向本地网段发起一个ARP请求的广播包,查询此目的主机对应的MAC地址。
此ARP请求数据包里包括源主机的IP地址、硬件地址、以及目的主机的IP地址。
网络中所有的主机收到这个ARP请求后,会检查数据包中的目的IP是否和自己的IP地址一致。
如果不相同就忽略此数据包;
如果相同,该主机首先将发送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP表中已经存在该IP的信息,则将其覆盖,然后给源主机发送一个ARP响应数据包,告诉对方自己是它需要查找的MAC地址;
源主机收到这个ARP响应数据包后,将得到的目的主机的IP地址和MAC地址添加到自己的ARP列表中,并利用此信息开始数据的传输。
如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。
ARP欺骗过程
ARP协议并不只在发送了ARP请求才接收ARP应答。
当计算机接收到ARP应答数据包的时候,就会对本地的ARP缓存进行更新,将应答中的IP和MAC地址存储在ARP缓存中。
所以在网络中,有人发送一个自己伪造的ARP应答,网络可能就会出现问题。
设一个网络环境中,网内有三台主机,分别为主机A、B、C。
主机详细信息如下描述:
A的地址为:
192.168.1.102MAC:
00-16-d3-fb-8c-c5
B的地址为:
192.168.1.101MAC:
00-1e-ec-94-e8-0c
C的地址为:
192.168.1.103MAC:
00-22-15-22-81-88
正常情况下A和C之间进行通讯,但是此时B向A发送一个自己伪造的ARP应答,而这个应答中的数据为发送方IP地址是192.168.1.103(C的IP地址),MAC地址是00-1e-ec-94-e8-0c(C的MAC地址本来应该是00-22-15-22-81-88,这里被伪造了)。
当A接收到B伪造的ARP应答,就会更新本地的ARP缓存(A被欺骗了),这时B就伪装成C了。
同时,B同样向C发送一个ARP应答,应答包中发送方IP地址192.168.1.102(A的IP地址),MAC地址是00-1e-ec-94-e8-0c(A的MAC地址本来应该是00-16-d3-fb-8c-c5),当C收到B伪造的ARP应答,也会更新本地ARP缓存(C也被欺骗了),这时B就伪装成了A。
这样主机A和C都被主机B欺骗,A和C之间通讯的数据都经过了B。
实验截图:
欺骗成功
实验关键代码(发送ARP数据包):
arp_packetpacket;
//设置目的MAC地址
packet.eth.dest_mac[0]=00;
packet.eth.dest_mac[1]=16;
packet.eth.dest_mac[2]=d3;
packet.eth.dest_mac[3]=fb;
packet.eth.dest_mac[4]=8c;
packet.eth.dest_mac[5]=c5;
//假设源MAC地址为本地IP地址
packet.eth.source_mac[0]=00;
packet.eth.source_mac[1]=1e;
packet.eth.source_mac[2]=ec;
packet.eth.source_mac[3]=94;
packet.eth.source_mac[4]=e8;
packet.eth.source_mac[5]=0c;
//填充数据包
packet.eth.eh_type=htons(0x0806);
//ARP
packet.arp.hardware_type=htons(0x0001);
packet.arp.protocol_type=htons(0x0800);
packet.arp.add_len=0x06;
packet.arp.pro_len=0x04;
packet.arp.option=htons(0x0002);
packet.arp.saddr=arp->
daddr;
packet.arp.daddr=arp->
saddr;
memcpy(packet.arp.dest_addr,arp->
sour_addr,6);
memcpy(packet.arp.sour_addr,packet1,6);
for(i=0;
18;
packet.arp.padding[i]=1;
psend=(unsignedchar*)&
packet;
//强制转换发送的数据包的类型
//发送数据包
pcap_sendpacket(adhandle,psend,sizeof(psend));
3.试验中出现的问题以及解决方案
(1)ComboBox控件无法下拉
工程运行时发现,对话框中的下拉列表只能显示第一个网卡的信息。
解决方法:
把鼠标放在下拉列表的
处,当光标的形状变成上下箭头时,点击下拉框的中间白点,向下拉即可。
(2)Wincap中的部分函数与MFC中的函数redefine,重定义
在link过程中,出现wincap中的一些函数以及变量重定义的错误,比如pcap_complile等。
在StdAfx.h文件中加上
#defineWIN32_LEAN_AND_MEAN
#include<
windows.h>
winsock2.h>
(3)编译时出现如下问题:
packet32.h(231):
errorC2079:
IPAddress'
usesundefinedstruct'
sockaddr_storage'
解决方法:
1.向winpcap库的packet32.h文件中加入如下代码,且应位于“structnpf_if_addr”定义之前:
#ifndef_SS_PAD1SIZE
structsockaddr_storage{
u_charsa_len;
u_charsa_family;
u_charpadding[128];
#endif
2.将sockaddr_storage
改成
sockaddr。
(4)添加mysql时出现错误
解决方式:
把mysql的Include,Lib.debug目录添加进VC6.0的环境变量中;
针对每一个项目,先用VC打开项目,然后在"
Project->
Settings"
,择"
Link"
,在"
Object/librarymodules"
的输入框里添加"
libmysql.lib"
。
在StdAfx.h文件中加上#include"
afxdb.h"
和#include"
mysql.h"
(5)在arp欺骗的工程中出现连接错误,需要在"
wsock32.lib"
4.实践总结
实验结论:
通过了近一个多星期的努力学习与实践运用,终于制作出了一个实现网络嗅探的基本功能的网络嗅探器,较为合理、圆满的完成了本实验的各项实验要求,取得了应有的实验效果。
能列出监测主机的所有网卡,并显示在网卡列表框中。
能选择其中的一个网卡进行监听,并记录器数据信息
能捕获并显示流经网卡的数据包,并做相应的分析和统计
能设置捕获过滤规则
在TCP、UDP、ARP、ICMP、等协议都能进行重点分析
能按照协议格式进行格式化显示
有可视化操作界面,易于使用
对ARP欺骗有了比较系统的了解,可以进行比较简单的ARP欺骗
实验体会:
通过自学,亲自动手,一点一滴的积累并实现,完成了一个具备了基本功能的网络嗅探器,受益良多。
学习了WinPcap开发工具包,对其在网络底层实现和接口运用的方面,有了更加清楚、较为深入的认识与掌握,熟练学会了如何利用WinPcap工具开发上实现网络协议编程。
通过实现了一个基于WinPcap的网络嗅探器,我对网络协议栈有了更加深入的了解与认识,并懂得了基本的网络协议栈的实现与应用,对以后网络学习和网络编程,将会大有裨益。
通过自己制作网络嗅探器,我对网络嗅探器的开发流程、基本原理和应用领域,有了大体的认识与掌握,知道制作网络嗅探器的基本方法与步骤,并知道如何利用网络嗅探器应用于自己所关心的网络领域。
通过近一个多星期的学习、理解、实践、掌握、应用WinPcap和网络嗅探器,我对新知识、新事物的学习、实践与应用的方法与途径,有了更加深入的认识与掌握,能够较为快速的汲取新知识、运用新概念、应用于新领域,这种能力的培养,才是最重要的,也将是对我以后的学习和工作,会产生很好的引导与启发作用。
通过学习ARP欺骗,可以简单的完成黑客的基本工作。