一、說明
1.1 背景說明
以前學網絡用的謝希仁的《計算機網絡原理》,一是網開始學不太懂網絡二是ARP協議是沒有數據包格式的(如果沒記錯應該是沒有)。學完只記得老師說:ARP很簡單的,就是一個問誰有x.x.x.x這個地址告訴y.y.y.y,一個答x.x.x.x在z:z:z:z:z:z。自己就一直在想這怎么簡單法嘛,數據包到底長什么樣嘛,把"Who has x.x.x.x? Tell y.y.y.y"用ASCII編碼發出去嗎。當時Wireshark也不會就不了了之了,所以其實就數據包來說我一直也不懂ARP長什么樣,昨天分析了一天產品用到的各種協議,今天突然想到似乎需要看一下ARP長什么樣了。
如果對wireshark不太熟悉,可參考"wireshark捕獲/顯示過濾器表達式書寫規律說明 "。
1.2 ARP說明
網絡傳輸我們一般說是通過IP地址傳輸的,但更專業的說法應該是MAC地址實現同子網主機的通信、在此基礎上IP地址實現遠程主機到遠程主機的通信、在此基礎上端口實現進程到進程之前的通信。換言之一個數據包必要必先要有Eth頭,然后才是IP頭、TCP頭,單純只有IP+端口是無法完成網絡通信的。Eth最重要的就是MAC地址,而MAC地址的獲取或者叫學習就是使用ARP協議。
ARP是一種同子網內以IP地址找MAC地址的協議。(另外有一種叫RARP的協議,是一種同子網內通過MAC地址找IP的協議,但MAC地址怎么知道是不是同子網?不太懂)
我們這里一直強調“同子網”這個定語,因為不同子網內的地址一是你學不到(終端主機不會向不同子網發送ARP方播包)二是不同子網的MAC地下學來沒有意義(MAC地址要且只要能且只能完成同子網內的通信,這也是終端主機不會向不同子網發送ARP方播包的原因)。
我們現在考濾這樣一個場景:x.x.x.x要向y.y.y.y的http服務發起訪問,ip地址和端口都是很明確的所以ip頭和tcp頭構造沒有問題,那如何獲取Mac地址構造Eth頭呢?整個流程是這樣:x.x.x.x主機先看y.y.y.y是否是同子網ip,不同子網則查找本地MAC地址表中是否有網關ip對應的MAC地址,有則直接使用沒有則對網關ip發起ARP;同子網則查找本地MAC地址表中是否有y.y.y.y對應的MAC地址,有則直接使用沒有則對y.y.y.y發起ARP。ARP查看本地MAC地址表中是否有給定的ip對應的mac地址,有則向該MAC地址發送ARP查詢包,沒有則向ff:ff:ff:ff:ff:ff廣播ARP查詢包。
可能有人會覺查在上面的描述中有個問題:主機分明是在mac地址表中找不到ip對應mac地址后發起的ARP,為什么ARP還要自己再去查詢mac地址表中是否有ip對應mac地址,這不是多此一舉嗎?這是因為MAC地址表除了建立之外還有維護的工作,即針對MAC地址表中已有條目ARP每隔一段時間(幾秒?)就會針對每個條目發送一個ARP查詢包確認該條目是否還是正確的。因為ARP身兼維護工作,所以他就不只是做為通信時刻的一個附屬而是一個獨立的程序;而從重用性角度建立和維護應該是使統一的代碼,所以ARP自己要去確認MAC地址表中是否有ip對應的mac地址。
主機關機、更換IP、更換網卡這些都是常有的事,所以維護是必要的。當然你可以說不管建立和維護我都直接發廣播包不就完事了?從道理上是可以的,但是廣播包是很消耗帶寬的,而主機沒有關機、沒有更換IP、沒有更換網卡是概率更大的事,向原來MAC地址發送ARP查詢包是命中率很高的事(對於交換機要向每個端口都發送一份而對每個終端主機都要接收一個數據包),這樣能節省的資源還是可觀的。
1.3 MAC地址表
MAC地址表就是一個“IP地址-MAC地址”的對照表,但我們一直說沒看到長什么樣總是讓人覺得水夠直觀。其實很簡單打開命令行使用arp -a進行查看即可。
arp -a
二、ARP協議數據包
2.1 數據包格式
ARP數據包當然不會真把"Who has x.x.x.x? Tell y.y.y.y"之類的人類語句經ASCII編碼而成,凡協議就是由各字段組成的結構(struct),各字段的含義是收發兩端協定好的不會加上文字描述其用途。
ARP只有三類數據包但他們共用一個數據包格式:指向性查詢包,廣播性查詢包和響應包。指向性查詢包與方播性查詢包的區別是指向性查詢包Target hardware address(THA)字段是原來記錄的Mac地址,而廣播性查詢包是00:00:00:00:00:00;查詢包與響應包的區別是查詢包Operation字段值為1響應包中Operation字段值為2。
前面我們說有ARP指向應查詢包和ARP廣播查詢包但這兩者的區別在Eth頭的dst mac上和ARP頭無關;另外還要注意不管是指向應查詢還是廣播查詢,響應包都是指向性的而不是廣播的(所以使用wireshark你可以截獲各個地址發出的廣播查詢包但只能截獲自己地址的響應包)。
列坐格是相對頭部的偏移量(單位字節),橫坐標表示兩個字節長度。next 2 bytes等表示該區域同屬上一字段。
Hardware type(HTYPE)----網卡類型,以太網(Ethernet)是1。我們常見的網絡都是以太網,但這並不意味着只有以太網。
Protocol type(PTYPE)----查詢中提供的網絡地址的類型,IPv4是0x0800。
Harware lenght(HLEN)----網卡地址長度,以太網網卡是6字節。
Protocol lengt(PLEN)----查詢中提供的網絡地址的的長度,IPv4是4字節。
Operation----查詢包值為1,響應包值為2。
Sender hardware address(SHA)----發送者的Mac地址。
Sender protocol address(SPA)----發送者的IP地址。
Target hardware address(THA)----接收者的Mac地址,指向性查詢包是MAC地址表中記錄的mac,廣播性查詢包是00:00:00:00:00:00。(注意區分ARP頭和Eth頭,指向性查詢包Eth頭的dst mac是MAC地址表中記錄的mac,而廣播性查詢包是ff:ff:ff:ff:ff:ff)。
Target protocol address(TPA)----要查詢mac地址的ip。
2.2 數據包示例
注意arp是數據鏈路層協議還不是網絡層協議,即沒有ip頭所以不能用ip頭過濾而只能用eth頭過濾;可使用ipconfig /all查看自己網卡mac地址。
指向性查詢數據包:
廣播性查詢數據包:
響應數據包:
三、ARP攻擊
3.1 arp攻擊原理
第一步,arp攻擊程序先向待攻擊目標IP發出廣播性查詢數據包,獲取其mac地址。
第二步,arp攻擊程序向待攻擊目標IP發送響應數據包,告訴該主機攻擊程序欲偽造的IP對應的mac地址是攻擊程序主機的mac地址。
經以上兩步會造成以下影響:
該存活主機本應發往受偽造主機的數據包會發往攻擊程序所在主機;特別地,當受偽造主機是網關那所有原本發往網關的數據都會被發送。造成信息泄漏,這也是最常說的arp攻擊。
如果攻擊程序不回應數據包,那就進一步造成該存活主機網絡通信異常。
如果攻擊程序回復針對性構造的數據包,那可造成中間人攻擊。
3.2 ARP攻擊示例
光說不練假把式,我們直接上一下最簡單的ARP欺騙的代碼:
from scapy.all import * # 要欺騙的機器的IP fake_taget = "10.10.6.94" # 要偽造的機器IP faked_ip = "10.10.6.95" # 要偽造的機器的MAC faked_mac = "11:22:33:44:55:66" # 總的意思就是:不斷告訴pdst,psrc的mac地址是hwsrc srloop(ARP(psrc=faked_ip,hwsrc=faked_mac,pdst=fake_taget,op=2))
原先94的arp記錄如下:
欺騙后,94的arp記錄如下,可以看到10.10.6.95的mac地址記錄已被欺騙:
20190830補充說明:
理論上來說由於此時94上的95的MAC地址不對,所以94應當是ping不通95的,但實際測試發現當使用“11:22:33:44:55:66”這種比較“假”的MAC地址時,在多次接收不到響應后會觸發ping程序的防欺騙機制ping程序會將MAC替換成一種廣播地址,95接收到廣播消息后應會回應,這樣就導致從觀察上看還是能ping通的。處理辦法就是使用形如“18:31:BF:CA:1D:34”這樣比較“真”的MAC地址。
另外,不同子網是不用記錄MAC的,所以比如你想偽造百度的MAC讓目標機器ping不通百度,那你本質上應當偽造的是網關的MAC地址。
3.2 arp防范
從《華為交換機學習指南》整理出兩條看起來比較實用的arp防范方法:
一是只從自己發送的ARP請求報文的應答報文中學習。不過因為似乎只有應答報文中的“Sender Mac address”和“Sender IP address”可以標識,所以如果這兩項也偽造那還是可以欺騙。
二是啟用send-ack方式。即當收到一個修改mac地址表的arp響應報文時,先向被修改項發送一個指向應查詢數據包如果無響應或有響應但返回結果有改變,那就允許mac地址表修改反之不予處理。
參考: