jamesccupps/HVAC-Network-Scanner
GitHub: jamesccupps/HVAC-Network-Scanner
一款基于 Python 的零依赖楼宇自动化协议发现与设备指纹识别工具,解决了工控网络被动侦察与设备识别的痛点。
Stars: 1 | Forks: 0
# HVAC 网络扫描器
一个零依赖的 BACnet/IP、Modbus TCP 和 HVAC 服务发现工具,带有 tkinter 图形界面。扫描楼宇自动化网络以枚举控制器、读取实时点值,并通过厂商和型号识别设备。



## 功能
- **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
## 截图
## 快速开始
### 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)
## 快速开始
### 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, 上下文菜单, 云存储安全, 厂商型号识别, 实时点值读取, 建筑自动化, 排序列, 数据统计, 无后门, 服务发现, 枚举控制器, 端口扫描, 网络扫描, 设备指纹, 逆向工具, 零依赖, 默认凭证数据库