一、背景
我是承影战队的zava,代码审计是信息安全研究员、白帽子以及渗透测试工程师必要掌握的一门技巧。在漏洞挖掘过程中,分析漏洞产生原理以及如何利用漏洞,都要求我们必须至少掌握一门开发语言。java语言由于其面向对象、良好的跨平台执行、高可移植性以及具有丰富的内置类库的特点在市场上占有率极高,以java语言开发的CMS也不计其数。
内容管理系统(Content Management System,CMS)是一种位于Web 前端服务器和后端办公系统之间的软件系统。内容的创作人员、编辑人员、发布人员使用内容管理系统来提交、修改、审批、发布内容。随着科技与信息的高速发展,CMS的开发也越来越个性化。然而在功能、性能和效率全面提高的同时,安全问题也逐渐暴露出来,逻辑漏洞、框架漏洞等各类业务漏洞不断被白帽子发现,
本文从一个简单的基于springboot框架的CMS所需各组件的开发过程正向分解分析,结合一个开源springboot架构的项目进行白盒审计,辅助黑盒工具,旨在提供一种从开发过程分析到黑白盒正向挖掘CMS漏洞的经验分享。
二、springboot介绍
Spring是Java企业版的轻量级代替品,通过依赖注入和面向切面编程,用简单的Java对象实现了EJB的功能。但是Spring用到了很多xml配置,这种重量级配置也是spring的一个重大缺点。
springboot是一个构建在Spring框架顶部的项目。在springboot框架中已经嵌入了tomcat,jetty,Undertow等web容器,因此在使用springboot开发时不需要部署WAR文件,只需要通过自己的启动器(Starter)来,简化项目的构建配置。
三、springboot项目搭建
3.1环境配置
本地部署环境:jdk-8u-102,Idea2022,mysql 8.0.31、maven3.8.6
3.2 springboot项目搭建步骤
新建springboot项目:
添加web依赖:
springboot项目结构:
SpringbootdemoApplication:作为springboot项目的启动类,它是基于main方法来运行的,目的是启springboot项目 。
application.yml:修改端口号和上下文路径
springboot的pom配置文件
在maven的POM里,我们可以看到springboot引入的一个重要依赖:spring-boot-starter-web,这是springboot的web启动器,查看依赖图可以发现其导入了很多web依赖,这里只附上一部分依赖图:
3.3启动springboot项目
修改端口号:springboot默认端口号是8080,这里我们修改为8088,防止测试时端口冲突。
运行springboot启动类
访问springboot项目:访问127.0.0.1:8088,这里我们已经成功搭建起了一个简单的springboot项目。
四、基于springboot架构CMS组件分解分析
springboot作为一个轻量级框架,本身已经集成了许多容器,并且spirngboot可以集成各类组件,从而快速提升开发效率,下面我们简单介绍一下在开发CMS时spirngboot集成个组件的过程,所用到的组件有Spring Security、Mybatis、Freemaker、Thymeleaf。
4.1 springboot集成Spring Security
Spring Security介绍
Spring Security是一个高度自定义的安全框架。利用Spring的IoC特性和AOP功能,为系统提供了声明式安全访问控制功能,减少了为系统安全而编写大量重复代码的工作。
引入依赖
下面我们简单启动一个Spring Security项目,由于Spring Security已经被Springboot集成,可直接引入启动器:spring-boot-starter-security
运行Spring Security项目
在浏览器内访问127.0.0.1:8080/html会主动显示如下界面:
默认用户名为user,password内置于控制台;
输入账户密码,成功跳转springboot首页;
UserDetailsService
当spring security未做任何配置的时候,账号和密码是由其自定义生成的,然而在实际项目中,账号和密码都是从数据库中查询出来的。所以我们需要通过自定义认证逻辑,这里只需要实现UserDetailsService接口即可。
4.2 springboot集成Mybatis
Mybatis介绍
MyBatis 是一个 Java 持久化框架,它将 Java 对象映射到数据库表,并提供 SQL 映射 API 来对数据库执行 CRUD(创建、读取、更新、删除)操作。 在 MyBatis 应用程序的上下文中,DAO(数据访问对象)层通常负责抽象与数据库交互的细节,并为应用程序的其余部分在访问数据时使用提供一个干净、简单的接口。
引入Mybatis依赖:
查看依赖:
写入配置文件:这里我们在application.yml配置文件中添加上数据库的配置信息。
controller层代码编写:
service层代码编写:
配置mapper.xml文件:保证namespace同mapper文件路径名相一致。
代码效果展示:添加数据。
查询数据:
4.3 springboot集成freemaker
freemaker介绍
FreeMarker是一款免费模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。
引入依赖:
controller层代码编写:
创建模版文件:在resources目录下创建.ftlh文件,作为渲染数据的模版。
启动项目:
4.4 springboot集成Thymeleaf
Thymeleaf介绍
Thymeleaf是一种适用于 Web 和独立环境的现代服务器端 Java 模板引擎。用 Thymeleaf 编写的 HTML 模板仍然像 HTML 一样看起来和工作,让应用程序中运行的实际模板继续作为有用的设计工件工作。
引入依赖:
controller层代码编写:
创建模版文件:在resources目录下创建index.html文件,作为渲染数据的模版。
测试文件:
五、白盒审计MCMS系统
以上对springboot框架和各类组件已经有了一定的了解,下面我们对某个开源系统进行代码审计。MCMS是一套完整开源的Java CMS,基于SpringBoot 2架构,前端基于vue、element ui。目前该CMS最新版本为5.2.11,论坛上也有很多大牛对该系统做过代码审计分析,本文是对该系统的5.2.1版本进行一个白盒审计,并结合部分黑盒辅助,提供一种代码审计思路分享。
5.1 项目环境搭建
导入项目:这里选择将源码下载到本地再由IDEA导入项目。源码下载地址为:https://gitee.com/mingSoft/MCMS/releases。
配置mysql数据库:导入源码数据库。
修改.yml配置文件:配置文件的数据库名要保持一致,数据库账户密码改为自己账户密码。
运行启动类启动项目:访问http://127.0.0.1:8080/ms/login.do。出现如下页面代表项目启动成功,默认账户密码:msopen/msopen。
5.2 白盒审计MCMS系统
查看项目依赖文件
在pom.xml中可以看到很多熟悉的组件,如:log4j、freemaker、fastjson、shiro、mybatis等等,因为这些组件经常爆出高危漏洞,所以在审计过程时可以重点关注一下依赖组件的版本和漏洞情况。
重点关注Mybatis的xml配置文件
Mybatis的DAO 层通常实现为一组接口,每个接口定义一组方法,用于对存储在数据库中的数据执行各种操作。要在应用程序中使用 MyBatis,通常还需要配置一个 .xml的SQL映射文件,该文件定义要用于 DAO 接口中每个方法的 SQL 语句。与任何其他持久化框架或数据库访问工具一样,如果使用不当,MyBatis 也容易受到 SQL 注入攻击,例如使用"$"符号来表示参数占位符时极易产生sql注入风险, 用户可以通过输入恶意的参数来绕过程序的防御措施。
对每一个DAO层的.xml配置文件进行搜索,发现一处使用$的sql语句参数:(select id FROM cms_category where find_in_set('${categoryId}',CATEGORY_PARENT_IDS)>0))。该参数位置很可能存在sql注入。
根据categoryId这个参数,快速搜索使用了该参数的类,在包net.mingsoft.cms.action.web和包net.mingsoft.cms.action.web下均存在categoryId参数。
定位到ContentAction.java,找到/list接口,可以看到content对象没有任何过滤直接被传参进来;
搜索对应前端页面,这里发现web端无论点击任何功能点url栏均未变化。
对页面抓包,可以在burp中发现隐藏的接口:
这里我们构造http://127.0.0.1:8080/ms/cms/content/list;
随后加入含有categoryId的参数;
这里借助sqlmap工具对该注入点测试,成功爆出数据库。
搜寻后台的文件上传点
我们在模版管理处发现一个上传位置,并且做了白名单处理,只允许上传zip文件;
对后端代码全局搜索发现前端js确实做了过滤;
这里我们上传一个名为pwd的文件夹,上传完毕后在后端代码处也发现了上传位置,但内部的文件没有解析。
从前面的前端js我们可以知道它只允许上传html和png、jpg类的图片格式,这里我们在pwd内上传一张图片,通过前端url定位后端源码的file/uploadTemplate.do处;
这里利用全局扫描搜索file可以找到文件上传的接口
抓包后可以发现文件的路径名,访问文件:
所以对后台对文件上传点我们要多多留心,容易出现上传漏洞。
分析容易出现高危漏洞的组件
首先通过全局搜索发现shiro位置。
在后台的登陆页面是存在shiro框架的,也可以通过工具直接爆破一下,但是这里是没有密钥泄漏的,我们通过源码也没有搜索到密钥泄漏。
5.3 审计思路总结
针对上述项目的白盒审计,最后总结一下:
(1) 对于静态java代码的审计工作,我们首先要对项目对每一个层次和功能点首先有所了解,对springboot架构的项目首先可以看它的.yml配置文件和启动类,找到项目启动点;
(2) 针对输入传入后端的位置我们一定要特别留意,尤其是传参没有过滤的地方极容易产生注入风险;
(3) 要经常利用idea中的快捷键,快速定位关键函数的位置,找到函数调用的利用链;
(4) 在白盒没有思路的时候,我们可以利用一些工具进行黑盒辅助,以更好的提升我们的工作效率
六、参考链接
https://www.365seal.com/y/QgV081ENVw.html
https://www.modb.pro/db/180555