之前學網絡用的謝希仁的《計算機網絡原理》,一是網開始學不太懂網絡二是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長什麼樣了。html
若是對wireshark不太熟悉,可參考"wireshark捕獲/顯示過濾器表達式書寫規律說明 "。網絡
網絡傳輸咱們通常說是經過IP地址傳輸的,但更專業的說法應該是MAC地址實現同子網主機的通訊、在此基礎上IP地址實現遠程主機到遠程主機的通訊、在此基礎上端口實現進程到進程以前的通訊。換言之一個數據包必要必先要有Eth頭,而後纔是IP頭、TCP頭,單純只有IP+端口是沒法完成網絡通訊的。Eth最重要的就是MAC地址,而MAC地址的獲取或者叫學習就是使用ARP協議。tcp
ARP是一種同子網內以IP地址找MAC地址的協議。(另外有一種叫RARP的協議,是一種同子網內經過MAC地址找IP的協議,但MAC地址怎麼知道是否是同子網?不太懂)oop
咱們這裏一直強調「同子網」這個定語,由於不一樣子網內的地址一是你學不到(終端主機不會向不一樣子網發送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查詢包是命中率很高的事(對於交換機要向每一個端口都發送一份而對每一個終端主機都要接收一個數據包),這樣能節省的資源仍是可觀的。spa
MAC地址表就是一個「IP地址-MAC地址」的對照表,但咱們一直說沒看到長什麼樣老是讓人以爲水夠直觀。其實很簡單打開命令行使用arp -a進行查看便可。.net
arp -a
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。
注意arp是數據鏈路層協議還不是網絡層協議,即沒有ip頭因此不能用ip頭過濾而只能用eth頭過濾;可以使用ipconfig /all查看本身網卡mac地址。
指向性查詢數據包:
廣播性查詢數據包:
響應數據包:
第一步,arp攻擊程序先向待攻擊目標IP發出廣播性查詢數據包,獲取其mac地址。
第二步,arp攻擊程序向待攻擊目標IP發送響應數據包,告訴該主機攻擊程序欲僞造的IP對應的mac地址是攻擊程序主機的mac地址。
經以上兩步會形成如下影響:
該存活主機本應發往受僞造主機的數據包會發往攻擊程序所在主機;特別地,當受僞造主機是網關那全部本來發往網關的數據都會被髮送。形成信息泄漏,這也是最常說的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地址。
從《華爲交換機學習指南》整理出兩條看起來比較實用的arp防範方法:
一是隻從本身發送的ARP請求報文的應答報文中學習。不過由於彷佛只有應答報文中的「Sender Mac address」和「Sender IP address」能夠標識,因此若是這兩項也僞造那仍是能夠欺騙。
二是啓用send-ack方式。即當收到一個修改mac地址表的arp響應報文時,先向被修改項發送一個指向應查詢數據包若是無響應或有響應但返回結果有改變,那就容許mac地址表修改反之不予處理。
參考: