Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
modbus-scanner — 基于 C 语言并使用 libmodbus 编写的多线程 Modbus/TCP 检测扫描器。 | Kitploit
工具/GitHubGitHub/k3ystr0k3r/modbus-scanner
漏洞扫描器网络映射端口扫描SCADA/ICS安全信息收集网络安全
GitHubk3ystr0k3r/modbus-scanner

modbus-scanner

基于 C 语言并使用 libmodbus 编写的多线程 Modbus/TCP 检测扫描器。

查看仓库
52天前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Modbus 检测扫描器

一个使用 libmodbus 的多线程 C 语言扫描器,用于检测 Modbus/TCP 服务。

该扫描器不仅仅依赖 TCP 端口 502 是否开放。相反,它会建立 Modbus/TCP 连接并发送应用层 Modbus 请求。有效的 Modbus 响应被用作判断 Modbus 服务存在的主要指标。


Modbus/TCP

Modbus 是一种工业通信协议,通常被 PLC、RTU、HMI、SCADA 系统、传感器、仪表以及其他工业设备所使用。

Modbus/TCP 通过 TCP 传输 Modbus 应用协议。

标准的 Modbus/TCP 端口是:

root@kitploit:~
TCP/502

典型的通信流程如下:

root@kitploit:~
扫描器
   |
   | TCP 连接 → 502
   |
   | Modbus/TCP 请求
   v
Modbus 设备
   |
   | Modbus/TCP 响应
   v
扫描器

与连接后立即提供横幅(banner)的协议不同,Modbus/TCP 通常要求客户端先发送有效的 Modbus 请求,设备才会产生应用层响应。


检测方法

扫描器分两个阶段执行检测。

1. TCP 连接

扫描器尝试建立到以下地址的 TCP 连接:

root@kitploit:~
<目标>:502

如果无法建立连接,则该目标被视为不响应 Modbus/TCP。

然而,仅凭 TCP/502 端口开放本身并不足以作为 Modbus 存在的证据。

2. Modbus 应用层探测

连接建立后,扫描器使用 libmodbus 发送一个 Modbus 请求。

主要的探测是:

root@kitploit:~
modbus_read_input_registers(ctx, 0, 1, &reg);

这会生成一个 Modbus 功能码:

root@kitploit:~
0x04 - 读取输入寄存器

该请求要求目标从地址 0 开始返回一个输入寄存器。

如果目标返回有效的 Modbus 响应,扫描器即认为检测到该服务。


Modbus/TCP 数据包结构

一个 Modbus/TCP 数据包由以下部分组成:

root@kitploit:~
+----------------------+----------------------+
| MBAP 头              | PDU                  |
+----------------------+----------------------+

MBAP 头:
+------------------+
| 事务标识符       | 2 字节
| 协议标识符       | 2 字节
| 长度             | 2 字节
| 单元标识符       | 1 字节
+------------------+

PDU:
+------------------+
| 功能码           | 1 字节
| 数据             | N 字节
+------------------+

MBAP 头是 Modbus/TCP 特有的。


主要检测数据包

扫描器的第一个探测使用功能码 0x04。

一个代表性的请求是:

root@kitploit:~
00 01 00 00 00 06 01 04 00 00 00 01

分解如下:

root@kitploit:~
00 01        事务标识符
00 00        协议标识符
00 06        长度
01           单元标识符
04           功能码
00 00        起始地址
00 01        数量

事务标识符

root@kitploit:~
00 01

标识该事务。

该值可以变化,因为事务标识符通常由 Modbus 客户端库管理。

协议标识符

root@kitploit:~
00 00

值为 0 表示 Modbus。

长度

root@kitploit:~
00 06

指定长度字段之后跟随的字节数。

单元标识符

root@kitploit:~
01

标识目标 Modbus 单元。

功能码

root@kitploit:~
04

功能码 0x04 表示:

root@kitploit:~
读取输入寄存器

起始地址

root@kitploit:~
00 00

扫描器从寄存器地址 0 开始。

数量

root@kitploit:~
00 01

扫描器请求一个寄存器。


预期响应

对该请求的成功响应包含功能码 0x04 以及所请求的寄存器数据。

一个代表性的响应可能如下:

root@kitploit:~
00 01 00 00 00 05 01 04 02 00 00

分解如下:

root@kitploit:~
00 01        事务标识符
00 00        协议标识符
00 05        长度
01           单元标识符
04           功能码
02           字节数
00 00        寄存器值

对于检测而言,重要的是目标成功处理了 Modbus 请求并返回了有效的 Modbus 应用层响应。

实际的寄存器值取决于具体设备。


为什么仅凭端口 502 不够

仅仅检查:

root@kitploit:~
TCP/502 = 开放

并不一定能证明该服务就是 Modbus。

端口号只是约定。其他应用程序也可以监听 TCP/502,而且 Modbus 设备也可能因其配置不同而表现各异。

因此,扫描器使用:

root@kitploit:~
TCP 连通性
        +
Modbus 协议响应
        =
Modbus 检测

这使得应用层检测比简单的端口扫描更有意义。


备用检测

某些设备可能因其寄存器配置或支持的功能码而无法响应最初的 0x04 请求。

因此,如果第一次请求失败,扫描器会尝试第二次请求:

root@kitploit:~
modbus_read_bits(ctx, 0, 1, bits);

这使用功能码:

root@kitploit:~
0x01 - 读取线圈

一个代表性的请求是:

root@kitploit:~
00 02 00 00 00 06 01 01 00 00 00 01

分解如下:

root@kitploit:~
00 02        事务标识符
00 00        协议标识符
00 06        长度
01           单元标识符
01           功能码
00 00        起始地址
00 01        数量

当任一 Modbus 操作收到成功响应时,扫描器即认为检测到目标。


检测流程

root@kitploit:~
             目标 IP
                 |
                 v
          TCP 连接
             端口 502
                 |
          +------+------+
          |             |
        失败          成功
          |             |
          v             v
       忽略       功能码 0x04
                        |
                 +------+------+
                 |             |
               有效          失败
                 |             |
                 v             v
           发现 MODBUS    功能码 0x01
                               |
                        +------+------+
                        |             |
                      有效          失败
                        |             |
                        v             v
                  发现 MODBUS     未检测到

实现

扫描器使用 libmodbus 来构造和解析 Modbus/TCP 数据包,而不是手动构造协议帧。

主要操作是:

root@kitploit:~
modbus_read_input_registers(ctx, 0, 1, &reg);

如果失败:

root@kitploit:~
modbus_read_bits(ctx, 0, 1, bits);

随后关闭连接并释放 libmodbus 上下文。

这样可以将协议处理保留在 Modbus 库内部,而扫描器负责:

  • 目标枚举
  • 线程管理
  • 连接管理
  • 检测
  • 进度跟踪
  • 结果记录

超时

扫描器使用较短的连接和响应超时时间:

root@kitploit:~
#define TIMEOUT_SEC 2

这可以防止单个不可达或无响应的主机长时间阻塞工作线程。

工业网络中可能包含响应相对较慢的设备,因此超时值可能需要根据具体环境进行调整。


多线程

目标在多个工作线程之间分配。

例如:

root@kitploit:~
线程 1 → 目标 1–64
线程 2 → 目标 65–128
线程 3 → 目标 129–192
线程 4 → 目标 193–254

每个工作线程独立尝试 Modbus/TCP 检测。

这样可以同时测试多个主机,而不是逐个顺序等待每个目标。


重要的检测注意事项

阳性结果意味着目标成功响应了扫描器所理解的 Modbus 请求。

它不一定能识别:

  • 设备制造商
  • 设备型号
  • 固件版本
  • PLC 程序
  • 寄存器内容
  • 设备是否存在漏洞

这些是单独的指纹识别或评估任务。

该扫描器主要是一个 Modbus/TCP 服务检测工具。


局限性

检测方法有意保持保守。

设备可能支持 Modbus,但在以下情况下可能检测失败:

  • TCP/502 被过滤
  • 防火墙阻止了请求
  • 设备需要不同的单元 ID
  • 不支持所请求的功能码
  • 设备未暴露所请求的地址
  • 设备暂时不可用
  • 网络延迟超过配置的超时时间

因此:

root@kitploit:~
无响应 ≠ 确定不是 Modbus

这仅表示扫描器使用其尝试的探测未能获得成功响应。


构建

安装所需的依赖项并使用以下命令编译:

root@kitploit:~
make

或直接编译:

root@kitploit:~
gcc -Wall -Wextra -O2 -o modbus modbus.c -lmodbus -lpthread

运行:

root@kitploit:~
./modbus -i 192.168.1.0 -s /24 -t 10 -o results.txt

示例:

root@kitploit:~
[+] 检测到 Modbus:192.168.1.20:502
[+] 检测到 Modbus:192.168.1.42:502

[+] 已扫描:254 | 发现:2 个 Modbus
[+] 结果已保存至:results.txt

总结

该扫描器通过执行实际的协议交互来检测 Modbus/TCP 服务,而不是仅仅依赖 TCP 端口检测。

检测过程如下:

root@kitploit:~
连接到 TCP/502
        ↓
发送 Modbus 功能码 0x04
        ↓
收到有效的 Modbus 响应?
        ↓
      是 → 检测到 Modbus
        |
       否
        ↓
发送 Modbus 功能码 0x01
        ↓
收到有效的 Modbus 响应?
        ↓
      是 → 检测到 Modbus
        |
       否
        ↓
   未检测到

关键原则很简单:

检测协议本身,而不仅仅是端口。

下载工具