新型PLC编程软件架构演进、安全风险分析

admin 2026-08-21 05:16:26 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文章剖析国产新型PLC编程软件天行IDE的三段式架构风险,指出其默认免认证、命令拼接执行及特权容器配置导致控制平面命令注入与容器逃逸,攻击链可致宿主沦陷与生产网渗透,建议强制开启认证、禁用特权模式并重构命令调用逻辑。 综合评分: 85 文章分类: 工控安全,IoT安全,漏洞分析,安全开发,安全建设


新型 PLC 编程软件架构演进、安全风险分析

原创

ic3blac4 ic3blac4

ChaMd5安全团队

2026年8月20日 08:00 辽宁

在小说阅读器读本章

去阅读

诚招web、re、crypto、pwn、misc、合约方向的师傅,长期招新IOT+Car+工控+样本分析多个组招人有意向的师傅请联系邮箱 [email protected](带上简历和想加入的小组)

1. 前言

  工业控制系统是电力、冶金、能源等关键基础设施的神经中枢,PLC 编程软件作为工程师与控制器交互的入口,其安全性直接影响产线稳定。传统 PLC 编程软件以 Windows 原生桌面程序形态存在:编辑、编译、调试一栈化,工程文件存本地,安全边界是”操作系统用户+厂商签名组件”。这类形态功能强大,但部署笨重、生态封闭、升级困难。

  近两年,一批国产新型 PLC 编程环境开始把 Web IDE 与容器化技术引入工控领域:前端浏览器化、编译链容器化、工程数据集中管理、支持仿真多实例与设备扫描。架构现代化的同时,安全边界也发生了根本性迁移——从”操作系统用户”退化为”一个默认免认证的本地 Web 端口”。

  近期笔者对国内某厂商的新型 PLC 编程软件做了系统性分析研究,发现诸多安全漏洞并提交至国家信息安全漏洞库。本文将从该新型 IDE 的信任边界在哪里、攻击面如何分布、典型风险有多严重、风险如何传导到最终用户、应该如何防御等多个维度展开阐述。

IMG_256

2. 架构之变-三段式本地 PaaS

  天行 IDE 的形态为 Web 控制平面 + WSL 工具链 + Docker 业务容器的三段式本地 PaaS 模型:Windows 侧”控制中心”统一编排,WSL2 定制发行版承载运维脚本与 Docker Engine,IDE 主服务运行在容器内,工程数据集中在虚拟磁盘,整体架构如下图所示。

svgviewer-png-output (17)

  表现层:浏览器即客户端。与传统 IDE 的桌面 UI 不同,新型 IDE 的全部交互发生在浏览器中:工程师通过 Web 控制台完成服务启停、备份恢复等运维操作,通过 IDE Web UI 进行工程编辑与在线调试。技术载体是动态 HTML 片段与 JSON API 双轨通信——页面加载走 HTML 片段,业务操作走 JSON 接口。这一层本身不保存业务状态,纯粹是”操作入口”,但它决定了整个环境暴露给用户的最小交互面:所有能力最终都以 HTTP 形式呈现。

  控制平面:Windows 侧的”运维大脑”。这是整套架构的中枢,通常是一个嵌入式 Web 服务(Node/Express 类技术栈),按配置文件动态注册控制器与路由。它负责五类核心事务:服务生命周期管理(IDE/仿真容器的启停)、备份恢复编排、许可证管理与分发、网络与端口配置、管理员账户管理。所有控制器的操作最终汇入统一的命令执行服务,再经由系统调用落到下层。关键特征是配置驱动——新增服务只需改配置即可注册出对应 API 与 UI,迭代效率高,但也意味着配置里的每一个字段都可能成为攻击入口。这一层同时是风险密度最高的位置:默认可达(本机回环端口)+ 高权限编排(能以 root 身份操作虚拟机与容器),二者叠加使其成为整套架构的”总开关”。

  运行时层:容器承载业务核心。IDE 主服务(编辑器内核、语言服务、工程数据库)运行在业务容器内,对外提供 HTTP API;仿真容器支持多实例,各自映射独立端口与网段。容器编排文件与运维脚本存放在虚拟磁盘固定目录,业务数据通过 bind mount 挂载进容器。技术载体是 Docker Engine + 编排文件。这一层承载了工程师真正使用的业务能力,也是插件与语言服务的执行场所——而容器本身的权限配置(特权模式、敏感挂载)直接决定了”容器内命令执行”能放大到多大的影响范围。其内部的数据层为虚拟磁盘集中管理。工程树、用户库、设备描述、插件副本等全部业务数据集中存放于虚拟磁盘的数据目录,经挂载供容器读写。这与传统 IDE”工程文件散落本地磁盘”形成鲜明对比:数据集中带来备份恢复与工程协作的便利,但也意味着攻击者只要控制环境,即可一次性获取全部工程资产,无需逐目录搜寻。同时,数据层经宿主机文件系统挂载,天然打通了”虚拟机数据”与”宿主磁盘”的边界。

  综上,各个层级从”交互入口”到”数据资产”层层递进:表现层提供入口,控制平面掌握编排,工具链执行业务,容器承载运行,数据层沉淀资产。后续章节的暴露面分析正是沿着这条纵向链条展开的——风险不一定只出现在某一层,而是可以在层与层之间传导放大。

  与传统的 PLC 编程软件做对比,这种架构差异体现在多个维度上,如下表所示。

| | | | | — | — | — | | 维度 | 传统PLC编程软件 | 天行IDE | | 运行形态 | Windows 原生桌面程序 | Web 控制台 + 容器运行时 | | 安全边界 | 操作系统用户 | 本地 Web 控制端口 | | 权限操作 | 桌面进程内 | 集中到控制平面 API | | 复杂业务 | 主程序内实现 | 委托给 Shell 脚本 + docker exec | | 信任假设 | 能登录即可信 | 默认信任本地(管理界面默认免登录) |

在上述差异中,有两个设计取向直接决定了这类架构的风险。

  1. Shell 脚本即扩展 API——备份、恢复、数据库等复杂业务不在主程序内实现,而是委托给 bash + docker exec,由控制中心通过 wsl -d … -u root 进入 Linux 执行。这把 Web 请求到系统命令的距离压缩到最短,任何一个未严格校验的用户输入都可能直接成为命令语法的一部分。
  2. 默认信任本地——管理 API 的认证开关出厂默认关闭,假设能访问本机即可信。这个假设在工控场景里并不成立:工程师站上运行的任何程序(浏览器扩展、下载的软件、U 盘带入的样本)都可能触达控制端口。

3. 技术细节分析

3.1 控制平面:配置驱动的 Express 编排

  控制中心通常是嵌入式 Web 服务(Node/Express 类技术栈),按配置文件动态注册控制器与路由,职责包括:服务生命周期管理、备份恢复编排、许可证管理、网络配置、管理员账户管理。所有控制器最终汇入统一的命令执行服务:

// 控制中心命令执行核心
const commandWithArgs = `${command} ${args}`;
child_process.exec(commandWithArgs, { maxBuffer: 100 * 1024 * 1024 }, (err, stdout) => {
    // 回调处理输出
});

关键点:Windows 上 child_process.exec 默认走 cmd.exe /c;&|||` 均为元字符——这是命令注入类问题的根源。

认证实现采用”开关”模式,配置为双文件模型:

// 业务配置
{
&nbsp;&nbsp;"services": [ {&nbsp;"container":&nbsp;"ide",&nbsp;"port":&nbsp;"<业务端口>",&nbsp;"composeFile":&nbsp;"<容器编排文件路径>"&nbsp;} ],
&nbsp;&nbsp;"adminName":&nbsp;"admin",
&nbsp;&nbsp;"adminPasswdHash":&nbsp;"<密码哈希>",
&nbsp;&nbsp;"loginEnabled":&nbsp;false
}
// 认证中间件逻辑:开关关闭则直接放行
const authEnabled = appConfig.isLoginEnabled();
if&nbsp;(isSessionValid() || !authEnabled) {
&nbsp; &nbsp; next();
}&nbsp;else&nbsp;{
&nbsp; &nbsp; req.session.destroy();
&nbsp; &nbsp; res.status(401).json({ error:&nbsp;"unauthorized"&nbsp;});
}

3.2 工具链层:备份恢复链

  备份恢复是工控 IDE 的高频功能,实现为一组 Shell 脚本,各司其职。备份脚本负责打包数据并用私钥签名(openssl dgst -sha256 -sign),产出带签名的备份包;校验脚本在恢复前执行,负责解压、校验签名与比较版本——但实现上仅在存在签名文件时才验签,缺失时直接放行;恢复脚本负责嵌套解压、按配置同步用户数据与插件目录,并触发容器内的数据库脚本;数据库脚本通过 docker exec 在容器内执行工程数据库的备份与恢复逻辑;健康检查脚本则在备份与恢复前后轮询 IDE 服务健康端口,最长等待数分钟。

恢复流程的数据流如下所示:

3.3 容器运行时与插件体系

天行 IDE 主服务容器对外提供业务端口,Web UI 经反向代理暴露于本机回环;仿真容器支持多实例与动态端口映射。容器编排文件与运维脚本存放在虚拟磁盘固定目录,业务数据经 bind mount 挂载进容器。

插件包为压缩包格式,内含扩展代码与语言服务组件,结构如下所示:

插件包
├── extension.manifest
├── [Content_Types].xml
└── extension/
&nbsp; &nbsp; ├── package.json &nbsp; &nbsp; &nbsp; &nbsp; ←&nbsp;"activationEvents": ["*"],&nbsp;"canDisable":&nbsp;false
&nbsp; &nbsp; ├── out/extension.js &nbsp; &nbsp; &nbsp;← 编译产物
&nbsp; &nbsp; ├── java/language-server.jar &nbsp;← 语言服务 (Java LSP, 数十MB)
&nbsp; &nbsp; └── signature.sig &nbsp; &nbsp; &nbsp; &nbsp; ← 仅覆盖部分文件

3.4 许可证与激活

控制平面 API 负责许可证 CRUD;配置文件写明厂商服务器地址与上报间隔(如 60s);激活由本地动态库完成,基于硬编码期望值的校验算法,可被静态分析绕过。

4. 攻击面与风险全景

天行 IDE 的攻击面沿三层架构纵向分布。从外部看,可达路径集中在控制平面——它是唯一同时满足”默认可达 + 高权限编排”的一层,其余各层多需前置条件(诱导恢复、安装插件等)才能触达。逐层来看:

  • 控制平面暴露面最广:管理 API 默认免认证,命令拼接执行、文件上传、配置与状态泄露集中于此。只要攻击者能触达管理端口(本机任意进程,或网络暴露场景下的远程),即可获得未授权全控、命令执行与敏感信息泄露的完整能力。
  • 工具链层的暴露面集中在备份恢复链路上:签名私钥随包分发、验签条件性跳过、压缩包路径穿越。其触达前提是诱导用户恢复一个恶意备份包,后果是数据篡改与恶意数据/插件植入。
  • 容器运行时的暴露面是特权容器与敏感挂载:docker.sock、宿主磁盘直接挂载进容器,触达前提是容器内获得命令执行,后果是容器逃逸与宿主 Windows 沦陷。
  • 插件与语言服务层的暴露面包括插件签名不全与语言服务命令桥接,触达前提是安装或恢复恶意插件,后果是容器内任意命令执行。
  • 凭据与激活层存在出厂硬编码口令+全量提权、激活校验可绕过的暴露面,触达前提是本地访问虚拟磁盘或分析激活组件,后果是本地提权与授权绕过。
  • 许可证层存在未授权操作与明文遥测外发,控制平面可达即可触达,后果是信息泄露与业务干扰。

其中控制平面是风险密度最高的一层:默认免认证使可达管理端口成为唯一前置条件,而该端口在默认部署下绑定本机回环——意味着任何能访问本机的进程都具备发起攻击的资格。其余各层的暴露面更多依赖社会工程(诱导恢复、诱导装插件)或先行突破控制平面,属于纵深攻击链中的后续环节。

4.1 典型风险举例:控制平面命令执行

控制平面命令拼接是最具代表性的严重风险:业务参数(文件名、密码、路径)未经校验直接拼入系统命令字符串,经cmd.exe/bash 解析执行。攻击者传入的不是文件名,而是命令语法(以下为示意请求,路由与动作名为占位符):

POST /api/admin/verify-backup HTTP/1.1
Content-Type: application/json

{&nbsp;"action":&nbsp;"verifyBackup",
&nbsp;&nbsp;"content": {&nbsp;"fileName":&nbsp;"x.bsbk; id > /tmp/payload.txt #"&nbsp;} }

拼接后的命令形态为虚拟机内 bash -c “… /tmp/x.bsbk; id > /tmp/payload.txt # …”,注入内容在虚拟机内以root执行;另一类变体在重置密码接口中经Windows命令解释器解析&/||`,同样可达命令执行。默认免认证 + 命令拼接叠加后,单条 HTTP 请求即可获得环境最高权限,是此类架构中危害等级最高的风险点。

4.2 典型风险举例:容器逃逸至宿主机

业务容器以特权模式运行并挂载 Docker 控制套接字与宿主磁盘:

# 容器编排文件
services:
&nbsp; ide:
&nbsp; &nbsp; image: ide-service:latest
&nbsp; &nbsp; privileged:&nbsp;true&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;# 特权模式
&nbsp; &nbsp; security_opt:
&nbsp; &nbsp; &nbsp; - seccomp=unconfined &nbsp; &nbsp;#关闭安全计算约束
&nbsp; &nbsp; volumes:
&nbsp; &nbsp; &nbsp; - /mnt:/mnt &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;# 宿主磁盘(Windows 盘符映射)
&nbsp; &nbsp; &nbsp; - /var/run/docker.sock:/var/run/docker.sock &nbsp;# 容器控制套接字

容器与宿主之间因此不存在真实隔离:容器内一旦获得命令执行(内置终端、恶意插件、脚本注入任一入口),即可读写宿主磁盘、控制宿主容器引擎,实现事实上的宿主沦陷。该风险是容器内执行到整机失守的关键放大环节,也是工控环境中后果最严重的一类——工程师站一旦失守,后续可向办公网、生产网横向渗透。

4.3 可能的攻击链

把全景中的暴露面串起来,是一条完整的纵深链路:免认证控制平面 → 命令执行 → 伪造签名备份/植入恶意插件 → 容器内执行 → 特权容器逃逸 → 宿主沦陷 → 工程数据与生产环境失守,如下所示。

图中 9 个环节:前 5 步(免认证 → 命令拼接 → 伪造备份/植入插件 → 恢复执行)发生在控制平面与工具链层,属于”进入阶段”;后 4 步(容器内执行 → 特权逃逸 → 宿主沦陷 → 数据失守)沿容器边界逐级放大,属于”放大阶段”。每一步既是前置条件,也是影响放大器——尤其需要注意的是,起点与多个关键环节(免认证、私钥随包、验签可跳、特权容器)都是出厂默认配置,攻击者甚至不需要真正”攻击”,只需走完流程即可达到攻击目的。

5. 风险传导与对用户的影响

对最终用户(工控企业、工程师、运维人员)而言,上述攻击面的影响是现实且多维度的。

  • 工程数据安全首当其冲。工程源码、用户库、设备描述集中存放于本机虚拟磁盘,环境一旦被控制,这些资产可被窃取、篡改或加密勒索——对产线而言,丢失工程文件可能意味着停工与重建成本。
  • 生产环境可信性同样堪忧。攻击者可伪造签名备份、植入恶意插件,经”工程师正常操作”(如恢复备份)完成持久化,且整个过程发生在合法的业务流程里,难以被发现。
  • 横向移动跳板是最具扩散性的影响。容器/虚拟机与宿主磁盘、容器引擎直接打通,攻破工程环境后可威胁工程师站,进而渗透办公网/生产网——工控环境最忌”工程师站失守”,而这类架构恰恰把工程师站变成了高价值目标。
  • 供应链风险也不容忽视。安装包、镜像、插件任一环节被篡改都可能带入后门;当签名机制形同虚设时,用户甚至无法自证环境可信。

需要特别强调:上述风险多数并非”必须被攻击”才会出现,它们是出厂设计决策的直接结果——风险在安装完成那一刻就已存在,与用户是否谨慎操作无关。这是此类架构与传统 IDE 最大的不同:传统 IDE 的风险要靠”被攻击”来触发,而新型 IDE 的风险是”默认存在”的。

6. 防护措施

  • 对工业软件厂商:
  1. 管理界面认证开关默认开启,强制首次改密;认证逻辑改为默认拒绝,白名单放行;
  2. 备份签名改为仅公钥验签,私钥不随产品下发;无签名或验签失败一律拒绝恢复;
  3. 系统调用全部参数化,杜绝字符串拼接;用户可控文件名/路径由服务端生成;
  4. 压缩包解压前校验路径白名单,防止路径穿越;恢复流程数据覆盖范围最小化;
  5. 容器默认非特权,仅挂载必需目录,docker.sock 与宿主磁盘不得默认挂载;
  6. 插件全量签名(含语言服务组件),语言服务命令桥接加白名单;
  7. 出厂镜像移除固定口令与全量提权配置;
  8. 激活机制服务端化或硬件绑定;遥测默认关闭、传输加密、支持离线模式。
  • 对工厂企业用户:
  1. 安装后立即开启管理登录、设置强口令,禁用/修改出厂默认账号;
  2. 控制平面与 IDE 端口严格限制在本机回环,禁止映射公网或办公网可达;
  3. 对备份/恢复文件执行来源核验,不接受来路不明的工程包;
  4. 插件仅从官方渠道获取,不安装来源不明的扩展;
  5. 定期巡检:管理端口监听地址、默认账号是否存在、有无异常外连流量;
  6. 将工程师站纳入主机加固与审计范围,必要时部署工控安全监测与审计系统。

7. 总结

天行 PLC 编程环境以 Web 控制平面 + 容器运行时重塑了工控软件的部署形态,工程效率的提升实实在在。但架构现代化的同时,安全边界发生了根本性迁移——从”操作系统用户”退化为”一个默认免认证的本地 Web 端口”。攻击面沿三层架构纵向分布,控制平面因”默认可达 + 高权限编排”成为风险密度最高的一层;控制平面命令执行与容器逃逸两类严重风险,配合免认证、私钥随包、特权容器等出厂默认设计,使这类产品在安装完成时即自带多条潜在高风险路径。

架构越现代,越要把认证、命令执行隔离与最小权限做扎实。对工控用户而言,理解新架构的信任边界与风险传导路径,比单纯依赖”软件本身的安全承诺”更为重要。也期待厂商在追求功能现代化的同时,把安全设计放在与业务功能同等的位置——毕竟工控环境里的一次失守,代价远高于普通 IT 系统。

结束

招新小广告

ChaMd5 Venom 招收大佬入圈

新成立组IOT+工控+样本分析 长期招新

欢迎联系[email protected]


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:ChaMd5安全团队 ic3blac4 ic3blac4《新型 PLC 编程软件架构演进、安全风险分析》

评论:0   参与:  0