0x01 前言

只做php的代码审计没法满足当前的市场需求了,国内的php建站系统越来越少。主流的还是java的框架,正好这段时间开始去审计一些java的框架,做一个从php到java代码审计的过渡,理解对java框架或者组件的审计思想。

Jspxcms是灵活的、易扩展的开源网站内容管理系统(java cms,jsp cms),支持多组织、多站点、独立管理的网站群。

0x02 漏洞审计

环境搭建不再说了,网上有相关文章,在 com.jspxcms.core 包下有Application启动程序,运行该程序即可启动springboot项目。

启动后访问网址:http://localhost:8080

代码很多,找控制器文件都得找半天,甚至连后台登录地址都不知道是什么,,看了框架的说明文档是http://localhost/cmscp/ 看了半天代码也没看懂是怎么判断 cmscp 为后台地址的。看来还是得学学开发了。

1. XSS漏洞

主页面随便点击一个新闻,下面有留言功能,猜测这里应该会存在XSS。

前台随便注册一个账户发表评论

评论了刷新并没有弹窗,应该是存储型的xss,会写进数据库里的,在提交处抓包看一下

评论写进数据库的代码分析

全局搜索 /comment_submit

定位到相关路由代码,调试跟进分析

首先对用户身份,权限做了一个判断,然后调用 service 的 save 方法。comment 参数包含了我们评论的XSS语句。

将 comment 参数的数据封装成 javabean 格式,传递到Dao层,将数据添加到数据库中,下面的代码就不用看了。

接着回到我们的问题上,为什么刷新页面没有出现弹窗,猜测可能是被转义了。抓包看一下。

果真被转义了。

页面刷新代码分析

全局搜索 /comment_list

跟进 list 方法

首先从数据库里把评论信息读取出来

然后设置模板填充数据

最终设置的模板是这个,查看一下这个模板

通过依赖查看到选用的模板是 freemarker,当前的前端页面使用了 escape 标签进行 HTML 实体编码。

接下来找与评论有关的前端页面,并且没有 escape 标签进行实体编码。

找到在 sys_member_space_comment.html 页面中,没有对数据进行转义,并且与评论有关,全局搜搜该文件

在sys_member_space.html 页面包含了 sys_member_space_comment.html

再全局搜索 sys_member_space.html

文件名被定义成了常量,那么全局搜索这个常量

在 space 方法引入了该模板,该方法也能够通过路由直接访问,访问路径的格式为 /space/{id} 时就能触发 XSS 了。

这个id应该就是用户的识别id,就是在个人空间的评论处出现弹窗

为什么有个 ?type=comment,是因为在这个模板做了一个if判断,如果 type 为 comment 就会包含 sys_member_space_comment.html 前端文件

这样就可以成功触发XSS了。

2. SSRF漏洞

ssrf的漏洞函数和php的不太一样,具体有以下几种函数

URL.openConnection()
URL.openStream()
HttpClient.execute()
HttpClient.executeMethod()
HttpURLConnection.connect()
HttpURLConnection.getInputStream()
HttpServletRequest()
BasicHttpEntityEnclosingRequest()
DefaultBHttpClientConnection()
BasicHttpRequest()

全局搜索 HttpClient.execute 方法,定位到 fetchHtml 方法

httpclient.execute 方法会模拟客户端发起url请求,并接受响应包,往上查找

找到一个控制器方法,从前端接受的url内容没有做任何处理,可以造成ssrf漏洞

成功跳转到百度页面,这个好像只能发起一个http请求

3. RCE漏洞

后台登录后,在文件管理处可以上传文件,有上传压缩包和文件两个选项

当我们上传 jsp 木马后

通过 store 方法将 jsp木马上传到 upload/1/ 目录下

多了一个 jsp目录,为什么会这样,调试一下

访问 jsp文件 JspDispatcherFilter 过滤器来做处理,该过滤器用于在java web 应用程序中处理JSP

加了一个jsp前缀,所以木马路径访问不到了。直接上传jsp看来是不行的,访问jsp的时候会被这个拦截器进行处理。

当我们上传一个压缩包

上传完压缩包后,会对其压缩包进行一个解压的操作,没有对文件做限制,那么我们就可以构造相对路径的文件名,将我们构造的文件解压到任意目录,为了绕过 JspDispatcherFilter 过滤器的处理,可以将木马文件打包成一个war包,通过tomcat 进行部署,这就相当于一个新的网站项目,该过滤器是不做处理的。

将冰蝎的jsp木马打包成 war包

修改文件名,默认会把压缩包上传到 uploads/1/ 目录下,我们希望把war包解压到 webapp目录下,通过python脚本修改文件名

import zipfile

z = zipfile.ZipFile('test0.zip', 'w', zipfile.ZIP_DEFLATED)
with open('shell.war','rb') as f:
temp=f.read()

z.writestr('../../shell.war',temp) #shell.war为上一步生产的后门war包
z.close()

压缩名为 test0.zip ,通过接口上传

会发现 webapp 里多了 shell.war,这时候需要启动tomcat,让它去解析我们上传的war包

这时候路径为 /shell_war/shell1.jsp,通过冰蝎连接

能够执行命令,我不能通过 bat 来启动tomcat,通过idea启动tomcat需要主动解析我们上传的war包,为了复现成功也只能这么做了。