网络攻击与防范实验报告
姓名:_ _杨刚_ _ 学号:____200948300108005 __ 所在班级: 702班
实验名称: 编写自己的网络嗅探器 实验日期:_2009_年_10_月_25_日
指导老师: 张玉清、宋杨 实验评分:
验收评语:
参与人员:
实验目的:
? 开发一个Windows平台上的网络嗅探工具
? 通过开发基于WinPcap的嗅探器,掌握嗅探器的工作原理,熟悉WinPcap的使用,掌握基于WinPcap网络嗅探器的开发过程
实验内容:
? 能列出监测主机的所有网卡。
? 能选择其中一个网卡进行监听
? 能捕获并显示流经网卡的数据包,并做相应的分析和统计
? 能设置捕获过滤规则(按协议类型、端口、地址等)
? 在TCP、UDP、ARP、ICMP、IGMP等协议中选择至少三种进行重点分析,
? 选择至少一种应用层协议如http、ftp等进行分析
? 能按照协议格式进行格式化显示。
? 有可视化操作界面,易于使用
实验环境:
Ø 硬件环境:
² 处理器:PentiumIII 800 以上
² 内存:1G
² 硬盘:40G
² 网卡:100M以上
² 网速:ISDN128K以上
Ø 软件环境:
² 操作系统:Windows XP with SP3 or Vista or Windows 7
² 开发工具:Visual Studio 20## with SP1
² 开发语言:C++
实验设计:
本实验的目标主要是利用WinPcap开发包工具,独立开发出一个网络嗅探器。因此可以首先根据WinPcap开发包提供的网络接口获取到底层的网卡信息及其数据包;然后再根据TCP/IP协议栈的结构,依次在数据链路层、网络层、数据传输层和应用层,分别进行数据包的分拆与解析,获取相应协议层的数据信息;再次经过几个最常用的协议,如针对Mac、ARP、IP、TCP、UDP、ICMP、HTTP等协议,进行测试;最后,对程序的结构框架、界面设计等不断地进行修正、改进,使自己开发的作品日臻完善。
详细过程(本文所有程序源码,均摘自于本人源程序):
Ø 利用WinPcap开发包工具
² 获取本机所有网卡列表信息
pcap_if_t * MyWinPcap::GetAdapterList(void )
{
/* Retrieve the device list from the local machine */
char errbuf[PCAP_ERRBUF_SIZE];
pcap_if_t * m_alldevs = new pcap_if_t(); // ?????? allocate memory to sava temp all-devs ?????
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL /* auth is not needed */, &m_alldevs, errbuf) == -1) // if error
{
CString errmsg;
USES_CONVERSION;
errmsg.Format(TEXT("Error in cap_finalldevs_ex(): %s\n"),A2W(errbuf));
AfxMessageBox(errmsg);
return NULL;
}
else if(NULL == m_alldevs)
{
AfxMessageBox(TEXT("No interfaces found! Make sure WinPcap is installed..."));
return NULL;
}
else
return m_alldevs;
}
² 打开选中的网卡,获取数据包信息
pcap_if_t* CYGSnifferDlg::GetSelectedAdapter(int iSelectAdapterNo,int iTotalAdapter)
{
int i;
pcap_if_t* tmpAllDevs = tmpMyWinPcap.GetAdapterList();
pcap_if_t* pSeletedAdapter = new pcap_if_t;
pSeletedAdapter = NULL;
/* Jump to the selected adapter */
for(pSeletedAdapter = tmpAllDevs,i = 0;i < iSelectAdapterNo;pSeletedAdapter = pSeletedAdapter->next,i++); //********* turn to next piont *********
return pSeletedAdapter;
if(pSeletedAdapter)
{
delete pSeletedAdapter;
pSeletedAdapter = NULL;
}
}
DWORD WINAPI Thread_GetFilterData(LPVOID param)
{
pcap_if_t* pSelectedAdapter = (pcap_if_t*)param; // Get SelectedAdapter
char errbuf[PCAP_ERRBUF_SIZE];
CString errmsg;
pcap_t* adhandle;
/* Open the device */
if((adhandle = pcap_open(pSelectedAdapter->name,65536,PCAP_OPENFLAG_PROMISCUOUS,1000,NULL,errbuf)) == NULL)
{
USES_CONVERSION;
errmsg.Format(TEXT("Unable to open the adapter. %s is not supported by WinPcap"),pSelectedAdapter->name);
AfxMessageBox(errmsg);
/* At this point, we don't need any more the device list. Free it */
pcap_freealldevs(pSelectedAdapter);
return -1;
}
// filter packet data(protocol)
u_int netmask;
struct bpf_program fcode;
// get netmask
if(NULL != pSelectedAdapter->addresses)
netmask = ((struct sockaddr_in *)(pSelectedAdapter->addresses->netmask))->sin_addr.S_un.S_addr;
else
netmask = 0xffffff;
// comppile the filter
if(pcap_compile(adhandle,&fcode,packet_filter,1,netmask) < 0)
{
AfxMessageBox(TEXT("Unable to compile the packet filter. Check the syntax."));
/* Free the device list */
pcap_freealldevs(pSelectedAdapter);
return -1;
}
// set the filter
if(pcap_setfilter(adhandle,&fcode) < 0)
{
AfxMessageBox(TEXT("Error setting the filter."));
/* Free the device list */
pcap_freealldevs(pSelectedAdapter);
return -1;
}
pcap_freealldevs(pSelectedAdapter);
pcap_loop(adhandle, 0, packet_handler, NULL);
pcap_close(adhandle);
return 0;
}
² 调用WinPcap提供的回调函数
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
pcap_pkthdr *header2 = new pcap_pkthdr;
u_char *pkt_data2 = new u_char[header->len];
memcpy(header2,header,sizeof(pcap_pkthdr));
memcpy(pkt_data2,pkt_data,header->len);
//PostMessage 只是把消息放入队列,不管其他程序是否处理都返回,然后继续执行;
//而SendMessage 必须等待其他程序处理消息后才返回,继续执行
::PostMessage(hDlgHandle, M_MESSAGEWINPCAP, (WPARAM)header2, (LPARAM)pkt_data2); // == ** Post Message ** ==
}
Ø 解析TCP/IP协议栈的结构
² 各层协议的头信息声明
// i386 is little_endian.
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN (1) //BYTE ORDER
#else
#error Redefine LITTLE_ORDER
#endif
//Mac头部,总长度字节
typedef struct ethernet_header
{
u_char dstmac[6]; //目标mac地址
u_char srcmac[6]; //源mac地址
u_short eth_type; //以太网类型
}ethernet_header;
/* 4 bytes IP address */
typedef struct ip_address{
u_char byte1; //IP地址第个字段
u_char byte2; //IP地址第个字段
u_char byte3; //IP地址第个字段
u_char byte4; //IP地址第个字段
}ip_address;
//IP头部,总长度字节
typedef struct ip_header
{
#if LITTLE_ENDIAN
u_char ihl:4; //首部长度
u_char version:4;//版本
#else
u_char version:4;//版本
u_char ihl:4; //首部长度
#endif
u_char tos; //服务类型
u_short tot_len; //总长度
u_short id; //标识号
#if LITTLE_ENDIAN
u_short frag_off:13;//分片偏移
u_short flag:3; //标志
#else
u_short flag:3; //标志
u_short frag_off:13;//分片偏移
#endif
u_char ttl; //生存时间
u_char protocol; //协议
u_short chk_sum; //检验和
struct ip_address srcaddr; //源IP地址
struct ip_address dstaddr; //目的IP地址
}ip_header;
//TCP头部,总长度字节
typedef struct tcp_header
{
u_short src_port; //源端口号
u_short dst_port; //目的端口号
u_int seq_no; //序列号
u_int ack_no; //确认号
#if LITTLE_ENDIAN
u_char reserved_1:4; //保留位中的位首部长度
u_char offset:4; //tcp头部长度
u_char flag:6; //6位标志
u_char reserved_2:2; //保留位中的位
#else
u_char offset:4; //tcp头部长度
u_char reserved_1:4; //保留位中的位首部长度
u_char reserved_2:2; //保留位中的位
u_char flag:6; //6位标志
#endif
u_short wnd_size; //16位窗口大小
u_short chk_sum; //16位TCP检验和
u_short urgt_p; //16为紧急指针
}tcp_header;
//UDP头部,总长度字节
typedef struct udp_header
{
u_short src_port; //远端口号
u_short dst_port; //目的端口号
u_short uhl; //udp头部长度
u_short chk_sum; //16位udp检验和
}udp_header;
//ICMP头部,总长度字节
typedef struct icmp_header
{
u_char type; //类型
u_char code; //代码
u_short chk_sum; //16位检验和
}icmp_header;
² 解析数据链路层的Mac协议
void CYGSnifferDlg::ShowMacDetail(HTREEITEM & hItem, const u_char * pkt_data)
{
ethernet_header *mac_hdr = (ethernet_header *)pkt_data;
hItem = m_treeDetailInfo.InsertItem(TEXT("MAC LAYER"));
CString str = NULL;
TCHAR mac_dstAddr[18];
TCHAR mac_srcAddr[18];
CString mac_strType = NULL;
GetMacType(mac_strType,ntohs(mac_hdr->eth_type),false); // 16-bit == u_short == ntohs() is to swap network to host
str.Format(TEXT("Mac Type = %s"),mac_strType);
m_treeDetailInfo.InsertItem(str,hItem);
GetMacAddress(mac_srcAddr,mac_hdr->srcmac);
str.Format(TEXT("Source Mac = %s"),mac_srcAddr);
m_treeDetailInfo.InsertItem(str,hItem);
GetMacAddress(mac_dstAddr,mac_hdr->dstmac);
str.Format(TEXT("Dest Mac = %s"),mac_dstAddr);
m_treeDetailInfo.InsertItem(str,hItem);
}
² 解析网络层的IP、ARP、RARP等协议
void CYGSnifferDlg::GetMacType(CString ð_strType, u_short eth_Type, bool isFirst) //& is to pass address
{
if(isFirst)
iStatistic_TotalProtocol++;
switch(eth_Type)
{
case 0x0800:
eth_strType = TEXT("IP");
if(isFirst)
iStatistic_TotalIP++;
break;
case 0x0806:
eth_strType = TEXT("ARP");
if(isFirst)
iStatistic_TotalARP++;
break;
case 0x8035:
eth_strType = TEXT("RARP");
break;
case 0x880B:
eth_strType = TEXT("PPP");
break;
case 0x814C:
eth_strType = TEXT("SNMP");
break;
default:
eth_strType = TEXT("other");
break;
}
}
² 解析数据传输层的TCP、UDP、ICMP等协议
void CYGSnifferDlg::GetIPType(CString &ip_strIP, u_short ip_Type, bool isFirst)
{
switch(ip_Type)
{
case 1:
ip_strIP = TEXT("ICMP");
if(isFirst)
iStatistic_TotalICMP++;
break;
case 6:
ip_strIP = TEXT("TCP");
if(isFirst)
iStatistic_TotalTCP++;
break;
case 17:
ip_strIP = TEXT("UDP");
if(isFirst)
iStatistic_TotalUDP++;
break;
default:
ip_strIP = TEXT("other");
break;
}
}
² 解析应用层的HTTP协议(基于传输层的TCP协议)
bool CYGSnifferDlg::IsHTTP(const u_char *pkt_data)
{
ip_header *ip_hdr = (ip_header *)(pkt_data+14);
u_short ip_hdrLen = ip_hdr->ihl*4;
tcp_header * tcp_hdr = (tcp_header *)(pkt_data+14+ip_hdrLen);
u_short tcp_hdrLen = tcp_hdr->offset*4;
u_char *http_pkt = (u_char *)(pkt_data+14+ip_hdrLen+tcp_hdrLen);
u_short http_pktLen = ntohs(ip_hdr->tot_len) - (ip_hdrLen+tcp_hdrLen); //u_short httpLen2 = header->len - (14+ip_hdrLen+tcp_hdrLen);
CString chrTmp = NULL;
CString strTmp = NULL;
CString strHttp = NULL;
int httpPos = 0;
if(ip_hdr->protocol == 6)
{
for(int i=0;i<http_pktLen;i++) // 仅提取第一行是否含有HTTP字符串
{
chrTmp.Format(TEXT("%c"),http_pkt[i]);
strTmp += chrTmp;
if(i>2 && http_pkt[i-1]==13 && http_pkt[i]==10)
break;
}
//AfxMessageBox(strTmp);
httpPos = strTmp.Find(TEXT("HTTP"),0);
if(httpPos != -1 && httpPos != 65535) // 如果第一行含有字符串HTTP,则为HTTP协议
{
iStatistic_TotalHTTP++;
return true;
}
else
return false;
}
return false;
}
Ø 测试各个协议层的数据信息
Mac、IP、UDP、TCP、HTTP等协议及其统计信息
Mac、IP、ARP、TCP、UDP、ICMP等协议及其统计信息
Ø 修正与改进,使之日臻完善
² 运用了多线程技术,进行抓包处理,使其速度、性能得到了有效改善
例如: m_hdlThread = CreateThread(NULL,0,Thread_GetFilterData,(LPVOID)pSelectAdapter,0,&dwThread);
² 运用了消息传递技术,使其能够在主线程(即主对话框线程)与子线程(即自己新创建的抓包线程)进行通信
例如:::PostMessage(hDlgHandle, M_MESSAGEWINPCAP, (WPARAM)header2, (LPARAM)pkt_data2); // == ** Post Message ** ==
² 运用了文件的存储与读取方法,节省了内存的消耗
// Append packet
void MyWinPcap::AppendPacket(packet *pkt)
{
const pcap_pkthdr *header = pkt->header;
const u_char *data = pkt->pkt_data;
++m_iCurNo;
packet_index index;
index.no = m_iCurNo;
index.pos = m_pfileData->GetPosition();
index.len = sizeof(pcap_pkthdr) + header->len;
m_pfileIndex->SeekToEnd();
m_pfileIndex->Write(&index,sizeof(packet_index));
m_pfileData->SeekToEnd();
m_pfileData->Write(header,sizeof(pcap_pkthdr));
m_pfileData->Write(data,header->len);
m_pfileIndex->Flush(); // write from memory to disk immediatly
m_pfileData->Flush();
}
// Get packet
packet * MyWinPcap::GetPacket(int m_iNo)
{
int iPos = (m_iNo-1)*sizeof(packet_index);
packet_index pIndex;
m_pfileIndex->Seek(iPos,CFile::begin);
m_pfileIndex->Read(&pIndex,sizeof(packet_index));
m_pfileData->Seek(pIndex.pos,CFile::begin);
byte *buffer = new byte[pIndex.len];
m_pfileData->Read(buffer,pIndex.len);
packet *pkt = new packet();
pkt->header = (pcap_pkthdr *)buffer;
pkt->pkt_data = (u_char *)(buffer+sizeof(pcap_pkthdr));
return pkt;
}
² 增加了版本、作者等信息显示说明,详见请点击“版本信息”按钮
² 优化了界面布局,使其更加的紧促,但又不足之处,例如没有菜单,只有按钮,这尚需要进一步的优化界面布局
实验结论:
通过了近一个月的努力学习与实践运用,终于制作出了一个实现网络嗅探的基本功能的网络嗅探器,较为合理、圆满的完成了本实验的各项实验要求,取得了应有的实验效果。
² 能列出监测主机的所有网卡,并显示在网卡列表框中。
² 能选择其中的一个网卡进行监听,并记录器数据信息
² 能捕获并显示流经网卡的数据包,并做相应的分析和统计
² 能设置捕获过滤规则(按协议类型、端口、地址等,但是仍然不够完善,尚需改进)
² 在TCP、UDP、ARP、ICMP、IGMP等协议都能进行重点分析
² 选择了一种应用层协议如http进行分析
² 能按照协议格式进行格式化显示
² 有可视化操作界面,易于使用
实验体会:(碰到的问题、如何解决、有何体会)
通过自学,亲自动手,一点一滴的积累并实现,完成了一个具备了基本功能的网络嗅探器,受益良多。
Ø 学习了WinPcap开发工具包,对其在网络底层实现和接口运用的方面,有了更加清楚、较为深入的认识与掌握,熟练学会了如何利用WinPcap工具开发上实现网络协议编程
Ø 通过实现了一个基于WinPcap的网络嗅探器,我对网络协议栈有了更加深入的了解与认识,并懂得了基本的网络协议栈的实现与应用,对以后网络学习和网络编程,将会大有裨益。
Ø 通过自己制作网络嗅探器,我对网络嗅探器的开发流程、基本原理和应用领域,有了大体的认识与掌握,知道制作网络嗅探器的基本方法与步骤,并知道如何利用网络嗅探器应用于自己所关心的网络领域。
Ø 通过近一个月的学习、理解、实践、掌握、应用WinPcap和网络嗅探器,我对新知识、新事物的学习、实践与应用的方法与途径,有了更加深入的认识与掌握,能够较为快速的汲取新知识、运用新概念、应用于新领域,这种能力的培养,才是最重要的,也将是对我以后的学习和工作,会产生很好的引导与启发作用。
学生签名: 杨刚
日期: 2009.10.25
综合实验报告(20xx--20xx年度第二学期)名称:网络攻防系统实验题目:木马院系:计算机系班级:信息安全1001班学号:***…
网络攻防实验报告姓名学号班级实验名称实验环境攻击主机lt包括使用的操作系统及相关工具gt目标主机lt包括使用的操作系统及相关工具g…
实验报告课程计算机安全与保密实验名称网络安全攻防实验院系部计算机科学学院学号姓名报告评分专业班级实验日期报告日期教师签字一实验名称…
网络防御实验报告学专班姓学院业网络工程级1班名刘小芳号4100904012720xx年12月30日一实验题目网络防御实验二实验环境…
实验报告第1页共13页网络攻击与防范实验报告姓名杨刚学号20xx48300108005所在班级702班实验名称编写自己的网络嗅探器…
网络信息安全综合实验任务书一、目的与要求根据实验内容的要求和实验安排,要求学生在掌握网络信息安全基本知识的基础上,能够设计出相应的…
实验报告课程计算机安全与保密实验名称网络安全攻防实验院系部计算机科学学院学号姓名报告评分专业班级实验日期报告日期教师签字一实验名称…
计算机网络安全网络攻击技术与防御学号110姓名专业班级指导教师1目录1网络安全现状2网络攻击常用步骤3网络攻击工具介绍4怎样防御网…
网络攻防实训实验报告马骏20xx211869实验一使用winarpattarker攻击目标主机使用scan扫描扫描到主机攻击已经有…
常州信息职业技术学院实习报告实习目的随着网络技术的飞速发展一名优秀的网络管理员无疑是保障网络安全通畅的一个重要前提对于网络管理员来…