自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

深入理解ARP攻擊

開發(fā) 開發(fā)工具
ARP(地址解析協(xié)議)是一種把物理地址地址轉(zhuǎn)換成邏輯地址的通訊協(xié)議,它屬于TCP/IP協(xié)議棧中的數(shù)據(jù)鏈路層協(xié)議。

ARP(地址解析協(xié)議)是一種把物理地址地址轉(zhuǎn)換成邏輯地址的通訊協(xié)議,它屬于TCP/IP協(xié)議棧中的數(shù)據(jù)鏈路層協(xié)議。下圖是Wiki上的一副截圖

所以它只有兩層數(shù)據(jù)包頭——以太網(wǎng)頭、ARP頭(TCP協(xié)議有三層,以太網(wǎng)頭、IP頭、TCP頭;HTTP協(xié)議有四層,以太網(wǎng)頭、IP頭、TCP頭、HTTP頭)。

  • 以太網(wǎng)頭包括6bytes的目標(biāo)地址,6bytes的源地址,2bytes數(shù)據(jù)幀類型(對于ARP來說它是0x0806)
  • ARP頭部包括2bytes的物理地址類型(0x0001以太網(wǎng),代表MAC地址),2bytes邏輯地址類型(0x8000 IP地址);6bytes表示硬件地址長度(MAC地址為固定值6),4bytes表示邏輯地址長度(IP地址為固定值4);1bytes操作碼(1表示請求,2表示回復(fù))
  • 后面是可以變長的發(fā)送者物理地址、邏輯地址;目標(biāo)硬件地址、邏輯地址。

我一直使用物理地址、邏輯地址這兩個(gè)術(shù)語;ARP是一種地址解析協(xié)議所以它可以實(shí)現(xiàn)任何兩種地址之間的轉(zhuǎn)換。只不過我們常用的是MAC地址轉(zhuǎn)換成IP地址。

首先用tcpdump抓ARP包。(tcpdump -i en0 -xx -vvvv -n -e arp,希望你還記得這個(gè)最常用的選項(xiàng)。e選項(xiàng)表示輸出以太網(wǎng)頭部,-xx表示輸出以太網(wǎng)16進(jìn)制頭部)

  • ffff ffff ffff(6bytes),廣播地址。說明ARP是通過廣播的方式發(fā)送ARP請求的
  • 60f8 1dac 8904(6bytes),本機(jī)MAC地址。
  • 0806,表示ARP數(shù)據(jù)包
  • 0001固定值表示物理地址是MAC地址
  • 0800固定值表示邏輯地址是IP地址
  • 06表示物理地址6bytes
  • 04表示邏輯地址4bytes
  • 0001表示是ARP請求
  • 60f8 1dac 8904表示發(fā)送方物理地址,這里是發(fā)送方MAC地址
  • c0a8 1fe9 表示發(fā)送方邏輯地址,這里是發(fā)送方的IP地址(192.168.31.233)
  • 0000 0000 0000表示接收方物理地址,這里是接收方的MAC地址。全0表示廣播地址
  • c0a8 1f01表示接收方的邏輯地址,這里是想要查詢的IP地址

第二條數(shù)據(jù)包ARP回應(yīng),大家可以自行解讀。

ARP攻擊的原理

通過上面的數(shù)據(jù)包分析不難看出,ARP協(xié)議是非常天真的協(xié)議——發(fā)送ARP請求->解讀ARP回應(yīng)。PC1喊一句——誰有IP地址192.168.31.1,快點(diǎn)把MAC地址發(fā)給我;如果PC2擁有這個(gè)IP地址則回應(yīng)ARP請求。但是這只是理想情況,事實(shí)上一個(gè)沒有擁有IP地址192.168.31.1的機(jī)器也是可以發(fā)送回應(yīng)包的。如果PC1信以為真那么就會拿到錯誤的“IP地址<->MAC地址”關(guān)系。這就是ARP攻擊。

從應(yīng)用層面看機(jī)器之間通訊是基于IP地址的,但是操作系統(tǒng)在發(fā)送數(shù)據(jù)包的時(shí)候會在IP頭部加上以太網(wǎng)頭。這是由于以太網(wǎng)規(guī)范所決定的——數(shù)據(jù)包在網(wǎng)絡(luò)上傳送使用的地址都是物理地址。錯誤“IP<->MAC映射”會導(dǎo)致“數(shù)據(jù)包不可達(dá)”——通俗的說“連不上對方”。如果這個(gè)IP地址剛好是網(wǎng)關(guān),那就意味著——“斷網(wǎng)”。

實(shí)施ARP攻擊需要解決三個(gè)問題

  • 探測到ARP請求
  • 發(fā)送ARP回應(yīng)數(shù)據(jù)包
  • 請求者“應(yīng)用”我們的回應(yīng)包

探測ARP請求

以太網(wǎng)是“共享傳輸介質(zhì)”,所以任何在網(wǎng)絡(luò)上傳遞的數(shù)據(jù)包都可以被所有網(wǎng)卡探測到。為了減輕網(wǎng)卡的壓力網(wǎng)卡設(shè)計(jì)的時(shí)候會只選擇讀取和自己MAC地址匹配的數(shù)據(jù)包(以太網(wǎng)數(shù)據(jù)包頭目標(biāo)地址=自己MAC地址)所以操作系統(tǒng)是無法讀取“所有數(shù)據(jù)包”的。當(dāng)然,這個(gè)開關(guān)是可以被關(guān)閉的——這就是混雜模式。在這種模式下所有的數(shù)據(jù)包都會被網(wǎng)卡接受并且傳遞到操作系統(tǒng)的TCP/IP協(xié)議棧。

ARP請求本身就是廣播數(shù)據(jù)包所以我們打不打開"混雜模式"都可以彈出到ARP請求。我一般習(xí)慣開啟混雜模式。

實(shí)現(xiàn)網(wǎng)絡(luò)探測的庫基本上都是脫胎于libpcap(包括tcpdump),這是一個(gè)非常歷史悠久的庫,我們直接上代碼。

pcap_open_live第一個(gè)參數(shù)是網(wǎng)卡名字(比如:eth0),65545表示最大捕獲65545bytes的數(shù)據(jù)包(其實(shí)我們永遠(yuǎn)到不了這個(gè)數(shù)字,一般1460或者1500就可以了),1表示開啟混雜模式,0表示一直抓取數(shù)據(jù);errbuf錯誤消息如果函數(shù)調(diào)用失敗會把錯誤信息寫入到這個(gè)字符串中。

pcap_loop第一個(gè)參數(shù)是pcap_open_live的返回值,它是一個(gè)結(jié)構(gòu)體;第二個(gè)參數(shù)是抓取次數(shù),-1表示一直抓取;on_pcaket是一個(gè)函數(shù),每當(dāng)抓取到數(shù)據(jù)包都會調(diào)用該函數(shù)(回調(diào));最后一個(gè)參數(shù)是一個(gè)指針把共享數(shù)據(jù)傳遞到回調(diào)函數(shù)里面。

這個(gè)就是on_pcaket的原型(第一個(gè)參數(shù)是pcap_loop的最后一個(gè)參數(shù)),pkthdr表示抓取到數(shù)據(jù)包頭指針;packet是數(shù)據(jù)包。

我們可以在on_packet里面直接判斷packet是否為ARP請求

packet表示完整的數(shù)據(jù)包,所以它的開頭一定是以太網(wǎng)數(shù)據(jù)包頭。我們直接看結(jié)構(gòu)體

就是以太網(wǎng)頭的三個(gè)字段。

跳過以太網(wǎng)頭一定是ARP頭部,所以我們定義了指針arp_hdr。

發(fā)送ARP回應(yīng)數(shù)據(jù)包

socket的封裝提供了TCP和UDP兩種接口,而我們要構(gòu)造的ARP數(shù)據(jù)包不屬于這兩種所以只能通過RAW類型的socket來寫入自己構(gòu)造的數(shù)據(jù)包。我們使用libetnet來完成這個(gè)工作。

 

第一個(gè)參數(shù)告訴libnet,我們要直接構(gòu)造數(shù)據(jù)鏈路層數(shù)據(jù)包——自己填充以太網(wǎng)頭和ARP頭;第二個(gè)參數(shù)是要發(fā)送數(shù)據(jù)包的網(wǎng)卡,第三個(gè)參數(shù)是錯誤處理。

構(gòu)造一個(gè)ARPOP_REPLY類型的數(shù)據(jù)包(回應(yīng));mac_addr是自己的MAC地址;tpa是請求arp的目標(biāo)地址(對于我們來說是源地址——即便我們不是192.168.31.1也是可以填寫這個(gè)字段,系統(tǒng)不會校驗(yàn)這部分?jǐn)?shù)據(jù));后面的數(shù)據(jù)都可以通過以太網(wǎng)頭和arp頭填充。

最后加上以太網(wǎng)頭

然后就可以發(fā)送了

 

請求者“應(yīng)用”的回應(yīng)包

PC1發(fā)送ARP請求,如果被我們的程序探測到并且我們“編造”一個(gè)ARP回應(yīng)那么對于PC1來說它會收到兩次ARP回應(yīng)。一條是正確的ARP回應(yīng),一條是我們編造的ARP回應(yīng)。

對于Windows來說它會選擇最后到達(dá)的回應(yīng)應(yīng)用;對于Linux來說它會選擇第一個(gè)到達(dá)的回應(yīng)應(yīng)用。(所以一些簡單的ARP攻擊Linux是天生免疫的,此處你可以盡情吐槽一下Windows的弱智)

所以如果我們要攻擊Windows只需要sleep(1)再發(fā)送回應(yīng)就行了;對于Linux來說就比較困難了——我們很難保證自己的數(shù)據(jù)包會優(yōu)先到達(dá)。但是正所謂道高一次魔高一丈,我們不能欺騙Linux主機(jī)但是可以冒充Linux主機(jī)啊。簡單來說就是:當(dāng)網(wǎng)關(guān)發(fā)送ARP請求探測PC的時(shí)候我們可以冒充PC回應(yīng)網(wǎng)關(guān)的請求,這也會到導(dǎo)致——斷網(wǎng)。

盡情發(fā)揮吧

我只能提供一個(gè)簡單的Demo,它會回應(yīng)整個(gè)網(wǎng)絡(luò)內(nèi)所有的ARP請求(除了自己)。你可以加上一些判斷語句實(shí)現(xiàn)“精準(zhǔn)打擊”只針對某個(gè)機(jī)器(比如知道它的IP地址或者M(jìn)AC地址)。還可以發(fā)揮更多想象~~~

小心開車

ARP的防護(hù)辦法其實(shí)很簡單,以360的流量防火墻為例。它啟動的時(shí)候會首先拿到當(dāng)前網(wǎng)關(guān)的MAC地址,通過修改系統(tǒng)底層所有的ARP回應(yīng)數(shù)據(jù)包都不會被真正的應(yīng)用,這樣就實(shí)現(xiàn)了“防”(你可以用MAC+IP地址綁定的方式固定網(wǎng)關(guān),但是顯的不夠高大上)。

當(dāng)收到ARP回應(yīng)的時(shí)候360會比較自己保存的網(wǎng)關(guān)MAC地址,如果發(fā)現(xiàn)MAC地址發(fā)生了變化就認(rèn)為發(fā)現(xiàn)了ARP攻擊。最最致命的——無論你怎么偽造你都會暴漏自己的mac地址(回應(yīng)ARP的時(shí)候頭部以太網(wǎng)頭的源地址是你自己的MAC地址)這是由于網(wǎng)卡本身的限制,如果mac地址不是自己的數(shù)據(jù)包是“發(fā)不出去的”。

完整代碼

https://gist.github.com/fireflyc/796f55d54be39e629a2a1fcb2607a33b

總結(jié)

除了做壞事這種框架還可以做很多事情。它們的思路基本上都是一致的——探測數(shù)據(jù)包,通過應(yīng)用處理,返回?cái)?shù)據(jù)包。比如我們可以用DPDK(一種高性能的數(shù)據(jù)平面開發(fā)工具包,徹底無視Linux和TCP/IP協(xié)議棧)來探測數(shù)據(jù)包,通過移植TCP/IP協(xié)議到用戶空間來繞過操作系統(tǒng)(kernel bypass)。

經(jīng)過多年的努力我們已經(jīng)解決了C10k的問題,現(xiàn)在又有人提出來C10M問題?;旧虾芏嗳说挠^點(diǎn)都基于kernel空間的TCP/IP是沒有辦法做到這一點(diǎn)的(受限于打開文件數(shù)量、維護(hù)每個(gè)連接的開銷、操作系統(tǒng)處理網(wǎng)卡的方式),解決辦法正是這種——kernel bypass的思路。

已經(jīng)有人做了相關(guān)的工作比如libuinet、dpdk-ans,甚至還有人基于dpdk + dpdk-ans(用戶空間TCP/IP協(xié)議棧) 移植了nginx(dpdk-nginx)。陳碩老師有一篇《C1000k 新思路:用戶態(tài)TCP/IP 協(xié)議?!反蠹乙部梢詫W(xué)習(xí)一下。

【本文是51CTO專欄作者邢森的原創(chuàng)文章,轉(zhuǎn)載請聯(lián)系作者本人獲取授權(quán)】

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來源: 寫程序的康德
相關(guān)推薦

2009-01-15 09:52:00

2013-04-01 10:12:39

2010-06-01 15:25:27

JavaCLASSPATH

2016-12-08 15:36:59

HashMap數(shù)據(jù)結(jié)構(gòu)hash函數(shù)

2020-07-21 08:26:08

SpringSecurity過濾器

2011-04-06 10:23:46

2013-09-22 14:57:19

AtWood

2023-10-19 11:12:15

Netty代碼

2021-02-17 11:25:33

前端JavaScriptthis

2009-09-25 09:14:35

Hibernate日志

2020-09-23 10:00:26

Redis數(shù)據(jù)庫命令

2017-08-15 13:05:58

Serverless架構(gòu)開發(fā)運(yùn)維

2024-02-21 21:14:20

編程語言開發(fā)Golang

2019-06-25 10:32:19

UDP編程通信

2009-12-15 11:03:49

2013-02-22 14:35:38

2022-11-04 09:43:05

Java線程

2015-11-04 09:57:18

JavaScript原型

2021-05-13 21:27:24

ThreadLocal多線程多線程并發(fā)安全

2013-06-14 09:27:51

Express.jsJavaScript
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號