网络攻击与防范实验报告
姓名:_ _ 学号:_ __ 所在班级:
实验名称:编写自己的网络嗅探器实验日期:2014 年10 月22 日指导老师:张玉清、宋杨实验评分:
验收评语:
实验目的:
通过开发基于WinPcap的嗅探器,掌握嗅探器的工作原理,熟悉WinPcap的使用,掌握基于WinPcap网络嗅探器的开发过程。
实验内容:
开发出一个任意平台上的Sniffer(嗅探器)工具,能显示所捕获的局域网数据包并能做相应的分析和统计。主要内容如下:
?列出监测主机的所有网卡,选择一个网卡,设置为混杂模式进行监听。
?捕获所有流经网卡的数据包,并利用WinPcap函数库设置过滤规则。
?分析捕获到的数据包的包头和数据,按照各种协议的格式进行格式化显示。
?将所开发工具的捕获和分析结果与常用的Sniffer进行比较,完善程序代码。
实验环境:
硬件环境:
处理器:Intel(R) Core(TM) i5-3337U CPU @
内存:
硬盘:600G
网卡:Intel(R) Centrino(R) Wireless-N 2230 / Realtek PCIe FE 系列控制器
网速:约200KB/s
软件环境:
操作系统:Windows x64位操作系统
开发工具:Visual Studio 2013
开发语言:C#
实验设计:
SharpPcap 是一个.NET 环境下的网络包捕获框架,是基于WinPcap 库开发。提供了捕获、注入、分析和构建的功能,适用于C# 和VB NET开发语言。本实验利用SharpPcap提供的这些网络接口获取到底层的网卡信息及其数据包,并且支持捕获前过滤条件和捕获后过滤条件的设定。再根据TCP/IP协议栈的结构(typeof(ProtocolPacket))和方法依次在数据链路层、网络层、数据传输层和应用层,分别进行数据包的分拆与解析,获取相应协议层的数据信息,并根据应用程序的端口信息找出其对应的数据包,例如Microsoft-SQL-Server、MySQL、Telnet、QQ、Tomcat等等。实验还对几个最常用的协议,如ARP、IP、ICMP、TCP、UDP等协议的数据包数量进行统计,并用柱状图的形式展现给用户。最后,还从网络层、传输层、应用层三个层次对数据包进行分类,计算它们的百分比,以饼图的形式展现。
1、界面设计:
图 1 主窗口设计视图
本系统主窗口主要分为9个部分。
第一部分:菜单
菜单栏总共有三项,包括“文件”、“查看”、“帮助”。“文件”菜单项包含常规的几个子菜单:“打开”“保存”“另存为”“退出”;“查看”包括“柱状图”和“饼图”两个子菜单;“帮助”菜单包括“使用帮助”和“关于MySniffer”,下面介绍各个子菜单的功能。
?打开:打开Pcap文件,从文件中读取数据包。
?保存:将当前捕获的流量包保存到用户选择的位置。
?另存为:暂时作用与“保存”相同。
?退出:退出系统。
?柱状图:如图4所示,以柱状图的形式显示捕获到的数据包,方便用户直观的看到数据包的数量情况,可以对ARP、IP、ICMP、TCP、UDP、HTTP、DNS这几种协议的数据包的个数进行比较。
?饼图:如图5所示,以饼图的形式显示捕获到的数据包在不同协议层的分类情况,包括,网络层、传输层和应用层,饼图的左侧图例上显示了每种数据包在该协议层所占的比例,主要的饼图部分更能直观的反应比例关系。最后一个应用层,由于应用的种类实在太多,因此这里只统计了常见的14种应用,详见图5中的图例。
?使用帮助:弹出使用帮助对话框,目前内容只是告诉捕获前过滤条件如何设置,还没有加上软件的使用说明,有待完善。如图6。
?关于MySniffer:弹出版本信息对话框,如图7所示。
?
图 2 打开文件选项
?
图 3 保存流量包到文件
第二部分:选择网卡
选择网卡是个下拉菜单,在窗口初始化的时候对下拉菜单进行初始化,将获得的网卡列表加入下拉菜单,用户可以通过点击想要打开的网卡进行网卡的选择
第三部分:捕获前过滤条件
设置捕获前过滤条件,该过滤条件由Winpcap规定,在上面的使用帮助对话框中可以得到提示。
第四部分:开始抓包和停止抓包按钮
点击开始抓包,选中的网卡被打开,开始捕获数据包,此时开始抓包按钮和捕获前过滤文本框变成不可用状态,停止抓包按钮从刚开始的不可用变成可用。如果没有选择网卡将给出提示框。
第五部分:捕获后过滤条件
设置捕获后过滤条件,这里也做成了下拉菜单的形式,有20种选项,包括ARP、IP、ICMP、TCP、UDP等等,当用户点击过滤按钮的时候,下面的数据包列表框中的内容就会发生改变。第六部分:封包总览
封包总览包括时序号、时间、源地址、目的地址、协议、长度这六项。
第七部:封包内容
封包内容以树状图的形式展示,对数据包进行数据链路层、网络层、传输层、应用层四个层次的展开,最后除去所有的包头得到最终的有用数据。用户可以根据需要展开和折叠内
容。
第八部分:十六进制码以及对应的ASCII码
将数据包的内容转化成ASCII码显示。
第九部分:统计已经抓到的数据包的个数。
图 4 部分数据包统计柱状图
图 5 各协议层数据包统计饼图
图 6 使用帮助对话框
图7 关于对话框
2、工作流程及算法设计:
本系统中的工作流程主要网络数据包的捕获、数据包的接收,以及数据包的分析处理这三个部分。
其中数据包的捕获又可以分为两种,一种是用网卡直接进行数据包的捕获,具体流程如图8所示;另一种方式是从pcap文件中读取数据包,然后进行分析,当用户点击文件菜单中的打开按钮时,创建一个虚拟设备,从文件中读取数据包的信息到内存中,除了利用的是虚拟设备这个跟第一种方式不同以外,对数据包的处理方法都是一样的。
图8 网络数据捕获流程图
数据包的接收也就是device_OnPacketArrival这个事件的实现。在这个啥时间中,我们对捕获到的数据包进行分析,找到里面包含的数据包类型,比如一个数据包是以太网数据包,去掉以太网包头以后里面可能是一个IP数据包,再去掉IP包头以后里面是一个TCP数据包,然后根据数据包的源端口和目的端口我们可以大概的判断这是哪个应用的数据包,像FTP 的端口是20和21,Telnet的端口是23等等。这样,我们就可以将数据包添加到相应的packet 队列,具体流程如图9所示。
图9 网络数据捕获流程图
在捕获到数据以后,开启后台线程对packet队列进行处理和显示,将packet中的基本信息,如序列、捕获到的时间、源地址、目的地址、使用的协议、数据包的长度等等,然后将其显示在ListView中,具体流程如图10所示。在用户点击ListView中的一行的时候调用包解析函数对数据包进行分析,得到各个协议层的源地址、目的地址、数据包长度等信息,以及最
终内部的有用数据,显示在下面的两个方框中,一个以树状图的形式显示,另一个显示十六进制内容和对应的ASCII码。
图10 数据包列表显示流程图
详细过程:
1、数据结构:
本系统中定义的数据结构如下:
(1)网络设备
public CaptureDeviceList devices; lear();
();
try{
if
{
();
} }catch{ }
ThreadStartthread=newThreadStart(Backgroundprocess);
_Backgroundthread=newThread(thread);
();cap)|*.pcap";
if() ==
{
CaptureFileReaderDevice captureFileReader = new
CaptureFileReaderDevice;
ount)
{
RawCapture Addpacket;
lock (QueueLock)
{
Addpacket = PacketQueue[QueueNum][_count];
}
_count++;
ListViewItem item = new ListViewItem();
var time = [0].Text = ();
string souce = "", destination = "", type = "";
var packet = ;
if (packet is
{
var eth = (packet);
souce = destination =
if (destination == "ffffffffffff" || destination == "FFFFFFFFFFFF")
destination = "广播地址";
type = var ipPacket =
if (ipPacket != null)
{
souce = if
souce += "IPv6链接本地地址";
if souce += "IPv6多路广播全局地址";
if souce += "IPv6站点本地地址";
if souce += "IPv6 Teredo地址";
destination = if destination = "IPv6链接本地地址";
if destination = "IPv6多路广播全局地址";
if destination = "IPv6站点本地地址";
if destination = "IPv6 Teredo地址";
type = var tcpPacket =
if (tcpPacket != null)
{
if == 80 || == 80)
{
type = "HTTP";
}
else if == 443)
type = "HTTPS";
else if == 21)
type = "FTP";
else
type = "tcp" + ":" + + " to "
+ }
var udpPacket = if (udpPacket != null)
{
if == 53)
{
type = "DNS";
}
else
type = "udp" + ":" + + " to "
+ }
}
}
if
();
if
= "ETH:" + + " ARP:" + + " IP:" + PacketQueue[2].Count + " TCP:" + PacketQueue[3].Count + " UDP:" + PacketQueue[4].Count + " HTTP:" + PacketQueue[5].Count;
}
}
}
7、解析数据包
当封包总览中的某一行被选中时,在下面两个方框中显示包的具体信息,第一框显示解析出来的内容,第二个框显示十六进制码和转换出来的ASKII码。也就是在点击ListView的某一行时,对这一行所对应的数据进行解析,并将解析的结果放到下面的两个框中。具体实现如下:
private void listView1_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
RawCapture Select_Packet;
Select_Packet = PacketQueue[QueueNum][];
oString("X2") + " ";
}
for (; j < 16; j++)
{
if (j % 8 == 0)
Str[i] += " ";
Str[i] += " ";
}
Str[i] += " ";
for (j = 0; (j < 16) && (i * 16 + j < j++)
{
if [i * 16 + j] < 32 || [i * 16 + j] > 126)
Str[i] += ".";
else
{
Str[i] += [i * 16 + j]);
}
}
}
for (int i = 0; i <= / 16; i++)
{
+= Str[i] + }
var packet = ;
();
"Frame " + + 1).ToString() + ":" + + " bytes 被捕获");
[0].("链路层类型:" + [0].("捕获时间:" + + " " + [0].("数据帧长:" + + "bytes");
if (packet is
{
var eth = (packet);
"以太网数据包:");
[1].("源地址:" + ;
[1].("目的地址:" + ;
[1].("上层协议" + if is
{
var arp = (;
"ARP数据包:" + + " bytes");
[2].("操作:" + ;
[2].("协议地址类型:" + + " 协议地址长度:" + + " bytes");
[2].("发送者硬件地址:" + + " 发送者协议地址:" + ;
[2].("目标硬件地址:" + + " 目标协议地址:" + ;
}
var ip = if (ip != null)
{
"IP数据包:" + + " bytes");
[2].("版本:" + + " 首部长度:" + ;
[2].("源地址:" + ;
[2].("目的地址:" + ;
if (ip is
{
var ipv4 = (ip);
[2].("IPv4数据包:");
[2].Nodes[3].("分片标志:" + + " 片偏移:" + ;
[2].Nodes[3].("标识:" + ;
[2].Nodes[3].("TOS服务类型:" + ;
}
if (ip is
{
var ipv6 = (ip);
[2].("IPv6数据包:");
[2].Nodes[3].("流量类型:" + ;
[2].Nodes[3].("流标签:" + ;
}
[2].("协议类型:" + ;
[2].("TTL生存期:" + ;
if is
{
var icmpv4 = ;
"ICMPv4数据包:");
[3].("类型编码:" + ;
[3].("序号:" + + " ID:" + ;
}
if is
{
var icmpv6 = ;
"ICMPv6数据包:");
[3].("编码:" + ;
[3].("类型:" + ;
}
var tcp = if (tcp != null) {
"TCP数据包:");
[3].("源端口:" + + " 目的端口:" + ;
[3].("标志位:0x" + "X2"));
[3].Nodes[1].("CWR:" + ;
[3].Nodes[1].("ECN:" + ;
[3].Nodes[1].("URG:" + ;
[3].Nodes[1].("ACK:" + ;
[3].Nodes[1].("PSH:" + ;
[3].Nodes[1].("RST:" + ;
[3].Nodes[1].("SYN:" + ; [3].Nodes[1].("FIN:" + ; [3].("序列号:" + ;
[3].("确认号:" + ;
[3].("窗口大小:" + ;
[3].("紧急指针:" + ;
[3].("数据偏移(首部长):" + ; if ((ip is && > 54)
{
if == 80 || == 80)
{
"HTTP数据包:");
}
else if == 443)
{
"HTTPS数据包:");
}
else
{
"数据:");
}
string tcpdata = "";
for (int i = 54; i < i++)
{
if [i] < 32 || [i] > 126)
tcpdata += ".";
else
tcpdata += [i]);
if > 40)
{
[4].(tcpdata);
tcpdata = "";
}
}
[4].(tcpdata);
}
if ((ip is && > 74)
{
if == 80 || == 80)
{
"HTTP数据包:");
}
else if == 443)
{
"HTTPS数据包:");
}
else
{
"数据:");
}
string tcpdata = "";
for (int i = 74; i < i++)
{
if [i] < 32 || [i] > 126)