jamesccupps/HVAC-Network-Scanner

GitHub: jamesccupps/HVAC-Network-Scanner

一款基于 Python 的零依赖楼宇自动化协议发现与设备指纹识别工具,解决了工控网络被动侦察与设备识别的痛点。

Stars: 1 | Forks: 0

# HVAC 网络扫描器 一个零依赖的 BACnet/IP、Modbus TCP 和 HVAC 服务发现工具,带有 tkinter 图形界面。扫描楼宇自动化网络以枚举控制器、读取实时点值,并通过厂商和型号识别设备。 ![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue) ![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux-lightgrey) ![License](https://img.shields.io/badge/license-MIT-green) ## 功能 - **BACnet/IP 发现** — 原始 UDP 的 Who-Is/I-Am,支持完整 ReadProperty(无需 BAC0 或 bacpypes) - **BACnet MSTP** — 通过 Who-Is-Router-To-Network 发现路由器,然后探测每个远程网络 - **BACnet 深度扫描** — 读取每个设备上的每个点的 objectName、presentValue、units 和 description - **Modbus TCP** — 端口 502 扫描(设备 ID FC 0x2B)、寄存器读取、线圈状态 - **25+ HVAC 服务端口** — Niagara Fox、OPC UA、KNX、LonWorks、EtherNet/IP CIP、Siemens S7、MQTT、HTTP/HTTPS 标头抓取、SSH、Telnet、FTP - **SNMP 发现** — 原始 UDP SNMPv1 sysDescr 读取 - **设备指纹识别** — 从协议响应和服务标头识别 Trane、西门子、Johnson Controls、Honeywell、施耐德、Carrier 等 20 多个厂商 - **默认凭据数据库** — 常见 BAS 控制器出厂默认登录信息 - **5 标签页界面** — 所有设备、BACnet 点、Modbus 寄存器、服务、原始 JSON - **可排序列** — 每列均支持 IP 感知和数值感知排序 - **右键上下文菜单** — 打开 Web 界面、复制 IP、复制凭据、Ping、显示详情 - **导出** — CSV(Excel 兼容)和 JSON ## 截图 image ## 快速开始 ### Windows ``` git clone https://github.com/jamesccupps/hvac-network-scanner.git cd hvac-network-scanner run_hvac_scanner.bat ``` ### Linux / macOS ``` git clone https://github.com/jamesccupps/hvac-network-scanner.git cd hvac-network-scanner pip install pymodbus # optional, for Modbus deep scan python3 hvac_scanner.py ``` ### 手册 1. 安装 [Python 3.10+](https://python.org) 2. 下载或克隆本仓库 3. 运行 `python hvac_scanner.py` 4. 输入您的 HVAC 网络 CIDR(例如 `192.168.1.0/24`) 5. 勾选所需协议并点击 **SCAN** ## 要求 | 要求 | 说明 | |------------|-------| | Python 3.10 - 3.13 | 标准 CPython | | tkinter | Windows 随 Python 内置;Linux 执行 `sudo apt install python3-tk` | | pymodbus | **可选** — 由批处理文件自动安装;仅深度 Modbus 扫描需要 | **无需 BACnet 库。** 扫描器使用原始 UDP 套接字从头实现 BACnet/IP ReadProperty。BAC0、bacpypes 和 bacpypes3 均不需要。 ## 工作原理 ### BACnet 发现流程 1. 在 UDP 端口 47808 上广播 Who-Is 数据包(BVLC → NPDU → 未确认 Who-Is) 2. 解析 I-Am 响应以提取设备实例、厂商 ID、最大 APDU 和分段支持 3. 发送 Who-Is-Router-To-Network 以发现 BACnet 路由器及其 MSTP/远程网络 4. 对每个路由器,向每个 DNET 发送定向 Who-Is 以查找 MSTP 字段控制器 5. **深度扫描**:发送 ReadProperty 请求以获取设备属性(objectName、vendorName、modelName、固件等) 6. 通过数组索引 ReadProperty 读取 objectList(索引 0 表示数量,然后 1..N) 7. 对每个对象:读取 presentValue、objectName、units、description ### 原始 BACnet ReadProperty `RawBACnetReader` 类从头构建完整的 BACnet 数据包: - BVLC 头(原始单播 NPDU) - 设置期待响应的 NPDU - 确认请求 APDU 包含 ReadProperty 服务 - 上下文标记的对象标识符和属性标识符 - 解析具有完整应用标签解码(Null、Boolean、无符号整数、有符号整数、实数、双精度、字符字符串、枚举、对象标识符)的 Complex-ACK 响应 ### 服务扫描 探测 25 多个与楼宇自动化相关的 TCP 端口,然后执行协议特定识别: - HTTP/HTTPS:抓取 Server 标头和页面标题,匹配 20 多个厂商指纹模式 - Niagara Fox:发送 Fox 握手 - Siemens S7:发送 COTP 连接请求 - EtherNet/IP:发送 CIP 列举标识 - SSH/Telnet/FTP:抓取标头 ### 设备指纹识别 交叉引用多个数据源以识别确切硬件: - BACnet 厂商 ID + 设备实例编号模式 - 最大 APDU 大小和分段支持 - MSTP 路由关系 - TCP 服务签名(Nucleus FTP、nginx、Ethernut) - HTTP 标题和服务器标头 ## 支持的厂商 指纹引擎可识别以下控制器的厂商: | 厂商 | 识别的型号 | |--------|-------------------| | Trane | Tracer SC+、Tracer SC、UC800/UC600、UC400/MP581 | | 西门子 | Desigo CC、PXC Automation Station、PXC Compact/Modular、TX-I/O | | Johnson Controls | FEC、FAC、NAE、Metasys | | Honeywell / Tridium | Niagara AX/N4、Spyder | | 施耐德电气 | EcoStruxure、SmartX | | Carrier / ALC | i-Vu、WebCTRL | | Contemporary Controls | BASRT-B 路由器 | | Cimetrics | BACstac 网关/分析器 | | +15 个其他 | KMC、Distech、Delta、Reliable、Daikin、Belimo 等 | ## 网络要求 - 扫描设备必须与 HVAC 控制器位于同一网络/VLAN 上,或具有到它们的可达路由 - BACnet/IP 使用 UDP 端口 47808 — 扫描器首先尝试绑定到此端口(某些设备将 I-Am 响应硬编码为 47808),然后回退到临时端口 - 如果另一个 BACnet 应用程序正在使用端口 47808,请先关闭它或接受临时端口模式 - 防火墙必须允许 UDP 47808(BACnet)和 TCP 502(Modbus) - 在 Windows 上如遇绑定问题,请以管理员身份运行 ## 配置 所有配置均在图形界面中完成。使用逗号分隔多个网络: ``` 192.168.1.0/24, 192.168.2.0/24, 10.10.0.0/16 ``` 单个设备扫描: ``` 192.168.1.100/32 ``` ### 扫描选项 | 选项 | 默认值 | 说明 | |--------|---------|-------------| | BACnet | ✓ | Who-Is 广播发现 | | MSTP | ✓ | 路由器 + 远程网络发现 | | Modbus | ✓ | TCP 端口 502 扫描 | | Services | ✓ | 25+ HVAC 服务端口 | | SNMP | ✓ | SNMPv1 sysDescr 探测 | | Deep | ✓ | 读取所有属性、对象列表、寄存器 | | 超时 | 5s | BACnet 超时;服务限制为 2s | ## 架构 ``` hvac_scanner.py (~2300 lines, single file) ├── RawBACnetReader — Raw UDP ReadProperty (zero dependencies) ├── BACnetScanner — Who-Is / I-Am / MSTP router discovery ├── ModbusScanner — Raw TCP Modbus scanner ├── HVACServiceScanner — TCP/HTTP service probing + banner grab ├── SNMPScanner — Raw UDP SNMP v1/v2c ├── fingerprint_device() — Multi-source device identification ├── HVACNetworkScanner — tkinter GUI (5 tabs, sorting, context menu) ├── BACNET_VENDORS — 30+ vendor ID mappings ├── BACNET_UNITS — ASHRAE 135 engineering unit enumerations ├── DEFAULT_CREDS — Known factory-default credentials └── HTTP_FINGERPRINTS — 20+ regex patterns for HTTP vendor ID ``` ## 导出格式 ### CSV - UTF-8 带 BOM 以兼容 Excel - 列:协议、IP、端口、设备/单元 ID、网络、厂商、型号、名称、点数、标头、分段、最大 APDU ### JSON - 包含所有读取属性、对象列表和寄存器值的完整设备数据 - 适用于程序化分析或导入其他工具 ## 注意事项 - 深度扫描每个设备最多限制 200 个对象以避免超时 - Trane Tracer SC/SC+ 控制器将 LonWorks 子对象展平为 BACnet 模拟输入。点名称中的竖线字符(`Discharge Air Temp|dac-1`)表示源控制器 - 来自ane VAV 的非常大的当前值(如 `9.87e35`)是 IEEE 754 哨兵值,表示未配置的自动校准点 — 不是真实读数 - 扫描器为只读模式 — 不会向任何设备写入数据 ## 贡献 欢迎提交 Pull Request。可改进的领域包括: - 额外的厂商指纹 - BACnet WriteProperty 支持(用于调试工具) - 趋势日志读取 - 计划读取/显示 - BACnet/SC(安全连接)支持 - 报警/事件订阅 ## 许可证 MIT 许可证 — 参见 [LICENSE](LICENSE)
标签:BACnet, CIP, CSV 导出, Deep Scan, EtherNet/IP, HTTP/HTTPS 横幅抓取, HVAC, I-Am, JSON 导出, KNX, LonWorks, Modbus TCP, Niagara Fox, OPC UA, Python, ReadProperty, Siemens S7, SSH, Telnet, tkinter GUI, Who-Is, Who-Is-Router-To-Network, 上下文菜单, 云存储安全, 厂商型号识别, 实时点值读取, 建筑自动化, 排序列, 数据统计, 无后门, 服务发现, 枚举控制器, 端口扫描, 网络扫描, 设备指纹, 逆向工具, 零依赖, 默认凭证数据库