2019 工业信息安全技能大赛-深圳站 WriteUp
组织架构
指导单位:由国家工业信息安全发展研究中心、中国网络空间安全协会竞评演练工作委员会、中国网络空间安全人才教育联盟、中国中文信息学会评测工作委员会共同指导
主办与承办:由鹏城实验室主办,其网络空间安全研究中心具体承办
技术支持:烽台科技(北京)有限公司(灯塔实验室)为大赛提供技术支持
Misc
Modbus 协议分析(Modbus 协议)

链接: https://pan.baidu.com/s/1RcC1VTPusecH9OqTvRPnPA?pwd=4wv3 提取码: 4wv3
题目:黑客通过外网进入一家工厂的控制网络,之后对工控网络中的操作员站系统进行了攻击,最终通过工控协议破坏了正常的业务。我们得到了操作员站在攻击前后的网络流量数据包,我们需要分析流量中的蛛丝马迹,找到 FLAG
首先打开流量包,数据包都是关于 Modbus/TCP 的流量,下面的流量解析
MBAP Header(报文头,共 7 字节)
Transaction ID(事务标识符,2 字节):类似序号,请求和响应的 ID 必须一致
Protocol ID(协议标识符,2 2字节):固定为
00 00,代表 Modbus 协议Length(长度,2 字节):表示后面还有多少个字节
Unit ID(单元标识符,1 字节):类似于从机地址(Slave ID)
PDU(协议数据单元):
Function Code(功能码,1 字节): 它告诉设备要做什么(读还是写)
Data(数据,可变长度):具体读写的地址、数量或者具体的数值
我们重点关注功能码字段
| 功能码 (十进制) | 功能码 (十六进制) | 功能码名称 (英文) | 作用与含义 |
|---|---|---|---|
| 1 | 0x01 | Read Coils | 读线圈状态:读取输出位的开关状态(0或1) |
| 2 | 0x02 | Read Discrete Inputs | 读离散输入状态:读取只读的输入位状态(0或1) |
| 3 | 0x03 | Read Holding Registers | 读保持寄存器:读取可读写寄存器中的二进制数据(CTF 最常用) |
| 4 | 0x04 | Read Input Registers | 读输入寄存器:读取只读寄存器中的物理测量值 |
| 5 | 0x05 | Write Single Coil | 写单个线圈:强制使能或关闭某一个输出位 |
| 6 | 0x06 | Write Single Register | 写单个寄存器:向某一个保持寄存器写入数据 |
| 7 | 0x07 | Read Exception Status | 读异常状态:快速读取设备的8个内部状态位 |
| 8 | 0x08 | Diagnostics | 诊断功能:提供一系列测试码,用于检查通信系统错误 |
| 11 | 0x0B | Get Comm Event Counter | 获取通信事件计数:从设备状态字中获取状态计数 |
| 12 | 0x0C | Get Comm Event Log | 获取通信事件日志:从设备中获取通信历史记录 |
| 15 | 0x0F | Write Multiple Coils | 写多个线圈:批量强制设置多个输出位 |
| 16 | 0x10 | Write Multiple Registers | 写多个寄存器:批量向一串寄存器写入数据(CTF 最常用) |
| 17 | 0x11 | Report Slave ID | 报告从机ID:描述设备的类型、运行状态等信息 |
| 20 | 0x14 | Read File Record | 读文件记录:读取大容量存储器中的文件型数据 |
| 21 | 0x15 | Write File Record | 写文件记录:向大容量存储器中写入文件型数据 |
| 22 | 0x16 | Mask Write Register | 屏蔽写寄存器:使用AND/OR掩码修改寄存器中的特定位 |
| 23 | 0x17 | Read/Write Multiple Registers | 读/写多个寄存器:在一个通信周期内同时进行读和写操作 |
| 24 | 0x18 | Read FIFO Queue | 读FIFO队列:读取先进先出队列中的数据 |
| 43 | 0x2B | Encapsulated Interface Transport | 封装接口传输:最常用于43/14(0x2B/0x0E)来读取设备厂商、型号等识别信息 |
WireShark 过滤语法 modbus.func_code == 16

解码拿到 flag
1 | flag{TheModbusProtocolIsFunny!} |

工业协议分析 1(TCP 协议)

链接: https://pan.baidu.com/s/1899iWcrAYhmYy9gXr8vFrQ?pwd=sdvm 提取码: sdvm
题目:工业网络中存在异常,尝试通过分析 PCAP 流量包,分析出流量数据中的异常点,并拿到 FLAG
打开流量包按长度过滤,有个 TCP 流量包长度过长,发现是传送的图片

CyberChef 直接解密拿到 flag

工业协议分析 2(UDP 协议)
链接: https://pan.baidu.com/s/1GoH9e7nUHRmUNajZtoUy-Q?pwd=xiui 提取码: xiui
题目:在进行工业企业检查评估工作中,发现了疑似感染恶意软件的上位机。现已提取出上位机通信流量,尝试分析出异常点,获取 FLAG
按照长度排行,就这几个流量包长度唯一

对 648 流量提取出字符串 666c61677b37466f4d3253746b6865507a7d 转为 ASCII 码得到 flag
1 | flag{7FoM2StkhePz} |
组态软件安全分析(工程文件取证)
链接: https://pan.baidu.com/s/1V3HSE3mPUAJppBtSW2qDrQ?pwd=evmx 提取码: evmx
题目:一些组态软件中进行会配置连接很多 PLC 设备信息。我们在 SCADA 工程中写入了 flag 字段,请获取该工程 flag
这类工控组态软件为了方便传输,其工程文件(如 .PCZ、.VDZ 等)本质上都是标准的 ZIP 压缩包
直接解压缩,提示需要输入密码不用管

使用 grep 指令找到 flag

工控蜜罐日志分析(日志分析)

链接: https://pan.baidu.com/s/1coYqNSqS5-zRn-KL48r3Vw?pwd=rjiv 提取码: rjiv
题目:工控安全分析人员在互联网上部署了工控仿真蜜罐,通过蜜罐可抓取并分析互联网上针对工业资产的扫描行为,将存在高危扫描行为的 IP 加入防火墙黑名单可有效减少工业企业对于互联网的攻击面。分析出日志中针对西门子私有通信协议扫描最多的 IP,分析该扫描组织。FLAG 为该 IP 的域名
使用 Python 脚本识别,最终的域名为 scan-42.security.ipip.net
隐信道数据安全分析(MP3 Private Bit 隐写)

链接: https://pan.baidu.com/s/1q7SA4Yl3NyS5JFtKUnjtNw?pwd=92c4 提取码: 92c4
题目:安全分析人员截获间谍发出的秘密邮件,该邮件只有一个 mp3 文件,安全人员怀疑间谍通过某种 private 的方式将信息传递出去,尝试分析该文件,获取藏在文件中的数据?
MP3 音频文件是由无数个 “音频帧” 组成的。每个帧都有一个 4 字节的帧头(Header)
在帧头的结构中,第 23 个比特位(Bit 23)被称为 Private Bit(私有位)。这个位在官方标准中没有定义具体用途,完全由用户自定义
编写脚本,首先是定义对照表
比特率:
索引 1 → 32 kbps
索引 9 → 128 kbps
采样率:
索引 0 → 44100 Hz(CD 音质)
索引 1 → 48000 Hz(常见视频音轨)
1 | BITRATE_TABLE = [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1] # 比特率 |
许多 MP3 文件在音频数据前附加了 ID3v2 标签(存储歌名、艺术家、封面等信息),我们需要识别跳过这个
结构:ID3v2 头部固定 10 字节:
第 0-2 字节:标识符 “ID3”(ASCII)
第 3-4 字节:版本号
第 5 字节:标志位
第 6-9 字节:标签总长度(不包含头部的 10 字节),采用同步安全整数编码(每个字节只使用低 7 位,最高位恒为 0)
1 | # 检查文件前 3 字节是否为 b'ID3' |
因此,要完全跳过整个 ID3v2 标签,需要移动的字节总数 = 头部 10 字节 + 标签数据 size 字节
1 | pointer = 10 + id3_size |
1 | import os |

FLAG{pr1v4t3_bi7}