2020 “之江杯” 工业互联网内生安全防御国际精英挑战赛 WriteUp
主办与支持:比赛由之江实验室联合中国信通院等机构共同举办,并获得了中国工程院和浙江省人民政府的支持
赛事概况:比赛于 2020 年 12 月 20 日至 22 日举办,为期三天。共邀请了来自中、美、俄、德等 8 个国家的 40 支顶尖 “白帽黑客” 战队参赛。赛事的核心目标是攻击之江实验室研发的工业互联网拟态防御系列设备
赛制与创新:大赛设置了 CTF 竞速赛、AWD 竞技赛、人机对抗赛和巅峰挑战赛四个环节。最大亮点是首次在工业互联网安全领域引入 “白盒” 人机对抗模式,即向参赛队伍开放部分系统控制权,允许其设置后门或植入病毒,以极端方式测试系统的防御能力
比赛结果:经过 54 小时、高达 95 万次的高强度攻击,没有任何一支队伍能够成功突破由拟态防御技术构筑的防线。这一结果验证了我国独创的内生安全理论与拟态防御技术在工业互联网领域的有效性
Misc
简单 Modbus 协议分析(Modbus 协议)

502 是 Modbus/TCP 常用端口

正常看了一圈找不到明显异常,没有别的功能码
正常情况下,以太网帧长度大致应该是:
1 | Ethernet header 14 字节 + IP total length |
下面过滤语法可以筛选出存在额外字节的流量包
1 | tcp.port == 502 && frame.len > ip.len + 14 |
frame.len:整个数据帧在物理网络上的总长度(从以太网头部开始,到数据包末尾结束)ip.len:IP 数据包的总长度(仅包含 IP 头部 + TCP 头部 + 应用层数据,不包含以太网链路层头部)+ 14:标准的 以太网 II 帧头部长度(6 字节目标 MAC + 6 字节源 MAC + 2 字节类型/长度字段)

转为 ASCII 码得到 flag{DGswTfgy1GD236fs2sfF2dskLng}
工控现场的恶意扫描(Modbus 协议)

题目说 PLC 被扫描,PLC 常见协议优先看:
Modbus/TCP -> 502 端口
S7comm -> 102 端口
EtherNet/IP -> 44818 端口
这份包里最明显的是 502 端口,也就是 Modbus/TCP
可以看到有两个主机在访问 PLC

按照长度排列找到 flag
1 | ip.src == 192.168.99.32 && ip.dst == 192.168.99.31 && tcp.dstport == 502 |

注册表分析(.reg 注册表取证)

注册表文件是 UTF-16LE 的 .reg 文本,直接搜索无线网络相关字段
1 | grep -a "NetworkList" zhucebiao.reg |
关键位置在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles
可以看到两个网络配置:
1 | "ProfileName"="OPPO Reno" |
但真正的无线网络在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Nla\Wireless
里面有
1 | @="4F50504F2052656E6F" |
解码是 OPPO Reno,也就是黑客连接过的 WiFi 名称
另外还能看到对应网关 MAC
1 | DefaultGatewayMac=hex:6e,58,6e,70,69,44 |
modbus(Modbus 协议)

过滤出来按照长度排列,有三个数据包长度是 81 且含有十进制的 ASCII 码

将这三个流量包的字符提取出来拼接得到 flag{18ghT1wr3}
S7 协议恶意攻击分析(S7comm 协议)

S7comm(S7 Communication)是西门子专有的工业控制协议,主要功能码如下:
| 功能码 | 描述 | 说明 |
|---|---|---|
| 0x00 | CPU 服务 | 用于执行与 CPU 本身相关的系统级功能 |
| 0xF0 | 建立通信 | 在数据传输前,用于协商通信参数,如 PDU 大小 |
| 0x04 | 读取变量 | 请求读取 PLC 中一个或多个变量的值 |
| 0x05 | 写入变量 | 请求向 PLC 写入一个或多个变量的值 |
| 0x1A | 请求下载 | 开始下载程序块或数据块前的请求 |
| 0x1B | 下载块 | 传输程序块或数据块的实际数据内容 |
| 0x1C | 下载结束 | 通知 PLC 下载过程已全部完成 |
| 0x1D | 开始上传 | 开始从 PLC 上传程序块或数据块 |
| 0x1E | 上传 | 传输从 PLC 上传的数据内容 |
| 0x1F | 上传结束 | 通知上位机上传过程已全部完成 |
| 0x28 | PLC 控制 | 用于远程控制 PLC 的运行模式,例如启动(Start) |
| 0x29 | 停止 PLC | 远程停止 PLC 的运行 |
题目说了是 “突然发生停机事件”,所以推测是 0x29 或者 0x28,直接过滤出来
P_PROGRAM 是实现 PLC 模式转换的关键服务。它主要包含两种操作:
启动:将 PLC 从停止状态切换至运行状态
停止:将 PLC 从运行状态切换至停止状态

本题的 flag 是 flag{3201414d}
上位机通讯异常分析(S7comm 协议)

题目说 “无法查询控制设备异常情况”
观察数据包发现功能码都是 0x04,所以判断是因为响应不正常才导致的 “无法查询”

我们随便一个响应来分析一下结构

📦 1. Header (头部) — 确认响应类型
| 字段 | 值 | 说明 |
|---|---|---|
| Protocol Id | 0x32 | S7 协议固定标识,表明这是 S7comm 报文 |
| ROSCTR | Ack_Data (3) | 表示这是一个数据确认包,即对请求的响应并携带数据 |
| PDU Reference | 52417 | 用于匹配请求与响应的流水号 |
| Parameter length | 2 | 参数部分的长度为 2 字节(仅包含 “Item count”) |
| Data length | 6 | 数据部分的长度为 6 字节(包含 1 个数据项的元信息+实际值) |
| Error class / code | 0x00 / 0x00 | 无错误,表示操作成功 |
📋 2. Parameter (参数) — 确认读取内容
| 字段 | 值 | 说明 |
|---|---|---|
| Function | Read Var (0x04) | 响应的是 “读取变量” 请求 |
| Item count | 1 | 数据部分包含 1个 数据项,与请求中的项数对应 |
💾 3. Data (数据) — 实际读取到的值
| 字段 | 值 | 说明 |
|---|---|---|
| Return code | Success (0xff) | 该项读取成功 |
| Transport size | BYTE/WORD/DWORD (0x04) | 表示数据长度以字节为单位,且 “Length” 字段按字节计数 |
| Length | 2 | 数据长度为 2个字节 |
| Data | 01 00 | 实际读取到的原始值,按大端序存储 |
可以看到 Return code 的值决定是否读取成功,成功的话为 0xff
我们右键这个值,选择 “准备作为过滤器” –> “选中”

然后加上 ! 筛选出没有读取成功的流量包

其 data 内容就是 flag{010400100100}

梯形图 2(梯形图分析)

直接在博图中载入程序,启动模拟器调试即可

flag:flag{-1150.885}
S7Comm 攻击协议分析(COTP 协议)

流量包中有两个 IP,其中 192.168.1.188 的功能码全是 0x00 CPU 服务,所以可以直接排除

但是 192.168.1.33 的功能码全是 0xf0 建立连接的,它为什么要一直建立连接呢?

这题考点不是普通 S7comm 的 Read/Write Var,而是 COTP 连接请求里的 TSAP 字段
它在工业自动化(如西门子 S7 通信)和一些传统 OSI 网络中很常见,你可以把它理解成一个 “加强版”的 TCP
使用 cotp && ip.src == 192.168.1.33 过滤一下,分析第一个请求包

简单分析如下:
包类型与目的
- PDU 类型为
0x0e(CR):这是一个主动发起连接建立请求的报文,相当于 TCP 的 SYN 包
- PDU 类型为
连接标识(引用)
Source reference(源引用)为
0x002f(47):发起方生成的本地连接标识,用于唯一标记这条会话Destination reference(目标引用)为
0x0000:因为尚未建立连接,所以目标引用填0
协议等级(Class)
- Class 为
0:这是最基础的传输层等级,不支持错误恢复和复用,只提供简单可靠的传输服务。这在工业控制等确定性场景中很常见
- Class 为
关键参数(TSAP 地址)
源 TSAP(0xc1):
0x0100—— 代表发起方(如工程师站/上位机)的访问点地址目标 TSAP(0xc2):
0x0102—— 代表接收方(如 PLC)的访问点地址含义:TSAP 相当于应用层的 “门牌号” 或端口扩展。在西门子 S7 协议栈中,
0x0102常对应 PLC 的编程/HMI 通信入口,0x0100常对应 PC 端。这明确指明了双方的应用实体
传输能力协商
- TPDU size(0xc0)为 1024:表示发送方建议在这个连接上传输的数据块(TPDU)最大长度为 1024 字节。接收方若接受,后续通信将以此值(或协商后的较小值)为准
往下看发现这里连续两次发送请求

对比如下:
上一个包:目标 TSAP 是 0102
当前这个包:目标 TSAP 是 0205
符合题目描述的 “对设备进行了修改设备参数操作”

右键追踪 TCP 流拿原始数据

所以 flag 就是 flag{11e00205}
异常的工程文件(关键字搜索)

直接搜关键字即可

病毒文件恢复(勒索文件恢复)

360 解密拿到 flag

工控组态分析(力控软件)

力控软件加载就行

梯形图分析 1(博图软件)


异常的流量分析(签到)

有个流量包里是一张图片,打开拿到 flag
1 | flag{4eSyVERxvt70} |

IC 卡分析(MIFARE Classic 1K IC 卡)

两个文件只有 sector 2 的两个 Value Block 不同
1 | 文件 1 block 9: |
这题的关键是通过金额块发现 IC 卡 Value Block 的存储规律
1 | [ value ][ ~value ][ value ][ addr ][ ~addr ][ addr ][ ~addr ] |
其中金额是小端序
1 | 0x000063ce = 25550 |
金额差是 27000 - 25550 = 1450
更重要的是可以看出加密/校验规律
1 | ce 63 00 00 -> 31 9c ff ff |
也就是
1 | 后 4 字节 = 前 4 字节按位取反 |
后面有多组伪造的 Value Block,结构类似
1 | 7b 00 00 00 a6 ff ff ff 30 00 00 00 01 fe 01 fe |
每组取 3 个位置
1 | 第 1 字节:明文 |
1 | from pathlib import Path |
得到 flag{Y0u_4re_1ike_my_sister}