文章总结: 文章剖析国产新型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 | | 信任假设 | 能登录即可信 | 默认信任本地(管理界面默认免登录) |
在上述差异中,有两个设计取向直接决定了这类架构的风险。
- Shell 脚本即扩展 API——备份、恢复、数据库等复杂业务不在主程序内实现,而是委托给 bash + docker exec,由控制中心通过 wsl -d … -u root 进入 Linux 执行。这把 Web 请求到系统命令的距离压缩到最短,任何一个未严格校验的用户输入都可能直接成为命令语法的一部分。
- 默认信任本地——管理 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,;、&、|、||` 均为元字符——这是命令注入类问题的根源。
认证实现采用”开关”模式,配置为双文件模型:
// 业务配置
{
"services": [ { "container": "ide", "port": "<业务端口>", "composeFile": "<容器编排文件路径>" } ],
"adminName": "admin",
"adminPasswdHash": "<密码哈希>",
"loginEnabled": false
}
// 认证中间件逻辑:开关关闭则直接放行
const authEnabled = appConfig.isLoginEnabled();
if (isSessionValid() || !authEnabled) {
next();
} else {
req.session.destroy();
res.status(401).json({ error: "unauthorized" });
}
3.2 工具链层:备份恢复链
备份恢复是工控 IDE 的高频功能,实现为一组 Shell 脚本,各司其职。备份脚本负责打包数据并用私钥签名(openssl dgst -sha256 -sign),产出带签名的备份包;校验脚本在恢复前执行,负责解压、校验签名与比较版本——但实现上仅在存在签名文件时才验签,缺失时直接放行;恢复脚本负责嵌套解压、按配置同步用户数据与插件目录,并触发容器内的数据库脚本;数据库脚本通过 docker exec 在容器内执行工程数据库的备份与恢复逻辑;健康检查脚本则在备份与恢复前后轮询 IDE 服务健康端口,最长等待数分钟。
恢复流程的数据流如下所示:
3.3 容器运行时与插件体系
天行 IDE 主服务容器对外提供业务端口,Web UI 经反向代理暴露于本机回环;仿真容器支持多实例与动态端口映射。容器编排文件与运维脚本存放在虚拟磁盘固定目录,业务数据经 bind mount 挂载进容器。
插件包为压缩包格式,内含扩展代码与语言服务组件,结构如下所示:
插件包
├── extension.manifest
├── [Content_Types].xml
└── extension/
├── package.json ← "activationEvents": ["*"], "canDisable": false
├── out/extension.js ← 编译产物
├── java/language-server.jar ← 语言服务 (Java LSP, 数十MB)
└── signature.sig ← 仅覆盖部分文件
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
{ "action": "verifyBackup",
"content": { "fileName": "x.bsbk; id > /tmp/payload.txt #" } }
拼接后的命令形态为虚拟机内 bash -c “… /tmp/x.bsbk; id > /tmp/payload.txt # …”,注入内容在虚拟机内以root执行;另一类变体在重置密码接口中经Windows命令解释器解析&/||`,同样可达命令执行。默认免认证 + 命令拼接叠加后,单条 HTTP 请求即可获得环境最高权限,是此类架构中危害等级最高的风险点。
4.2 典型风险举例:容器逃逸至宿主机
业务容器以特权模式运行并挂载 Docker 控制套接字与宿主磁盘:
# 容器编排文件
services:
ide:
image: ide-service:latest
privileged: true # 特权模式
security_opt:
- seccomp=unconfined #关闭安全计算约束
volumes:
- /mnt:/mnt # 宿主磁盘(Windows 盘符映射)
- /var/run/docker.sock:/var/run/docker.sock # 容器控制套接字
容器与宿主之间因此不存在真实隔离:容器内一旦获得命令执行(内置终端、恶意插件、脚本注入任一入口),即可读写宿主磁盘、控制宿主容器引擎,实现事实上的宿主沦陷。该风险是容器内执行到整机失守的关键放大环节,也是工控环境中后果最严重的一类——工程师站一旦失守,后续可向办公网、生产网横向渗透。
4.3 可能的攻击链
把全景中的暴露面串起来,是一条完整的纵深链路:免认证控制平面 → 命令执行 → 伪造签名备份/植入恶意插件 → 容器内执行 → 特权容器逃逸 → 宿主沦陷 → 工程数据与生产环境失守,如下所示。
图中 9 个环节:前 5 步(免认证 → 命令拼接 → 伪造备份/植入插件 → 恢复执行)发生在控制平面与工具链层,属于”进入阶段”;后 4 步(容器内执行 → 特权逃逸 → 宿主沦陷 → 数据失守)沿容器边界逐级放大,属于”放大阶段”。每一步既是前置条件,也是影响放大器——尤其需要注意的是,起点与多个关键环节(免认证、私钥随包、验签可跳、特权容器)都是出厂默认配置,攻击者甚至不需要真正”攻击”,只需走完流程即可达到攻击目的。
5. 风险传导与对用户的影响
对最终用户(工控企业、工程师、运维人员)而言,上述攻击面的影响是现实且多维度的。
- 工程数据安全首当其冲。工程源码、用户库、设备描述集中存放于本机虚拟磁盘,环境一旦被控制,这些资产可被窃取、篡改或加密勒索——对产线而言,丢失工程文件可能意味着停工与重建成本。
- 生产环境可信性同样堪忧。攻击者可伪造签名备份、植入恶意插件,经”工程师正常操作”(如恢复备份)完成持久化,且整个过程发生在合法的业务流程里,难以被发现。
- 横向移动跳板是最具扩散性的影响。容器/虚拟机与宿主磁盘、容器引擎直接打通,攻破工程环境后可威胁工程师站,进而渗透办公网/生产网——工控环境最忌”工程师站失守”,而这类架构恰恰把工程师站变成了高价值目标。
- 供应链风险也不容忽视。安装包、镜像、插件任一环节被篡改都可能带入后门;当签名机制形同虚设时,用户甚至无法自证环境可信。
需要特别强调:上述风险多数并非”必须被攻击”才会出现,它们是出厂设计决策的直接结果——风险在安装完成那一刻就已存在,与用户是否谨慎操作无关。这是此类架构与传统 IDE 最大的不同:传统 IDE 的风险要靠”被攻击”来触发,而新型 IDE 的风险是”默认存在”的。
6. 防护措施
- 对工业软件厂商:
- 管理界面认证开关默认开启,强制首次改密;认证逻辑改为默认拒绝,白名单放行;
- 备份签名改为仅公钥验签,私钥不随产品下发;无签名或验签失败一律拒绝恢复;
- 系统调用全部参数化,杜绝字符串拼接;用户可控文件名/路径由服务端生成;
- 压缩包解压前校验路径白名单,防止路径穿越;恢复流程数据覆盖范围最小化;
- 容器默认非特权,仅挂载必需目录,docker.sock 与宿主磁盘不得默认挂载;
- 插件全量签名(含语言服务组件),语言服务命令桥接加白名单;
- 出厂镜像移除固定口令与全量提权配置;
- 激活机制服务端化或硬件绑定;遥测默认关闭、传输加密、支持离线模式。
- 对工厂企业用户:
- 安装后立即开启管理登录、设置强口令,禁用/修改出厂默认账号;
- 控制平面与 IDE 端口严格限制在本机回环,禁止映射公网或办公网可达;
- 对备份/恢复文件执行来源核验,不接受来路不明的工程包;
- 插件仅从官方渠道获取,不安装来源不明的扩展;
- 定期巡检:管理端口监听地址、默认账号是否存在、有无异常外连流量;
- 将工程师站纳入主机加固与审计范围,必要时部署工控安全监测与审计系统。
7. 总结
天行 PLC 编程环境以 Web 控制平面 + 容器运行时重塑了工控软件的部署形态,工程效率的提升实实在在。但架构现代化的同时,安全边界发生了根本性迁移——从”操作系统用户”退化为”一个默认免认证的本地 Web 端口”。攻击面沿三层架构纵向分布,控制平面因”默认可达 + 高权限编排”成为风险密度最高的一层;控制平面命令执行与容器逃逸两类严重风险,配合免认证、私钥随包、特权容器等出厂默认设计,使这类产品在安装完成时即自带多条潜在高风险路径。
架构越现代,越要把认证、命令执行隔离与最小权限做扎实。对工控用户而言,理解新架构的信任边界与风险传导路径,比单纯依赖”软件本身的安全承诺”更为重要。也期待厂商在追求功能现代化的同时,把安全设计放在与业务功能同等的位置——毕竟工控环境里的一次失守,代价远高于普通 IT 系统。
结束
招新小广告
ChaMd5 Venom 招收大佬入圈
新成立组IOT+工控+样本分析 长期招新
欢迎联系[email protected]
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:ChaMd5安全团队 ic3blac4 ic3blac4《新型 PLC 编程软件架构演进、安全风险分析》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论