【问题标题】:Sending hand-crafted BPDU (Spanning Tree Protocol packet) with Python使用 Python 发送手工制作的 BPDU(生成树协议数据包)
【发布时间】:2015-01-18 00:05:26
【问题描述】:

我正在尝试发送手工制作的 BPDU TCN 数据包(以及其他一些属于不同协议的数据包)来测试我的网络实验室的 DoS 攻击。

我找到了this answer,但没有用。

我尝试使用原始套接字和scapy,但没有成功。

这是我使用原始套接字的代码:

from socket import *
from struct import pack
class EthFrame():
    def __init__(self, dst_addr='', src_addr='',  llc_header ='',  payload =''):
        self.dst_addr = dst_addr
        self.src_addr = src_addr
        self.llc_header = llc_header
        self.payload = payload
        self.header = pack('!s', self.dst_addr + self.src_addr + self.llc_header)  
        self.frame = pack('s',  self.header + self.payload)

    def sendFrame(self,  interface):
        s = socket(AF_PACKET,  SOCK_RAW)
        s.bind((interface, 0))
        s.send(self.frame)

p = EthFrame(b'\x01\x80\xC2\x00\x00\x00',  b'\x00'*6,  b'\x42\x42\x03',  b'\x00\x00\x00\x80')
p.sendFrame('eth0')

结果是一个格式错误的数据包,仅包含一个字节 - “00000010”。 据我在文档中读到,NIC 应该自己添加 CRC 和填充位。

这是我的scapy 代码:

import scapy.all
from scapy.all import *

netpacket = Raw('\x00\x00\x00\x80')
sendp(netpacket,  iface="eth0")

它还会发送一个格式错误的数据包,这次包含两个字节。

this pdf document 的第 5 页描述了我正在尝试准备的数据包。

我正在使用 Linux。

---- 编辑: 按照 Oliver 的建议,我正在添加链接文档中的信息。

TCN(拓扑变化通知)BPDU 数据包是第 2 层以太网(I)数据包。 BPDU 数据包的结构略有不同,具体取决于硬件供应商。在此示例中,我使用的是 CISCO 实现。

以太网标头应始终将目标地址设置为 01:80:C2:00:00:00(STP 多播地址)。

在以太网报头之后,TCN BPDU 应包括:
逻辑链路控制 - 3 个字节,始终设置为 [0x42, 0x42, 0x03]
BPDU 标头 - 4 字节,对于 TCN BPDU 始终设置为 [0x00, 0x00, 0x00, 0x80]

后跟填充(本例中 39 字节设置为 0x00)

【问题讨论】:

  • 欢迎来到 Stackoverflow。您能否将该 pdf 文档中的相关信息添加到您的问题中?这样做是为了帮助未来的用户,以便在链接失效的情况下,他们仍然能够推断出数据包的内容。

标签: python sockets networking ethernet scapy


【解决方案1】:

您忘记了数据包中的以太网长度,即源以太网地址和 LLC 之间的长度。在您的情况下,它将是 7(LLC 为 3 个字节,STP 为 4 个字节)。在您的代码中,替换:

        self.header = pack('!s', self.dst_addr + self.src_addr + self.llc_header)  
        self.frame = pack('s',  self.header + self.payload)

作者:

        self.header = self.dst_addr + self.src_addr + pack('>H', len(self.llc_header) + len(self.payload)) + self.llc_header
        self.frame = self.header + self.payload

但正如@Yoel 所建议的,您最好的选择是使用 Scapy:

>>> sendp(Dot3(dst="01:80:c2:00:00:00")/LLC()/STP(bpdutype=128))

或者,如果您想直接打造自己的 LLC 级别:

>>> sendp(Dot3(dst="01:80:c2:00:00:00")/LLC('\x42\x42\x03\x00\x00\x00\x80'))

【讨论】:

  • 感谢您的回复。 Scapy 解决方案效果很好。 Python 脚本仍然只发送 1 字节格式错误的打包文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-14
  • 1970-01-01
相关资源
最近更新 更多