项目介绍
这是一款基于SpringBoot+SpringSecurity的RBAC权限管理系统。原本只想着做成基于SpringSecurity的权限管理系统,但随着功能的增加感觉有些刹不住车了,之后可能会往后台管理系统方向发展。无任何重度依赖,非常适合新手练习上手,项目文档从零开始,十分详细。
项目搭建
项目地址:https://gitee.com/witmy/my-springsecurity-plus
这个地址项目的是目前最新版,文章中审计的是先前的版本,部分漏洞最新版也存在,这个在文章中会说明,我会把老版本的漏洞产生代码段与新版本做对比,方便更直观理解漏洞的产生
打开项目等待maven加载
修改配置文件,创建对应数据库
my-springsecurity-plus\src\main\resources\application.yml
导入sql文件
sql文件:my-springsecurity-plus\docs\sql\my-springsecurity-plus.sql
导入完成后,配置spring boot,jdk版本1.8
配置完成后启动项目即可
http://127.0.0.1:8088/login.html
管理员账号:admin/123456
漏洞挖掘
SQL注入
检查pom.xml文件,发现导入了mybatis依赖
初步判断使用,全局搜索关键词${
第一处
my-springsecurity-plus\src\main\resources\mybatis-mappers\DictMapper.xml
根据id搜索Dao层对应方法
往上查调用到controller层
接着查调用
查到controller文件,查看myDict是从哪来的,分析下这段代码
@RequestMapping
定义了基础路由 /api/dict
@Api
是Swagger文档生成标记控制器的
@Autowired
:注入 DictService
服务类,用于业务逻辑处理
index()
:处理 GET /api/dict/index
请求,返回视图名 system/dict/dict
。需要 dict:list
权限。
getDictAll()
:处理 GET /api/dict
请求,返回字典列表。需要 dict:list
权限,并记录操作日志 (@MyLog("查询字典列表")
)。使用 PageTableRequest
和 MyDict
作为请求参数,调用 dictService.getDictPage()
返回分页数据。
什么?你说你看不懂代码?GPT啊!!!
初期代码基础差,要学会使用工具,在这些信息中我们只提取我们需要的信息分析
首先这处功能点是在字典管理(代码中有注释,路由是触发/api/dict)
结合xml中的sql语句%%
,应该是查询字典的功能
带入getDictPage方法执行的参数myDict会通过参数传递所以可控
分析完后,开始漏洞复现
在后台找到字典查询的功能点
burp抓包
参数名跟代码中对应上,保存数据包Sqlmap一把搜哈
漏洞存在,新版本中这处注入修复了
第二处
my-springsecurity-plus\src\main\resources\mybatis-mappers\DeptMapper.xml
一样的思路根据id关键字追到controller层调用
跟到controller层调用
my-springsecurity-plus\src\main\java\com\codermy\myspringsecurityplus\admin\controller\DeptController.java
这一处有点不一样,如果通过后台访问功能点数据包中是没有params这个参数的,这一块代码段也没发现params参数,那么它是哪来的呢?这一处卡了我很久
全局搜索params
定位到了这个类:my-springsecurity-plus-master\src\main\java\com\codermy\myspringsecurityplus\admin\entity\BaseEntity.java
注释中也表明了是请求参数,params是Map类型的,如果为空就是new一个空的map,有值就会返回
通过类定位发现这是个抽象类,我们看下谁继承了它
通过继承的类名也可以看出都是些数据库操作类,我们看下controller的导入
发现是存在的,那么我们构造对应url
http://192.168.37.1:8088/api/dept/build?params["dataScope"]=1
报错400,不应该啊?
考虑到可能是字符的问题,url编码一下
http://192.168.37.1:8088/api/dept/build?params%5B%22dataScope%22%5D=1
发现可以解析了,上sqlmap
新版本这处没改
XSS(存储型)
由于这套系统只有后端管理,可以尝试的功能点不多,依旧是选择管理员能交互到的功能
我们先创建一个普通用户看下能操作哪些功能
那么就是在这两处尝试插入xss了
第一处
创建完成时已经弹窗了,基本确定了
模拟管理员查看用户
第二处
模拟管理员
这个最新的也有,没对参数做校验
垂直越权
查找用户操作的功能点,找到用户删除这个功能点,抓下包
数据包中校验删除用户的条件貌似是userID,我们执行看下数据库执行记录
看来是通过urse_id确认删除目标的,正常功能我们只能删除下级用户
那么我们可以尝试下删除同级用户
成功删除test6
最新版无法越权删除用户,貌似是加上JWT身份认证的原因,在做删除用户操作前会通过JWT校验用户权限
druid未授权(不存在)
虽然不存在但是分析过程我感觉不错也写上
在pom.xml文件中看到了druid的依赖
在后台发现确实存在对应功能
在代码中查看对应配置,发现是允许访问Druid的监控界面
我们在未登录的情况下尝试访问
发现实际上是有做限制的,限制了访问ip,仅允许本地访问,我尝试了xff,绕过不了,说明不是从这里获取IP
我尝试在源码中寻找,发现是存在获取ip的代码段
但是跟踪getIP这个方法的调用,没发现异常到这里就断了,这时我想到是不是把代码封装在jar里了,使用maven下载源代码
这次搜索报错信息
Sorry, you are not permitted to view this page.
定位到这个文件
我一看路径,果然是jar包里面的,全局搜索文件名
定位到验证代码段,代码中可以看出是关键是isPermittedRequest
这个方法,我们跟进去看下
看样子这个getRemoteAddress
方法就是获取IP的了,继续跟进方法
先判断remoteAddressHeader != null,查看remoteAddressHeader是个常量为null,那么直接看下面的if
通过request.getRemoteAddr()方法获取ip,确认了ip获取的方法
我尝试搜索了一下这个方法
没想到第一篇就这么劲爆,看来这个方法是有绕过可能的
由于环境在本地,本地搭建dns服务器(过程就不放了),搭建完成后再次尝试
寄,本地再起个测试环境看下获取到的ip
客户端ip为:192.168.37.130
服务端ip为:192.168.37.1
呜呜呜!欺骗我感情
自此判断不存在druid未授权
新版本取消了post方法的未授权访问,也就说可以未授权看到登入界面,但是登入不了,难崩
Spring boot Actuator未授权访问
这个其实是我之前一直没注意到的一个点,Spring boot框架已经成为java的主流之一,很多系统都采用Spring boot搭建,关于它上面的安全,确实应该重视,我自己也在思考总结思路,之后应该会专门出一篇见解下Spring boot的审计方向
这篇不会提太多
依旧是通过pom.xml发现引入了Actuator依赖
稍微看过java审计文章的就会发现pom.xml对于java代审而言真的很重要,是可以等到很多信息的,要重点查看
在配置文件中寻找配置查看开放的端点
如果设置了management.endpoints.web.exposure.include
为 *
,就可以在 /actuator
看到所有存在的端点
但是它这里只开放了这几个
/info
显示任意的应用信息
展示了关于应用的一般信息,这些信息从编译文件比如 META-INF/build-info.properties 或者 git 文件比如 git.properties 或者任何环境的 property 中获取
/health
显示应用的健康信息(当使用一个未认证连接访问时显示一个简单的’status’,使用认证连接访问则显示全部信息详情)
health一般只展示了简单的UP和DOWN状态
/beans
//显示一个应用中所有Spring Beans的完整列表
/env
//显示来自Spring的 ConfigurableEnvironment的属性
可能会泄露数据库账号密码等敏感信息
/metrics
//展示当前应用的metrics信息
获得每个度量的名称,其中主要监控了JVM内容使用、GC情况、类加载信息等
比较重点的是/env,可能会泄露配置文件信息(并不是说其它没有)
针对env这种路径下泄露的密码会用*
进行脱敏,想要获取对应的明文密码,可以尝试通过分析heapdump数据的方式
但是很可惜这套系统没有开放/heapdump端点
新版本也是直接不允许未授权访问/actuator了
Swagger API泄露
依旧是通过pom.xml发现依赖
也设置了静态资源,也就是未授权了
尝试访问
http://127.0.0.1:8088/swagger-ui.html#/
提供了很多接口,但是能不能用,得测试
我们可以访问它提供的api地址
http://127.0.0.1:8088/v2/api-docs
然后使用工具批量爬取接口测试存活
swagger-hack
项目地址:https://github.com/jayus0821/swagger-hack
python swagger-hack2.0.py -u "http://ip:8088/v2/api-docs"
测试结果会保存在csv文件中
新版本和老版本这块没差别
总结
关于Spring boot框架常见的漏洞平时我确实没有注意,更多的都是通用漏洞和组件挖掘为主,对于框架易产生的漏洞较为疏忽,接触的也少,要让自己的思路扩展开来,多个攻击面出洞的几率就更高。这套源码实际上属于半成品,很多功能点都没开发,不知道后面作者会不会加,部分漏洞修补的也比较潦草。
- my-springsecurity-plus.zip 下载