您的位置:首页 > Web前端

简易sniffer演示程序

2015-10-07 09:20 531 查看
这是网络攻防课的一次实验,完成之后简单整理一下发布到博客中。

实验内容:

开发出一个任意平台上的Sniffer(嗅探器)工具,能显示所捕获的局域网数据包并能做相应的分析和统计。主要内容如下:

列出监测主机的所有网卡,选择一个网卡,设置为混杂模式(网卡能够接收所有经过它的数据流,而不论其目的地址是否是它。)

进行监听。捕获所有流经网卡的数据包,并利用WinPcap函数库设置过滤规则。分

析捕获到的数据包的包头和数据,按照各种协议的格式进行格式化显示。

实验环境:

 开发平台:Window 7 ~32bit

开发环境:Microsoft Visual Studio 2012

开发语言:C#

库环境:WinPcapV4.1.3、SharpPcap V4.2.0

dell文件下载地址:http://pan.baidu.com/s/1pJG4Iwj

实验设计:

本实验的目标主要是利用WinPcap开发包工具,独立开发出一个网络嗅探器。

分析整个嗅探器工作流程,首先需要获取本地网络适配器借口列表,然后需要选择适配器接口并打开,开启监听并根据过滤规则开始捕获数据包。捕获到的数据包需要实时显示在窗体控件中,并进行必要的统计。

程序流程图如下:



效果图如下:



主要功能代码实现:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.IO;
using Tamir.IPLib;
using Tamir.IPLib.Packets;
using Tamir.IPLib.Protocols;
using System.Collections;

namespace sniffer
{
public partial class sniffer : Form
{
PcapDeviceList devices ;
PcapDevice device ;
PcapDevice device1;
Packet pac;
int index=1;
int ipnum = 0;
int icmpnum = 0;
int tcpnum = 0;
int udpnum = 0;
int arpnum = 0;
int sum = 0;
private delegate void ControlDelegate(Packet packet);
public struct Info
{
public int index1;
public DateTime time1;
public int len1;
public int hwtype1;
public int protocoltype1;
public int hwaddresslength1;
public int operation1;
public string srcIp1;
public string dstIp1;
public string srchwaddress1;
public string dsthwaddress1;
public int srcPort1;
public int dstPort1;
public string pr1;
public int version1;
public int ipheaderlength1;
public int sevicetype1;
public int totallength1;
public int flag1;
public int fragflag1;
public int livetime1;
public int protocol1;
public int checksum1;
public long sequencenum1;
public int code1;
public byte[] data1;
}
List<Info> array = new List<Info>();

public sniffer()//初始化
{
InitializeComponent();
btnstop.Enabled = false;
}

private void btnstart_Click(object sender, EventArgs e)//开始按钮响应事件
{
btnstop.Enabled = true;
btnstart.Enabled = false;
if (cmb_netcard.Text == "")
{
MessageBox.Show("请选择网卡");
btnstart.Enabled = true;
btnstop.Enabled = false;
}
else
{
//打开所选网卡接口进行监听
device = devices[cmb_netcard.Items.IndexOf(cmb_netcard.Text)];
device1 = devices[cmb_netcard.Items.IndexOf(cmb_netcard.Text)];
int readTimeoutMilliseconds = 1000;
device.PcapOpen(true, readTimeoutMilliseconds);
device1.PcapOpen(true, readTimeoutMilliseconds);
if (cmb_fliter.Text.ToString() == "tcp" || cmb_fliter.Text.ToString() == "udp" || cmb_fliter.Text.ToString() == "ip" || cmb_fliter.Text.ToString() == "icmp" || cmb_fliter.Text.ToString() == "arp")
{
string filter = cmb_fliter.Text.ToString();
device.PcapSetFilter(filter);
device1.PcapSetFilter(filter);
}

device.PcapOnPacketArrival += device_PcapOnPacketArrival;
device1.PcapOnPacketArrival += new SharpPcap.PacketArrivalEvent( device_PcapOnPacketArrivalfile);
device1.PcapDumpOpen("test.pcap");
device.PcapStartCapture();
device1.PcapStartCapture();
}
}

private void show_arp(Packet packet )//解析并显示统计ARP包
{

if (dvinfo.InvokeRequired)
{
ControlDelegate cd = new ControlDelegate(show_arp);
this.Invoke(cd, new object[] { packet });
}
else
{
DateTime time = packet.PcapHeader.Date;
int len = packet.PcapHeader.PacketLength;
ARPPacket arp = (ARPPacket)packet;
int hwtype = arp.ARPHwType;
int protocoltype = arp.ARPProtocolType;
int hwaddresslength = arp.ARPHwLength;
int operation = arp.ARPOperation;
string srchwaddress = arp.ARPSenderHwAddress;
string dsthwaddress = arp.ARPTargetHwAddress;
string srcIp = arp.ARPSenderProtoAddress;
string dstIp = arp.ARPTargetProtoAddress;
Info info = new Info();
info.index1 = index++;
info.time1 = time;
info.len1 = len;
info.hwtype1 = hwtype;
info.protocoltype1 = protocoltype;
info.hwaddresslength1 = hwaddresslength;
info.operation1 = operation;
info.srchwaddress1 = srchwaddress;
info.dsthwaddress1 = dsthwaddress;
info.srcIp1 = srcIp;
info.dstIp1 = dstIp;
info.pr1 = "ARP";
info.data1 = arp.EthernetData;
array.Add(info);
string[] arr = {info.index1.ToString(),info.time1.ToString(),info.len1.ToString(),info.srcIp1,info.dstIp1,info.srcPort1.ToString(),info.dstPort1.ToString(),info.pr1 };
dvinfo.Rows.Add(arr);
arpnum = arpnum + 1;
sum = sum + 1;
tbxarp.Text = arpnum.ToString();
tbxsum.Text = sum.ToString();

}
}

private void show_tcp(Packet packet)//解析并显示统计TCP包
{

if (dvinfo.InvokeRequired)
{
ControlDelegate cd = new ControlDelegate(show_tcp);
this.Invoke(cd, new object[] { packet });
}
else
{
DateTime time = packet.PcapHeader.Date;
int len = packet.PcapHeader.PacketLength;
TCPPacket tcp = (TCPPacket)packet;
int checksum = tcp.Checksum;
long sequencenum = tcp.SequenceNumber;
string srcIp = tcp.SourceAddress;
string dstIp = tcp.DestinationAddress;
int srcPort = tcp.SourcePort;
int dstPort = tcp.DestinationPort;
string srchwaddress = tcp.SourceHwAddress;
string dsthwaddress = tcp.DestinationHwAddress;
Info info = new Info();
info.index1 = index++;
info.time1 = time;
info.len1 = len;
info.checksum1 = checksum;
info.sequencenum1 = sequencenum;
info.srcIp1 = srcIp;
info.srcPort1 = srcPort;
info.dstIp1 = dstIp;
info.dstPort1 = dstPort;
info.srchwaddress1 = srchwaddress;
info.dsthwaddress1 = dsthwaddress;
info.pr1 = "TCP";
info.data1 = tcp.TCPData;
array.Add(info);
string[] arr = { info.index1.ToString(), info.time1.ToString(), info.len1.ToString(), info.srcIp1, info.dstIp1, info.srcPort1.ToString(), info.dstPort1.ToString(), info.pr1 };
dvinfo.Rows.Add(arr);
tcpnum = tcpnum + 1;
sum = sum + 1;
tbxtcp.Text = tcpnum.ToString();
tbxsum.Text = sum.ToString();

}
}

private void show_udp(Packet packet)//解析并显示统计UDP包
{

if (dvinfo.InvokeRequired)
{
ControlDelegate cd = new ControlDelegate(show_udp);
this.Invoke(cd, new object[] { packet });
}
else
{
DateTime time = packet.PcapHeader.Date;
int len = packet.PcapHeader.PacketLength;
UDPPacket udp = (UDPPacket)packet;
int checksum = udp.Checksum;
string srchwaddress = udp.SourceHwAddress;
string dsthwaddress = udp.DestinationHwAddress;
string srcIp = udp.SourceAddress;
string dstIp = udp.DestinationAddress;
int srcPort = udp.SourcePort;
int dstPort = udp.DestinationPort;
Info info = new Info();
info.index1 = index++;
info.time1 = time;
info.len1 = len;
info.checksum1 = checksum;
info.srchwaddress1 = srchwaddress;
info.dsthwaddress1 = dsthwaddress;
info.srcIp1 = srcIp;
info.srcPort1 = srcPort;
info.dstIp1 = dstIp;
info.dstPort1 = dstPort;
info.pr1 = "UDP";
info.data1 = udp.UDPData;
array.Add(info);
string[] arr = { info.index1.ToString(), info.time1.ToString(), info.len1.ToString(), info.srcIp1, info.dstIp1, info.srcPort1.ToString(), info.dstPort1.ToString(), info.pr1 };
dvinfo.Rows.Add(arr);
udpnum = udpnum + 1;
sum = sum + 1;
tbxudp.Text = udpnum.ToString();
tbxsum.Text = sum.ToString();

}
}

private void show_ip(Packet packet)//解析并显示统计IP包
{

if (dvinfo.InvokeRequired)
{
ControlDelegate cd = new ControlDelegate(show_ip);
this.Invoke(cd, new object[] { packet });
}
else
{
DateTime time = packet.PcapHeader.Date;
int len = packet.PcapHeader.PacketLength;
IPPacket ip = (IPPacket)packet;
int version = ip.Version;
int ipheadlength = ip.IpHeaderLength;
int sevicetype = ip.TypeOfService;
int totallength = ip.IPTotalLength;
int flag = ip.FragmentOffset;
int fragflag = ip.FragmentFlags;
int livetime = ip.TimeToLive;
int protocol = ip.IPProtocol;
int checksum = ip.IPChecksum;
string srcIp = ip.SourceAddress;
string dstIp = ip.DestinationAddress;
string srchwaddress = ip.SourceHwAddress;
string dsthwaddress = ip.DestinationHwAddress;
Info info=new Info();
info.index1 = index++;
info.time1 = time;
info.len1 = len;
info.version1 = version;
info.ipheaderlength1 = ipheadlength;
info.sevicetype1 = sevicetype;
info.totallength1 = totallength;
info.flag1 = flag;
info.fragflag1 = fragflag;
info.livetime1 = livetime;
info.protocol1 = protocol;
info.checksum1 = checksum;
info.srcIp1 = srcIp;
info.dstIp1 = dstIp;
info.srchwaddress1 = srchwaddress;
info.dsthwaddress1 = dsthwaddress;
info.pr1 = "IP";
info.data1 = ip.IPData;
array.Add(info);
string[] arr = { info.index1.ToString(), info.time1.ToString(), info.len1.ToString(), info.srcIp1, info.dstIp1, info.srcPort1.ToString(), info.dstPort1.ToString(), info.pr1 };
dvinfo.Rows.Add(arr);
ipnum = ipnum + 1;
sum = sum + 1;
tbxip.Text = ipnum.ToString();
tbxsum.Text = sum.ToString();

}
}

private void show_icmp(Packet packet)//解析并显示统计ICMP包
{

if (dvinfo.InvokeRequired)
{
ControlDelegate cd = new ControlDelegate(show_icmp);
this.Invoke(cd, new object[] { packet });
}
else
{
DateTime time = packet.PcapHeader.Date;
int len = packet.PcapHeader.PacketLength;
ICMPPacket icmp = (ICMPPacket)packet;
int sevice = icmp.TypeOfService;
int checksum = icmp.ICMPChecksum;
int code = icmp.MessageCode;
string srcIp = icmp.SourceAddress;
string dstIp = icmp.DestinationAddress;
string srchwaddress = icmp.SourceHwAddress;
string dsthwaddress = icmp.DestinationHwAddress;
Info info = new Info();
info.index1 = index++;
info.time1 = time;
info.len1 = len;
info.sevicetype1 = sevice;
info.checksum1 = checksum;
info.code1 = code;
info.srcIp1 = srcIp;
info.dstIp1 = dstIp;
info.srchwaddress1 = srchwaddress;
info.dsthwaddress1 = dsthwaddress;
info.pr1 = "ICMP";
info.data1 = icmp.ICMPData;
array.Add(info);
string[] arr = { info.index1.ToString(), info.time1.ToString(), info.len1.ToString(), info.srcIp1, info.dstIp1, info.srcPort1.ToString(), info.dstPort1.ToString(), info.pr1 };
dvinfo.Rows.Add(arr);
icmpnum = icmpnum + 1;
sum = sum + 1;
tbxicmp.Text = icmpnum.ToString();
tbxsum.Text = sum.ToString();
}
}

void device_PcapOnPacketArrival(object sender, Packet packet)//抓包
{

if (packet is ARPPacket)
{
show_arp(packet);
}
if (packet is TCPPacket)
{
show_tcp(packet);
}
if (packet is IPPacket)
{
show_ip(packet);
}
if (packet is UDPPacket)
{
show_udp(packet);
}
if (packet is ICMPPacket)
{
show_icmp(packet);
}
}

private static void device_PcapOnPacketArrivalfile(object sender, Packet packet)//抓包存入文件
{
PcapDevice device = (PcapDevice)sender;
//if device has a dump file opened
if( device.PcapDumpOpened )
{
//dump the packet to the file
device.PcapDump( packet );
Console.WriteLine("Packet dumped to file.");
}
}

private void btnstop_Click(object sender, EventArgs e)//停止按钮响应事件
{
device.PcapOnPacketArrival -= device_PcapOnPacketArrival;
device1.PcapOnPacketArrival -= device_PcapOnPacketArrivalfile;
btnstart.Enabled = true;
btnstop.Enabled = false;

}

private void btnsave_Click(object sender, EventArgs e)//保存按钮响应事件
{
SaveFileDialog sfile = new SaveFileDialog();
if (sfile.ShowDialog() == DialogResult.OK)
{
string fileName = sfile.FileName;
File.Copy("test.pcap", (fileName+".pcap"));
}
}

private void btnread_Click(object sender, EventArgs e)//读取按钮响应事件
{
OpenFileDialog ofile = new OpenFileDialog();
if (ofile.ShowDialog() == DialogResult.OK)
{
PcapDevice device2 = SharpPcap.GetPcapOfflineDevice(ofile.FileName);
int readTimeoutMilliseconds = 1000;
device2.PcapOpen(true, readTimeoutMilliseconds);
device2.PcapOnPacketArrival += device_PcapOnPacketArrival;
device2.PcapStartCapture();
}
}

private void sniffer_Load(object sender, EventArgs e)//窗体加载后初始化
{
getnetcard();
flitershow();
}

void getnetcard()  //获取网卡列表并显示
{
devices = SharpPcap.GetAllDevices();
// If no devices were found print an error
if (devices.Count < 1)
{
MessageBox.Show("No devices were found on this machine");
return;
}
// Print out the available network devices
foreach (PcapDevice dev in devices)
cmb_netcard.Items.Add(dev.PcapName.ToString());
//cmb_netcard.Items.Add(dev.PcapDescription.ToString());

}

void flitershow() //显示过滤规则
{
cmb_fliter.Items.Add("不过滤");
cmb_fliter.Items.Add("tcp");
cmb_fliter.Items.Add("udp");
cmb_fliter.Items.Add("ip");
cmb_fliter.Items.Add("icmp");
cmb_fliter.Items.Add("arp");
}

private void sniffer_FormClosed(object sender, FormClosedEventArgs e)//窗口关闭响应事件
{
Application.Exit();
}

private void dvinfo_SelectionChanged(object sender, EventArgs e)//选中行改变触发事件
{
tvinfo.Nodes.Clear();
rtbinfo.Text = "";
rtxinfo2.Text = "";
List<char> ch=new List<char>();
List<string>str=new List<string>();
for (int a = 0; a < array[dvinfo.CurrentRow.Index].data1.Length;a++ )
{
int ints = array[dvinfo.CurrentRow.Index].data1[a];
char ch1;
if (ints < 128&&ints>0)
ch1 = (char)ints;
else
ch1='.';
ch.Add(ch1);
String strA = array[dvinfo.CurrentRow.Index].data1[a].ToString("x2");
str.Add(strA);
}
for (int a = 0; a < array[dvinfo.CurrentRow.Index].data1.Length; a++)
{
if (((a+1) % 10) == 0)
{
rtbinfo.Text += (str[a] + "  " + "\n");
rtxinfo2.Text += (ch[a].ToString() + "\n");
}
else
{
rtbinfo.Text += (str[a] + "  " );
rtxinfo2.Text += (ch[a].ToString());
}

}
TreeNode trnode = tvinfo.Nodes.Add("捕获到的第"+(dvinfo.CurrentRow.Index+1).ToString()+"个包");
TreeNode ctrnode = trnode.Nodes.Add("协议:  "+dvinfo.CurrentRow.Cells[7].Value.ToString());
string sflag = dvinfo.CurrentRow.Cells[7].Value.ToString();
switch (sflag)
{
case  "ARP" :
ctrnode.Nodes.Add("硬件类型:" +array[dvinfo.CurrentRow.Index].hwtype1.ToString());
ctrnode.Nodes.Add("协议类型:" +array[dvinfo.CurrentRow.Index].protocoltype1.ToString());
ctrnode.Nodes.Add("硬件地址长度:" + array[dvinfo.CurrentRow.Index].hwaddresslength1.ToString());
ctrnode.Nodes.Add("操作码:" + array[dvinfo.CurrentRow.Index].operation1.ToString());
ctrnode.Nodes.Add("源MAC地址:" + array[dvinfo.CurrentRow.Index].srchwaddress1.ToString());
ctrnode.Nodes.Add("目的MAC地址:" + array[dvinfo.CurrentRow.Index].dsthwaddress1.ToString());
ctrnode.Nodes.Add("源IP地址:" + array[dvinfo.CurrentRow.Index].srcIp1.ToString());
ctrnode.Nodes.Add("目的IP地址:" + array[dvinfo.CurrentRow.Index].dstIp1.ToString());
break;
case "IP" :
ctrnode.Nodes.Add("版本:" + array[dvinfo.CurrentRow.Index].version1.ToString());
ctrnode.Nodes.Add("IP头长:" + array[dvinfo.CurrentRow.Index].ipheaderlength1.ToString());
ctrnode.Nodes.Add("服务类型:" + array[dvinfo.CurrentRow.Index].sevicetype1.ToString());
ctrnode.Nodes.Add("总长度:" + array[dvinfo.CurrentRow.Index].totallength1.ToString());
ctrnode.Nodes.Add("标识:" + array[dvinfo.CurrentRow.Index].flag1.ToString());
ctrnode.Nodes.Add("段偏移:" + array[dvinfo.CurrentRow.Index].fragflag1.ToString());
ctrnode.Nodes.Add("生存期:" + array[dvinfo.CurrentRow.Index].livetime1.ToString());
ctrnode.Nodes.Add("协议:" + array[dvinfo.CurrentRow.Index].protocol1.ToString());
ctrnode.Nodes.Add("头部校验和:" + array[dvinfo.CurrentRow.Index].checksum1.ToString());
ctrnode.Nodes.Add("源MAC地址:" + array[dvinfo.CurrentRow.Index].srchwaddress1.ToString());
ctrnode.Nodes.Add("目的MAC地址:" + array[dvinfo.CurrentRow.Index].dsthwaddress1.ToString());
ctrnode.Nodes.Add("源IP地址:" + array[dvinfo.CurrentRow.Index].srcIp1.ToString());
ctrnode.Nodes.Add("目的IP地址:" + array[dvinfo.CurrentRow.Index].dstIp1.ToString());
break;
case "ICMP":
ctrnode.Nodes.Add("类型:" + array[dvinfo.CurrentRow.Index].sevicetype1.ToString());
ctrnode.Nodes.Add("代码:" + array[dvinfo.CurrentRow.Index].code1.ToString());
ctrnode.Nodes.Add("校验和:" + array[dvinfo.CurrentRow.Index].checksum1.ToString());
ctrnode.Nodes.Add("源MAC地址:" + array[dvinfo.CurrentRow.Index].srchwaddress1.ToString());
ctrnode.Nodes.Add("目的MAC地址:" + array[dvinfo.CurrentRow.Index].dsthwaddress1.ToString());
ctrnode.Nodes.Add("源IP地址:" + array[dvinfo.CurrentRow.Index].srcIp1.ToString());
ctrnode.Nodes.Add("目的IP地址:" + array[dvinfo.CurrentRow.Index].dstIp1.ToString());
break;
case "TCP":
ctrnode.Nodes.Add("校验和:" + array[dvinfo.CurrentRow.Index].checksum1.ToString());
ctrnode.Nodes.Add("序列号:" + array[dvinfo.CurrentRow.Index].sequencenum1.ToString());
ctrnode.Nodes.Add("源端口:" + array[dvinfo.CurrentRow.Index].srcPort1.ToString());
ctrnode.Nodes.Add("目的端口:" + array[dvinfo.CurrentRow.Index].dstPort1.ToString());
ctrnode.Nodes.Add("源MAC地址:" + array[dvinfo.CurrentRow.Index].srchwaddress1.ToString());
ctrnode.Nodes.Add("目的MAC地址:" + array[dvinfo.CurrentRow.Index].dsthwaddress1.ToString());
ctrnode.Nodes.Add("源IP地址:" + array[dvinfo.CurrentRow.Index].srcIp1.ToString());
ctrnode.Nodes.Add("目的IP地址:" + array[dvinfo.CurrentRow.Index].dstIp1.ToString());
break;
case "UDP":
ctrnode.Nodes.Add("校验和:" + array[dvinfo.CurrentRow.Index].checksum1.ToString());
ctrnode.Nodes.Add("源端口:" + array[dvinfo.CurrentRow.Index].srcPort1.ToString());
ctrnode.Nodes.Add("目的端口:" + array[dvinfo.CurrentRow.Index].dstPort1.ToString());
ctrnode.Nodes.Add("源MAC地址:" + array[dvinfo.CurrentRow.Index].srchwaddress1.ToString());
ctrnode.Nodes.Add("目的MAC地址:" + array[dvinfo.CurrentRow.Index].dsthwaddress1.ToString());
ctrnode.Nodes.Add("源IP地址:" + array[dvinfo.CurrentRow.Index].srcIp1.ToString());
ctrnode.Nodes.Add("目的IP地址:" + array[dvinfo.CurrentRow.Index].dstIp1.ToString());
break;
default :
break;

}
}

}
}
完整项目代码下载:

点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: