某RBAC管理系统审计

前言

这个管理系统的审计我去年就开始了但烂尾了,那时候太热闹了log4j2,cs的cve反制等等。这个都给忘了,所以本篇可能有些图有点老,现在就是旧图没一个个换遇到的新的就加上。现在Java也学了一些了,来搞审计理解就更深了。

环境配置

MySql

小皮面板开起MySQL。

找到MySQL安装目录,加环境变量。小皮面板的在这个extensions目录下面。

创建一个库。

导入rbac.sql文件,全ok就没问题了。

Maven

idea中内置了maven就直接用了,下面记录了一些遇到的问题。

依赖问题

加载依赖的时候还有可能会遇到这样的情况:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/context/index/CandidateComponentsIndexLoader

[这个异常的原因是Spring Boot在创建entityManagerFactory这个bean时,找不到CandidateComponentsIndexLoader这个类,解决办法就是在pom.xml中添加spring-context-indexer依赖。

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-indexer</artifactId>
<optional>true</optional>
</dependency>

在idea中打开pom.xml,以项目方式打开,如果之前没用过maven就去设置里面勾选一下下面的选项,将IDE的构建/运行操作委托给Maven,就可以自动下载所需要的依赖了。

更改数据库配置,修改号连接的用户名和密码。端口号有冲突也是自行修改。

配置问题

有报错时,双击红色报错跳转到对应的标签下,可以发现org.springframework.boot没问题,但是的spring-boot-maven-plugin提示有问题。

crtl+单击上面的org.springframework.boot会跳转到配置文件中,找到spring-boot-maven-plugin的版本信息,也就是,复制到标错的那行下边就行了。

JDK问题

还有可能遇到的几种错误:

  1. java: -source 1.3 中不支持注释(请使用 -source 5 或更高版本以启用注释) 或者 java: Compilation failed: internal java compiler error

  2. class lombok.javac.apt.LombokProcessor (in unnamed module @0x50b78155) cannot access class com.sun.tools.javac.processing.JavacProcessingEnvironment (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.processing to unnamed module @0x50b78155

    像这些情况基本都是JDK版本问题,就检查一下这三个地方是否已经更换成了相应版本的jdk。ctrl+alt+shift+s 打开项目结构。然后现在project这里更换

再检查底下modules。

最后再 File -> Settings里面注意两个地方的版本都要相同。

最后能够跑起来有日志了就没问题了。

访问 http://127.0.0.1:8088/login.html 即可看到以下界面。

渗透测试

目录爆破

先用dirsearch扫一下目录。

未授权访问

根据上面的结果可以看到有一些目录,首先先去看/actuator/env ,因为通过他可以看到 SpringBoot 载入了哪些 properties,以及 properties 的值(这个里面会自动用*替换 key、password、secret 等关键字的 properties 的值进行脱敏)

其他的一些常见的:

路径 描述
/autoconfig 提供了一份自动配置报告,记录哪些自动配置条件通过了,哪些没通过
/beans 描述应用程序上下文里全部的Bean,以及它们的关系
/env 获取全部环境属性
/configprops 描述配置属性(包含默认值)如何注入Bean
/dump 获取线程活动的快照
/health 报告应用程序的健康指标,这些值由HealthIndicator的实现类提供
/info 获取应用程序的定制信息,这些信息由info打头的属性提供
/mappings 描述全部的URI路径,以及它们和控制器(包含Actuator端点)的映射关系
/metrics 报告各种应用程序度量信息,比如内存用量和HTTP请求计数
/shutdown 关闭应用程序,要求endpoints.shutdown.enabled设置为true
/trace 提供基本的HTTP请求跟踪信息(时间戳、HTTP头等)

我这里不知道是不是浏览器的原因,访问不到 /heapdump/actuator/heapdump(按道理actuator这个目录的所有内容都放行了应该能访问到的),拿不到堆转储文件后续就搞不了星号脱敏拿密码。项目用git托管了然后还原回去也还是下载不了。

Swagger接口文档泄露

在前面目录扫描的结果里面有几个swagger路径,可以看到所有的接口都泄露了。

登录验证码爆破

登录页面有个验证码,先去查看前端代码,点击验证码之后回去请求一个url。

这个时候用到这个插件: captcha-killer。在bp中拦截请求发送给插件的send to captcha panel。

接口的话可以选择去用百度免费的,登陆上控制台搜文字识别可以申请但是现在需,要实名认证才能领了。

实名认证并领取,然后创建一个应用自定义名字,其他的我是全选的。

然后还要利用这里的两个值去获得access_token,分别用上面的API KEY Secret Key去填充下面的两个参数,之后去浏览器中访问这个地址。或者按照官方的调用:

curl -i -k 'https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic?access_token=【调用鉴权接口获取的token】' --data 'image=【图片Base64编码,需UrlEncode】' -H 'Content-Type:application/x-www-form-urlencoded'

我这直接浏览器访问了:

https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=****&client_secret=****

回到bp中选择百度的模板然后填上刚刚得到的token。

但是真的是奇怪了,传的image参数明明是按照官方文档来的将图片转成base64,再url编码一下。

但硬是乱识别一个都识别不出来,网上也说百度对gif的识别很差劲。先试试看验证码是不是只是前端验证。

简单尝试可以发现验证码怎么修改都不会报类似验证码有误,验证码过期之类的错误提示。哪会不会是因为校验到账号密码不对就已经提前在函数中return了然后就只会显示用户名或账号密码错误了呢?

但当去掉验证码的参数之后就提示了验证码不能为空,很显然不是这样他还是对验证码有校验的。

那就有一种可能服务端根本就没做验证码值是否相等的验证,可以尝试一下,然后爆破出来得到admin:123456

Druid登录爆破

用gobuster扫了一下显示有一个druid组件,是个登录页面可以进行爆破。

在bp中给用户名和密码参数加上$,设置好字典挂着跑。根据响应长度得到admin:admin

XSS

奉承见框就插的思想,对这些输入框都拿payload试试看有没有过滤校验。在角色管理->新增模块处存在xss。

提交后刷新页面就会弹窗。

在用户管理这里的查询也是,当插入payload时会引发全局异常,此时会被记录得到异常操作日志中。

在系统管理->异常日志中加载错误记录时就会触发。

同样的,这样的xss有很多很多,因为很多地方都直接将错误记录了,对一些输入框的校验过滤可以说根本没有。

只要能触发全局异常,在加载异常日志的时候都会引发xss弹窗。

SQL注入

现在很多项目中都有基本的安全意识不会去拼接sql语句,基本上都是用PrepareStatement去预编译了。就先挂插件在后台扫,自己试试看他有没有配置疏忽的地方,插件在bapp store里面有,环境要求有JPython,配置的话网上有一堆就不赘述。

在开启扫描之后去看看其他的页面,把查询的地方都丢进去扫。不一会就有了,看payload是盲注。

系统管理 -> 字典管理 的查询那里也有sql注入。

插件里勾选了库和表信息但他没脱出来,这里就单独把报文拿出来用sqlmap跑一遍。

python sqlmap.py -r E:\sql1.txt --dbs --batch

按src标准到这适可而止,做良好公民。

python sqlmap.py -r E:\sql2.txt -D rbac --tables --batch

越权漏洞

创建了用户110但是侧边栏什么功能都没有,没明白怎么个事后续再看看。

进数据库修改一下,可以看到很明显的是bcrypt,直接将admin或者110(这两个密码相同)的加密值给他就行,虽然是不同的加密字符串但提取出的盐值相同,bcrypt的验证可以通过。

当然了破解也可以,这里将test6密码字段的加密字符串写到文件里面,john指定format即可。

john -w=/usr/share/wordlists/rockyou.txt hash --format=bcrypt

以这个普通用户test1登录F12拿到他的cookie, 在插件中设置好cookie的值然后开启autorize,然后就到处点点页面的功能(不需要拦截)。

红色表示不存在,绿色则是确定存在,黄色是不确定的需要手工验证。这里看到userId那里有可能就去尝试一下。

试试删除功能,这里选择test用户进行删除,拦截报文看到他的userId是2,drop掉这个请求不将admin删除。

然后退出,以刚刚创建的110:123456登录,这个用户下只能看到test6,抓包选择删除将userId改为2,下面乱码问题不大,状态码200就执行没问题。

此时再登录上admin就可以看到test用户已经删除了。

代码审计

未授权访问

产生原因就是SprinBoot的错误配置,这种大概率就是程序员为了方便调试而放行,但由于疏忽而忘记禁行。来到security/config/SpringSecurityConfig里面,可以看到放行了actuator和swagger-ui.html这种危险的目录。

越权漏洞

逆向去分析越权漏洞产生的原因,根据之前发现漏洞的位置,在操作用户的地方/api/user。在控制层的UserController,通过关键字找到删除用户的相关函数:

跟进这个函数,来到了事务层的UserService接口,直接去看他的实现接口。看到这里有个校验函数,后面就是在删除这个用户之前先删除与他相关的角色,相关的职位。

进入到校验的checkUserAllowed,只判断了非空和是否是admin也就是说删除其他的用户都没有限制。

一般dao都是直接操作数据库了,校验判断集中在事务层调度,这里也是一样。这一路下来并没有发现userId权限关联的判断校验,而userId也是直接从用户那边输入而不是从session中获取,也就是说他只是在根据userId进行删除用户。这就导致userId可控,这样任何人调用这个接口都可以进行删除操作。

验证码校验

看看后端的校验com/codermy/myspringsecurityplus/security/filter/VerifyCodeFilter.java(这下面的一段是本来就注释的不是我注的),看到他只有在验证码为空时才会置空销毁掉缓存中存储的验证码,这也就是说不为空的时候就算使用了错误的验证码也可以通过校验,这就是验证码可以重用的原因。

SQL注入

这个项目中使用了 Mybatis 去操作数据库,在编辑xml时Mybatis支持两种参数符号。

  1. #{value} 在预编译的时候就会用?代替参数部分将其当作字符串处理。
  2. ${} 这个表示拼接字符串,以这种方式拼接就会引起SQL注入。

根据前面发现的两处SQL注入一个个逆向去分析漏洞成因,先看字典管理那里的(一般直接审计代码的话就两下shift全局搜${)。在工程下的main/resources/mybatis-mappers, 看文件名就是DicMapper.xml

很明显这里用了拼接,解决方法也就是直接用#替换掉$。这里一路跟进getFuzzyDictByPage这个函数的调用折,看到事务层的实现类DicServiceImpl调用了他。

这里就不用去接着看谁调用他,回到这个实现方法的接口中看更直观(一般是action这个层去接收前端传来的内容,这里是controller)。已经很明显了,没有dictNname这个参数传入,那就是这是一个实体对象中的一个属性。

他的传参是一个为MyDict的对象,进入这个bean看一下。找到了dictName这处为字典名称,这就是漏洞触发的地方。另一个地方同理。

漏洞成因分析完了可能会有疑问使用拼接容易产生SQL注入,哪为什么不全部使用预编译?使用${}拼接是有一些有优点的,他可以实现一些动态的功能,比如指定表名,列名,排序字段等等。而在某一些场景下还真不能使用#{}去进行预编译。举个栗子:

  1. 模糊查询 like

就是上面发现的地方,拿另外一个sql语句来看:

select * from users where name like '%#{name}%'

这时候使用#号会直接报错,而经验不足的新手程序员就直接改成%号,这样如果没有对用户输入再有额外的过滤转义那势必产生SQL注入,而正确写法应该是这样的:

select * from users where name like contact('%', #{name}, '%')
  1. in之后有多个参数

in之后多个id查询时使用# 同样会报错,就比如:

select * from users where id in (#{ids})

正确用法应该是使用foreach标签,如下:

select * from users where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
  1. order by

使用#{}来动态拼接order by的字段或方向,可能会导致SQL注入,比如:

@Select("select * from user order by #{column} #{direction}")
List<User> selectUsers(@Param("column") String column, @Param("direction") String direction);

修改方案:使用${}。

@Select("select * from user order by ${column} ${direction}")
List<User> selectUsers(@Param("column") String column, @Param("direction") String direction);

或者也可以使用orderby方法来构建动态排序。

SelectStatementProvider selectStatement = select(user.allColumns())
.from(user)
.orderBy(sortColumn(sortSpecification(column, direction)))
.build()
.render(RenderingStrategies.MYBATIS3);

XSS

一般来说一个项目中都是由一个统一的工具类或者函数来过滤转义来自用户的传参。所以在idea中按两下shift搜索所有的文本内容,可以看到根本没有XSS相关过滤器(Filter)或拦截器(Interceptor)。这些关键词都出现在前端代码中:

在前端代码中可以发现使用了Thymeleaf模板引擎和Layui框架,这里有个知识点就是它里面的th:text属性会将文本内容作为纯文本处理,也就是说,它会对HTML标签进行转义,从而避免XSS攻击,th:utext属性则会将文本内容作为未转义的HTML处理,也就是说,它会保留HTML标签,并将其渲染为HTML元素。因此全局搜索一下,发现并没有因为使用th:utext而产生的xss。

但是还有一个属性——th:value,来到resources/templates/system/role/role-edit.html这里使用了th:value属性来设置输入框的值,而th:value属性不会对HTML标签进行转义,恶意输入也会被浏览器执行,导致产生XSS。

某RBAC管理系统审计的更多相关文章

  1. 开源干货!!!.NET Core + JWT令牌认证 + Vue.js(iview-admin) 通用动态权限(RBAC)管理系统框架[DncZeus]开源啦!!!

    DncZeus 前言 关于 DncZeus DncZeus = Dnc + Zeus "Dnc"--.Net Core 的缩写: "Zeus"--中文译为宙斯, ...

  2. 基于RBAC模型的通用企业权限管理系统

    1. 为什么我们需要基于RBAC模型的通用企业权限管理系统 管理信息系统是一个复杂的人机交互系统,其中每个具体环节都可能受到安全威胁.构建强健的权限管理系统,保证管理信息系统的安全性是十分重要的.权限 ...

  3. ABP module-zero +AdminLTE+Bootstrap Table+jQuery权限管理系统第十三节--RBAC模式及ABP权限管理(附送福利)

    ABP+AdminLTE+Bootstrap Table权限管理系统一期 Github:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate- ...

  4. RBAC权限管理系统

    RBAC--基于角色的权限管理系统 优势: 1. 简化了用户和权限的关系 2. 易扩展,易于维护 3. RBAC不用给用户单个分配权限,只用指向对应的角色就会有对应的权限,而且分配权限和收回权限都很方 ...

  5. 这些用来审计 Kubernetes RBAC 策略的方法你都见过吗?

    原文链接:这些用来审计 Kubernetes RBAC 策略的方法你都见过吗? 认证与授权对任何安全系统来说都至关重要,Kubernetes 也不例外.即使我们不是安全工作人员,也需要了解我们的 Ku ...

  6. 基于thinkphp3.2.3开发的CMS内容管理系统(二)- Rbac用户权限

    基于thinkphp3.2.3开发的CMS内容管理系统 thinkphp版本:3.2.3 功能: --分类栏目管理 --文章管理 --商品管理 --用户管理 --角色管理 --权限管理 --友情链接管 ...

  7. Spring Cloud实战: 基于Spring Cloud Gateway + vue-element-admin 实现的RBAC权限管理系统,实现网关对RESTful接口方法权限和自定义Vue指令对按钮权限的细粒度控制

    一. 前言 信我的哈,明天过年. 这应该是农历年前的关于开源项目 的最后一篇文章了. 有来商城 是基于 Spring Cloud OAuth2 + Spring Cloud Gateway + JWT ...

  8. yii2的权限管理系统RBAC简单介绍

    这里有几个概念 权限: 指用户是否可以执行哪些操作,如:编辑.发布.查看回帖 角色 比如:VIP用户组, 高级会员组,中级会员组,初级会员组 VIP用户组:发帖.回帖.删帖.浏览权限 高级会员组:发帖 ...

  9. 利用RBAC模型实现一个通用的权限管理系统

    本文主要描述一个通用的权限系统实现思路与过程.也是对此次制作权限管理模块的总结. 制作此系统的初衷是为了让这个权限系统得以“通用”.就是生产一个web系统通过调用这个权限系统(生成的dll文件), 就 ...

  10. 权限管理系统(五):RBAC新解,基于资源的权限管理

    本文讨论以角色概念进行的权限管理策略及主要以基于角色的机制进行权限管理是远远不够的.同时我将讨论一种我认为更好的权限管理方式. 1.什么是角色 当说到程序的权限管理时,人们往往想到角色这一概念.角色是 ...

随机推荐

  1. 【WPF】后台代码实现绑定ComboBox的SelectedItem功能

    WPF 开发程序目前最好的用的设计模式为MVVM模式,实现了前后端的分离,前端页面的更改不需要后台代码逻辑发生变化,同理,后台逻辑发生变化时基本上也不需要修改前台的页面布局等信息. 由于某些原因,可能 ...

  2. RCU的简单认识

    RCU RUC是什么? RCU(Read-Copy-Update)是一种用于并发编程的技术,旨在提供高效且无锁(lock-free)的读操作,同时保证数据一致性和并发性. 也就是说他并不需要锁的机制来 ...

  3. 5.go语言函数提纲

    1 本篇前瞻 前端时间的繁忙,未曾更新go语言系列.由于函数非常重要,为此将本篇往前提一提,另外补充一些有关go新版本前面遗漏的部分. 需要恭喜你的事情是本篇学完,go语言中基础部分已经学完一半,这意 ...

  4. c语言代码练习9

    \\判断1000-2000之间的闰年有哪些,有几个 #define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h> int main(){ //判断 ...

  5. Go函数介绍与一等公民

    Go函数介绍与一等公民 函数对应的英文单词是 Function,Function 这个单词原本是功能.职责的意思.编程语言使用 Function 这个单词,表示将一个大问题分解后而形成的.若干具有特定 ...

  6. 快速展示原型之Minimal API开发

    Minimal API官网地址: https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/minimal-apis/security?vi ...

  7. docker的疑难杂症

    本篇博客主要是解决docker使用中遇到的常见报错,为了下次能够快速解决同样的问题,专门记录一下,文章会持续更新. 容器名称被占用. Error response from daemon: Confl ...

  8. 堆优化模拟退火(List-Based Simulated Annealing|List-Based SA|LBSA|模拟退火) 算法

    图炸了的话请多刷新几次(upd:8.9) 堆优化模拟退火(List-Based Simulated Annealing) 算法 引入 堆优化模拟退火(List-Based Simulated Anne ...

  9. Wonder8.promotion营销规则引擎,轻松搞掂千变万化的营销玩法

    超过10年没有更新过内容了,不知道现在园子的氛围这类文章还适不适合放首页 想着整点内容,也是支持园子! 旺德發.营销 引擎 概述 为了广泛支持营销活动的复杂与灵活,Wonder8.promotion( ...

  10. OceanBase金融SQL、亿万级别据量优化案例(Row_number 开窗 + 分页SQL)

    最近优化了不少SQL,简单的SQL顺手搞了不好意思发出来了忽悠人,复杂很考验逻辑思维的,但是又不想分享出来(自己收藏的案例),怕被人抄袭思路. 今天遇到一条很有意思的SQL案例:  性能SQL(金融行 ...