物联网相关协议流量分析
字数 3834 2025-08-29 22:41:24
物联网与工控协议流量分析技术指南
一、流量分析基础工具与技巧
1.1 Wireshark使用技巧
过滤规则
- 基本过滤:针对工控流量中非TCP协议的混乱情况,可对大量出现的正常数据流进行过滤,追踪剩余数据的ID
- 正则匹配:将匹配内容拖到窗口自动生成匹配规则
- 数据导出:可提取大量数据包进行导出分析
追踪流功能
- 右键点击感兴趣的数据包,选择"追踪流"(主要针对TCP协议)
- 工控协议中使用较少
1.2 Tshark使用
主要用于提取大量二进制数据
常用指令模板:
# 去除重复行
tshark -r 1.pcapng -Y "dns" -T fields -e dns.qry.name | uniq > data.txt
1.3 关键词搜索方法
- Flag检索:常见转换包括Base64、16进制
- Strings检索:
strings | grep flag{ - Wireshark检索:直接搜索协议或关键词
- 协议检索:根据题目提示直接检索对应协议
二、工控协议详解
2.1 Modbus协议
协议类型
-
Modbus/RTU
- 格式:从机地址1B + 功能码1B + 数据字段xB + CRC值2B
- 最大长度:256B
-
Modbus/ASCII
- 使用ASCII字符表示数据
- 格式:开始标记(0x3A) + 从机地址1B + 功能码2B + 数据字段(最大252B) + LRC校验值2B + 结束标记(\r\n)
-
Modbus/TCP
- 不使用从机地址,使用UnitID
- 格式:传输标识符2B + 协议标识符2B + 长度2B + 从机ID 1B + 功能码1B + 数据字段xB
功能码汇总
| 功能码 | 描述 | 请求数据字段 | 响应数据字段 |
|---|---|---|---|
| 01 | 读线圈状态 | 起始地址(2B) 读取数量(2B) | 字节计数(1B) 线圈状态(NB) |
| 02 | 读离散输入 | 起始地址(2B) 读取数量(2B) | 字节计数(1B) 输入状态(NB) |
| 03 | 读保持寄存器 | 起始地址(2B) 读取数量(2B) | 字节计数(1B) 数据(NB) |
| 04 | 读输入寄存器 | 起始地址(2B) 读取数量(2B) | 字节计数(1B) 数据(NB) |
| 05 | 写单个线圈 | 地址(2B) 状态(2B) | 地址(2B) 状态(2B) |
| 06 | 写单个保持寄存器 | 地址(2B) 值(2B) | 地址(2B) 值(2B) |
| 15 | 写多个线圈 | 起始地址(2B) 写入数量(2B) 字节计数(1B) 线圈状态(NB) | 起始地址(2B) 写入数量(2B) |
| 16 | 写多个保持寄存器 | 起始地址(2B) 写入数量(2B) 字节计数(1B) 数据(NB) | 起始地址(2B) 写入数量(2B) |
CRC校验
- 算法:使用CRC-16-CCITT多项式(0x8005)
- 计算流程:
- 初始化CRC寄存器为0xFFFF
- 逐字节处理数据
- 对每个字节进行异或和移位操作
- 最终CRC值附加在数据帧末尾
2.2 S7comm协议
协议栈结构
| OSI层 | 协议 |
|---|---|
| 应用层 | S7 communication |
| 表示层 | S7 communication(COTP) |
| 会话层 | S7 communication(TPKT) |
| 传输层 | ISO-on-TCP (RFC 1006) |
| 网络层 | IP |
| 数据链路层 | Ethernet |
| 物理层 | Ethernet |
主要功能码
- 0xF0:建立通信
- 0x04:读取值
- 0x05:写入值
- 0x1A:请求下载
- 0x1B:下载块
- 0x1C:下载结束
- 0x1D:开始上传
- 0x1E:上传
- 0x1F:上传结束
- 0x28:程序调用服务
- 0x29:PLC停止
数据包结构
-
Header:
- 协议ID(0x32)
- PDU类型
- 参数长度
- 数据长度
- 错误类和错误代码
-
Job & Ack_Data:
- 第一个字段是function(1字节无符号整数)
- 不同function对应不同数据结构
2.3 IEC104协议
基本概述
- 电力自动化系统常用通信协议
- 基于TCP/IP
- 用于监视和控制电力系统设备
传输模式
-
平衡传输模式:
- 每个client和server都可启动消息传输
- 支持的服务类型:
- SEND/CONFIRM:发送消息并要求确认
- SEND/NO REPLY:广播消息,不等待回复
-
非平衡传输模式:
- 只有控制站(client)能启动消息传输
- 受控站(server)只能响应请求
协议帧结构
- APDU:应用协议数据单元
- APCI:应用控制帧型
- I-FORMAT:包含ASDU,携带应用层数据
- S-FORMAT:只有APCI,用于确认接收
- U-FORMAT:用于控制功能(测试帧、传输停止/开启)
- ASDU:应用服务数据单元
- 数据单元识别符(固定6B)
- 数据段(一个或多个信息对象)
- APCI:应用控制帧型
常见类型标识
-
监视方向信息:
- 1:单点信息
- 3:双点信息
- 5:步位量信息
- 7:32比特串
- 9:归一化测量值
-
控制方向信息:
- 45:单命令
- 46:双命令
- 47:步调节命令
- 48:设点命令(归一化值)
2.4 MMS协议
基本概述
- 制造报文规范(Manufacturing Message Specification)
- 用于IEC61850标准站控层和间隔层之间的通信
- 通过面向对象建模实现设备互操作
协议分类
- Initiate-RequestPDU:启动请求
- Confirmed-RequestPDU:确认请求
- Initiate-ResponsePDU:启动应答
- Confirmed-ResponsePDU:确认应答
COTP协议
- 连接包:用于S7Comm握手
- 功能包:用于数据传输,结构更简洁
三、实战案例分析
3.1 Modbus流量分析案例
案例1:异常数据查找
- 筛选Modbus协议
- 分析各功能码流量数量,找出最少的功能码(如16)
- 在对应功能码中查找flag
案例2:转速写入分析
- 筛选写操作(
modbus.func_code==6) - 查找转速超过2000(16进制0x7D0)的数据
- 分析异常写入数据包
3.2 S7comm流量分析案例
案例1:二进制数据提取
- 过滤有响应数据的流量(
(s7comm)&&(s7comm.resp.data)) - 提取二进制数据并分组
- 使用工具解密提取的数据
案例2:异常写入查找
- 筛选写入操作(
(s7comm) && (s7comm.param.func == 0x05)) - 筛选JOB包(
s7comm.header.rosctr == 1) - 排除正常数据(
!(s7comm.resp.data == 66)) - 提取异常数据
3.3 IEC104流量分析案例
案例1:破损数据处理
- 筛选协议(
iec60870_asdu) - 过滤同一TCP流(
tcp.stream == 0) - 筛选标准化值(
iec60870_asdu.normval) - 排除常见类型ID(
iec60870_asdu.typeid != 34 && iec60870_asdu.typeid != 9)
案例2:Flag直接检索
- 直接筛选iec60870_104协议
- 向下检索flag关键词
3.4 MMS流量分析案例
案例1:异常ID查找
- 过滤domainID和itemID
- 排除常见前缀(
!(mms.itemId contains "LLN0")) - 分析偏移字符提取flag
案例2:文件操作分析
- 查找文件打开操作(
mms.confirmedServiceRequest == 72) - 过滤特定文件名(
mms.FileName_item == "flag.txt") - 跟踪文件读取操作(
mms.fileRead)
3.5 GOOSE流量分析案例
案例1:异常长度分析
- 筛选GOOSE协议
- 分析不同长度数据包(如205和206)
- 提取Base编码数据解密
案例2:异常数据查找
- 筛选GOOSE协议
- 过滤特定appid(
goose.appid==8) - 查找异常Data值(如"VBfMWV")
- 提取并解密字符串
四、总结与最佳实践
4.1 分析流程建议
- 协议识别:首先确定使用的工控协议类型
- 功能码分析:了解协议的功能码含义和用途
- 异常过滤:通过排除法过滤大量正常数据
- 数据提取:使用tshark等工具提取关键数据
- 解密分析:对提取的数据进行解码和转换
4.2 常见Flag隐藏方式
- 直接明文:在协议字段中直接显示
- Base编码:Base64、Base32等编码
- 二进制数据:需要提取后解码
- 异常参数值:在正常数据流中的异常值
- 文件操作:通过文件读写操作传输flag
4.3 工具推荐
- Wireshark:基础流量分析
- Tshark:批量数据提取
- CyberChef:数据解码和转换
- Python脚本:自定义数据处理
- Hex编辑器:二进制数据分析
通过掌握这些协议特性和分析方法,可以有效识别和提取工控流量中的关键信息,解决各类工控安全挑战。