ARP 協(xié)議抓包解析

協(xié)議設(shè)計(jì)

場(chǎng)景

layer3 網(wǎng)絡(luò)中(網(wǎng)絡(luò)層),IP 協(xié)議中 IPv4 使用32位地址

layer2 網(wǎng)絡(luò)中(鏈路層),機(jī)器間通訊尋址是用 MAC 48位地址,ARP 協(xié)議在這一層游走。

那么當(dāng) layer3 下發(fā)一個(gè)數(shù)據(jù)包時(shí),硬件需要知道目標(biāo)設(shè)備的 MAC 地址才能確定接收方,但報(bào)文中只給了一個(gè) IP 地址,硬件設(shè)備玩不來(lái) layer3 那一套,老頭子們就整出一套 ARP 協(xié)議。

報(bào)文內(nèi)容

我們直接通過(guò) tshark 抓包后的字段信息學(xué)習(xí),更清晰易懂

有耐心的同學(xué)可以去 RFC 看看字段定義

Request

Address Resolution Protocol (request)
    Hardware type: Ethernet (1)
    Protocol type: IPv4 (0x0800)
    Hardware size: 6
    Protocol size: 4
    Opcode: request (1)
    Sender MAC address: Dell_aa:aa:aa (80:18:44:aa:aa:aa)
    Sender IP address: 10.0.2.123
    Target MAC address: 00:00:00_00:00:00 (00:00:00:00:00:00)
    Target IP address: 10.0.2.251

Fields:

  1. Protocol: 請(qǐng)求轉(zhuǎn)換的地址協(xié)議類(lèi)型,此處未 IPv4
  2. Size: 地址字段的字節(jié)數(shù)
  3. Sender: 發(fā)起方
  4. Target MAC address: all 0 broadcast
  5. Target IP address: 請(qǐng)求轉(zhuǎn)換的地址

Reply

Address Resolution Protocol (reply)
    Hardware type: Ethernet (1)
    Protocol type: IPv4 (0x0800)
    Hardware size: 6
    Protocol size: 4
    Opcode: reply (2)
    Sender MAC address: Dell_cc:cc:cc (f4:8e:38:cc:cc:cc)
    Sender IP address: 10.0.2.251
    Target MAC address: Dell_aa:aa:aa (80:18:44:aa:aa:aa)
    Target IP address: 10.0.2.123

字段含義同上,建議閱讀下方偽代碼,就基本能理解 arp 的工作原理了。

Received arp frame

If I have Hardware type (mac addr) == False: exit
If I have Protocol (IPv4) == False: exit
# 上面兩個(gè)都沒(méi)的話(huà),沒(méi)得玩
Set Merge_flag = False
    # 更新舊記錄,設(shè)置flag
    If <protocol type, sender protocol address> in arp_table:
        Update it
        Set Merge_flag = True
# 如果我是被請(qǐng)求方
If target target protocal(ip) address == mine:
    If Merge_flag == False: 
        # 新紀(jì)錄,直接添加
        arp_table.append(<protocol type, sender protocol address, sender hardware address>)
    If Opcode == Request:
        # 直接在原報(bào)文中互換字段,設(shè)置新值后發(fā)送。巧妙~
        Swap Mac and IP
        Set Sender info = mine
        Set Opcode = reply
        Send this arp

拓展信息: MAC Address Table

交換機(jī)有很多個(gè)端口,當(dāng)需要轉(zhuǎn)發(fā)幀給未知 mac 地址時(shí),會(huì) arp flood 所有的端口,這顯然是比較浪費(fèi)資源的。

因此交換機(jī)會(huì)維護(hù)一個(gè) mac address table,當(dāng)從 a 端口收到來(lái)自 h 地址的廣播幀時(shí),會(huì)將 a-h 作為一條記錄加進(jìn) mac address table。當(dāng)后續(xù)有發(fā)往 h 地址的廣播時(shí),就能直接將廣播幀轉(zhuǎn)發(fā)給 a 端口。

Arp Spoof 就是利用這一機(jī)制,不停向交換機(jī)發(fā)送虛假的 mac 地址,塞滿(mǎn)它的 table,讓它在轉(zhuǎn)發(fā)時(shí)不得不 flood 所有端口,是比較常見(jiàn)的攻擊手段。

Tshark 抓包

Case1 - 同子網(wǎng)

  • host-a: 10.0.0.123
  • gateway:
  • host-b: 10.0.0.125
  • 拓?fù)浣Y(jié)構(gòu)圖


Tips:

  1. layer2 switch 是二層交換機(jī),只有二層網(wǎng)絡(luò)功能的交換機(jī)
  2. layer3 switch 是含有部分路由功能(三層網(wǎng)絡(luò))的交換機(jī)

host-a ping host-b 捕捉 ARP 協(xié)議

# 清除 arp 緩存內(nèi)容
host-a$ sudo ip -s neigh flush all
host-b$ sudo ip -s neigh flush all
# 抓包開(kāi)始
host-a$ sudo tshark -i eno1 -f 'arp host 10.0.0.125 or icmp'
host-a$ ping 10.0.0.125 -c1

# 抓包結(jié)果
# host-a 發(fā)出 arp request,尋求 host-b mac addr
    1 0.000000000 Dell_aa:aa:aa → Broadcast    ARP 42 Who has 10.0.0.125? Tell 10.0.0.123
# host-b 響應(yīng)了
    2 0.000158010 Dell_bb:bb:bb → Dell_aa:aa:aa ARP 60 10.0.0.125 is at 80:18:44:f0:ea:38
# 開(kāi)始通訊
    3 0.000168966   10.0.0.123 → 10.0.0.125   ICMP 98 Echo (ping) request  id=0x2017, seq=1/256, ttl=64
    4 0.000328873   10.0.0.125 → 10.0.0.123   ICMP 98 Echo (ping) reply    id=0x2017, seq=1/256, ttl=64 (request in 3)
# 來(lái)自網(wǎng)絡(luò)中其他節(jié)點(diǎn)的廣播~~
    5 1.008209509 Dell_cc:cc:cc → Broadcast    ARP 60 Who has 10.0.0.4? Tell 10.0.0.251
# 很奇怪,怎么 host-b 又發(fā)了一個(gè) unicast
    6 5.150301642 Dell_bb:bb:bb → Dell_aa:aa:aa ARP 60 Who has 10.0.0.123? Tell 10.0.0.125
    7 5.150311419 Dell_aa:aa:aa → Dell_bb:bb:bb ARP 42 10.0.0.123 is at 80:18:44:aa:aa:aa

現(xiàn)象及疑問(wèn)

發(fā)現(xiàn)一個(gè)有趣的現(xiàn)象,原本設(shè)想只會(huì)抓到兩個(gè)包(request from 123 + reply from 125),但實(shí)際抓到了 4 個(gè)(125 主動(dòng)發(fā)起一次 request)。

ARP RFC 中提到,在完成 reply 后 target host 節(jié)點(diǎn)應(yīng)該是記下了 source mac 地址了,為何還發(fā)起了一次查詢(xún) 10.0.0.123 的。

猜想

有可能是以下原因:

  • ARP spoofing (我的網(wǎng)絡(luò)挺安全?。?/li>
  • Directed ARP (跨子網(wǎng),路由會(huì)向相鄰路由發(fā)起 ARP)
  • ARP 的 Refresh 行為,通過(guò)發(fā)起 Unicast Poll

簡(jiǎn)單排除:

  • 125 發(fā)起的是 Unicast ARP Request,且兩臺(tái)機(jī)器同子網(wǎng),不需要借助路由可直接訪(fǎng)問(wèn),因此可以排除交換機(jī)行為

驗(yàn)證

Linux APR:
前兩種情況都與我們的網(wǎng)絡(luò)環(huán)境不相符,所以搜了下 Linux arp(7) table cache refresh 機(jī)制。

When there is no positive feedback for an existing mapping after some
time (see the /proc interfaces below), a neighbor cache entry is
considered stale. Positive feedback can be gotten from a higher
layer; for example from a successful TCP ACK.

  • arp 將一個(gè) ip 標(biāo)記為 stale 后,會(huì)在間隔 delay_first_probe_time(5s) 后發(fā)起 Request 探針。
  • arp 會(huì)為可用 record 基于 base_reachable_time_ms(30s) 參數(shù)生成一個(gè)隨機(jī)有效時(shí)間。
# 查看第一次 probe 發(fā)起的延遲
host-b$ cat /proc/sys/net/ipv4/neigh/eno1/delay_first_probe_time 
5
# 發(fā)現(xiàn)跟我們抓包時(shí)的間隔時(shí)間很像,修改成 10 試一試
host-b# echo 10 > cat /proc/sys/net/ipv4/neigh/eno1/delay_first_probe_time
# 真的間隔變成 10s,這里就不放結(jié)果了~~信我就是了!

# 再看一下記錄的狀態(tài)轉(zhuǎn)換
# 清理兩端的 apr cache
host-a$ ping host-b -c1
host-b$ ip neigh
10.0.0.123 dev eno1 lladdr 80:18:44:f0:bb:7c DELAY

# host-b probe request 發(fā)起后
host-b$ ip neigh
10.0.0.123 dev eno1 lladdr 80:18:44:f0:bb:7c REACHABLE

# 等一段比較長(zhǎng)時(shí)間 >60s
host-b$ ip neigh
10.0.0.123 dev eno1 lladdr 80:18:44:f0:bb:7c STALE

# 這時(shí)候從 125 發(fā)起 ping (arp 表內(nèi)已存在)
host-b$ ping host-a -c1
# host-a 收到 ping,但沒(méi)有 arp request
# host-b 上的記錄變?yōu)?DELAY
host-b$ ip neigh
10.0.0.123 dev eno1 lladdr 80:18:44:f0:bb:7c DELAY

# 10s 后 probe 發(fā)起并受到 reply
host-b$ ip neigh
10.0.0.123 dev eno1 lladdr 80:18:44:f0:bb:7c REACHABLE

# 以上行為與 linux arp 文檔描述一致

總結(jié)

  1. 同子網(wǎng)通訊,發(fā)起端廣播 arp 請(qǐng)求目標(biāo)機(jī) mac 地址
  2. 等待 arp 請(qǐng)求得到回應(yīng),取得 10.0.0.125 的 mac-address
  3. 與目標(biāo)建立通訊
  4. Probe request 是 linux 下行為,非 arp 協(xié)議定義行為。

Case2 - 跨子網(wǎng)

  • host-a: 10.0.2.123 (改了下 ip 和 gateway)
  • host-b: 10.0.0.125
  • Gatway: 10.0.2.251、10.0.0.251 (同一臺(tái)三層交換機(jī))
  • 拓?fù)浣Y(jié)構(gòu)圖

Tips:

  • 跨子網(wǎng)時(shí),ping 包會(huì)發(fā)給默認(rèn)網(wǎng)關(guān),網(wǎng)關(guān)幫忙轉(zhuǎn)發(fā)
  • 改了 ip 需要調(diào)通交換機(jī)上的 vlan,該例子中兩個(gè)網(wǎng)關(guān)是同一臺(tái)物理交換機(jī)

需要做如下配置:

  1. host-a 的 ip 和 gateway 修改成 10.0.2.123 和 10.0.2.251
  2. layer2 switch 要將 host-a 所連端口的 vlan10 改成 vlan12(10.0.2.xxx 網(wǎng)段所屬vlan)
  3. layer3 switch 要允許 vlan12 的幀通過(guò) layer2 switch 所在的端口(port-channel or port)

抓包

host-a ping host-b,捕捉 ARP 協(xié)議
# 清除 arp 緩存內(nèi)容
host-a$ sudo ip -s neigh flush all
host-b$ sudo ip -s neigh flush all

# 因?yàn)闊o(wú)法在交換機(jī)上抓包,所以在兩個(gè)節(jié)點(diǎn)分別抓包
host-a$ sudo tshark -i eno1 -f 'arp host 10.0.0.125 or arp host 10.0.0.251 or arp host 10.0.2.251 or icmp'
host-b$ sudo tshark -i eno1 -f 'arp host 10.0.0.125 or arp host 10.0.0.251 or arp host 10.0.2.251 or icmp'

host-a$ ping 10.0.0.125 -c1

# host-a Dell_aa:aa:aa 抓包結(jié)果
# 1.arp 請(qǐng)求網(wǎng)關(guān) 10.0.2.251 mac 地址
# 2.網(wǎng)關(guān)回復(fù) arp
# 3.icmp 目的地址是 host-b。但其數(shù)據(jù)幀目的地其實(shí)是網(wǎng)關(guān),網(wǎng)關(guān)再轉(zhuǎn)發(fā)給 host-b
# 4.收到 icmp 回復(fù)
    1 0.000000000 Dell_aa:aa:aa → Broadcast    ARP 42 Who has 10.0.2.251? Tell 10.0.2.123
    2 0.010917102 Dell_cc:cc:cc → Dell_aa:aa:aa ARP 60 10.0.2.251 is at f4:8e:38:cc:cc:cc
    3 5.005604716   10.0.2.123 → 10.0.0.125   ICMP 98 Echo (ping) request  id=0x24a8, seq=1/256, ttl=64
    4 5.006708884   10.0.0.125 → 10.0.2.123   ICMP 98 Echo (ping) reply    id=0x24a8, seq=1/256, ttl=63 (request in 3)

# host-b Dell_bb:bb:bb 抓包結(jié)果
# 1.收到 icmp 請(qǐng)求
# 2.arp 請(qǐng)求網(wǎng)關(guān) 10.0.0.251 mac 地址
# 3.網(wǎng)關(guān)回復(fù) arp
# 4.回復(fù) icmp,數(shù)據(jù)幀是發(fā)給網(wǎng)關(guān),網(wǎng)關(guān)負(fù)責(zé)轉(zhuǎn)發(fā)
    1 0.000000000   10.0.2.123 → 10.0.0.125   ICMP 98 Echo (ping) request  id=0x24a8, seq=1/256, ttl=63
    2 0.000028673 Dell_bb:bb:bb → Broadcast    ARP 42 Who has 10.0.0.251? Tell 10.0.0.125
    3 0.000937934 Dell_cc:cc:cc → Dell_bb:bb:bb ARP 60 10.0.0.251 is at f4:8e:38:cc:cc:cc
    4 0.000948037   10.0.0.125 → 10.0.2.123   ICMP 98 Echo (ping) reply    id=0x24a8, seq=1/256, ttl=64 (request in 1)

總結(jié)

  • 跨網(wǎng)段通訊,arp 會(huì)請(qǐng)求默認(rèn)網(wǎng)關(guān) mac 地址,由網(wǎng)關(guān)負(fù)責(zé)轉(zhuǎn)發(fā)數(shù)據(jù)幀
  • layer2 數(shù)據(jù)幀和 layer3 數(shù)據(jù)包的 destination 可能是不同節(jié)點(diǎn),容易混淆
  • layer2:mac layer3:ip layer4:port,區(qū)分各層網(wǎng)絡(luò)的雙端通訊標(biāo)識(shí),能在日常調(diào)試中幫助理解網(wǎng)絡(luò)問(wèn)題
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容