BOF(Boiboite Opener Framework)是一个用于现场协议实现和设备的测试框架。它是一个 Python 3.6+ 库,提供发送、接收、创建、解析和操作受支持协议帧的方法。
该库目前为 KNXnet/IP 提供发现和扩展测试功能,这是我们的重点,但它也可以扩展到其他类型的 BMS 或工业网络协议。它还提供针对依赖 KNXnet/IP、LLDP、Profinet DCP 和 Modbus TCP 的工业网络的多播和/或端到端发现功能。
请注意,针对工业系统可能会对人员、工业运营和建筑物造成严重影响,因此必须谨慎使用 BOF。
pip install boiboite-opener-framework
https://pypi.org/project/boiboite-opener-framework/
git clone https://github.com/Orange-Cyberdefense/bof.git
使用以下命令安装依赖:
pip install -r requirements.txt
协议实现使用 Scapy 的格式。
BOF 是一个 Python 3.6+ 库,应在脚本中导入。
import bof
from bof.layers import profinet, knx
from bof.layers.knx import KnxPacket
使用 BOF 的方式有三种,具体取决于层,并非所有方式都可用:
自动:从层中直接导入或调用更高级别的函数。无需了解协议。例如,discovery 模块包含一些使用多种工业网络协议发现设备的功能。
标准:使用层构造数据包以与远程设备交互。需要了解协议的基础知识。
实验:对数据包进行操作,滥用协议(我们用它来对设备进行模糊测试)。最终用户应该已经深入研究过协议规范。
现在你可以开始使用 BOF 了!
from bof.modules.discovery import *
devices = multicast_discovery(iface="eth0", verbose=True)
from bof.layers.knx import search
devices = search()
for device in devices:
print(device)
from bof.layers.knx import *
pkt = KNXPacket(type="search request")
responses = KNXnet.multicast(pkt, (KNX_MULTICAST_ADDR, KNX_PORT))
for response, _ in responses:
print(KNXPacket(response))
from bof.layers.knx import KNXnet, KNXPacket, SID
from bof import BOFNetworkError
try:
knxnet = KNXnet().connect("192.168.1.242", 3671)
pkt = KNXPacket(type=SID.description_request,
ip_address=knxnet.source_address,
port=knxnet.source_port)
pkt.show2()
response, _ = knxnet.sr(pkt)
response.show2()
except BOFNetworkError as bne:
pass
finally:
knxnet.disconnect()
from bof.layers.knx import KNXPacket, SID
from bof.layers.raw_scapy.knx import LcEMI
pkt = KNXPacket(type=SID.description_request)
pkt.ip_address = b"\x01\x01"
pkt.port = 99999 # Yes it's too large
pkt.append(LcEMI())
pkt.show2() # This may output something strange
接收方设备可能不会对此作出响应,但至少你知道 BOF 不会阻止你随意修改数据包。
BOF 依赖 Scapy 实现协议,并在此基础上增加了一层,将 BOF 代码转换为对 Scapy 数据包和字段的更改。为什么?因为 BOF 可能会略微修改或覆盖 Scapy 的内部行为。
使用 BOF 并不需要了解如何使用 Scapy,但如果你了解,也可以直接与 Scapy 数据包进行交互。
packet = KNXPacket(type=connect_request)
packet.field1 = 1 # Applying additional BOF operations (ex: change types)
packet.scapy_pkt.field1 = 1 # Direct access to Scapy Packet object
文档链接:https://bof.readthedocs.io
HTML 用户手册和源代码文档可以从仓库构建:
$> cd docs && make html[path to repository]/docs/_build/html/index.html示例脚本位于 examples 文件夹中。
欢迎贡献者!BOF 仍是一个持续开发中的项目,依赖 Scapy 格式的工业网络协议实现。你可以先通过为 Scapy 贡献代码并添加新协议(“layers”)来参与。或者,你也可以通过将 Scapy 协议集成到 BOF 中来贡献。文档中说明了具体做法。此外,未来还需要更高级别的功能,以使测试更简单或实现对协议/协议实现的已知攻击。
以下是几点需要提前了解的事项:
我们喜欢干净的代码,并希望贡献尽可能符合 PEP-8 规范(尽管我们不会对此进行测试)。新代码应易于阅读和维护。请记住:如果在解释函数功能时需要用到“并且”,那么这个函数很可能会被拆分。
请编写单元测试,并确保现有测试仍然通过!测试位于 tests/ 目录。可以使用以下命令运行所有单元测试:python -m unittest discover -s tests
请通过 GitHub 提交 issue 来报告错误、提问或请求补充缺失的文档和新功能。对于错误,请尽可能清晰地描述你的问题。
| 自动 | 标准 | 实验 |
|---|
| KNX | X | X | X |
| LLDP | X | ||
| Modbus | X | X | X |
| Profinet DCP | X |