Shiro安全(四):Shiro权限绕过之Shiro-782

  • 0x00 前言
  • 0x01 前置知识
  • 0x02 漏洞环境
  • 0x03 漏洞利用
  • 0x04 漏洞原理
    • Shiro层面绕过
    • Spring层面绕过
  • 0x05 总结
  • 0x06 参考文章

0x00 前言

刚好在学shiro安全,就看了看shiro权限绕过方面的洞

0x01 前置知识

学习一下shiro的配置与使用

https://cloud.tencent.com/developer/article/1643122

0x02 漏洞环境

影响版本:shiro < 1.5.3

添加shiro配置

Shiro 中的匹配规则是通过 AntPathMatcher 来进行实现的

? 匹配一个字符
* 匹配一个或多个字符
** 匹配一个或多个目录

ps:这里的规则是 /admin/* 所以 Shiro 并不会对多个目录进行权限校验,例如:/admin/aaa/bbb 这种是不会对其进行权限校验的

添加一个controller,这个只有在认证后才能访问

0x03 漏洞利用

正常情况访问/admin/aaa,因为没有认证所以会弹回登录页

payload:/admin/Hello%252faaaa

成功绕过shiro认证,进入到controller中

0x04 漏洞原理

经过调试发现本质其实就是shiro和spring在处理url时候的规则不同导致的认证绕过

通过断点可以看到请求先经过shiro然后再进入spring分发请求到controller

Shiro层面绕过

Shiro的认证是通过新建filter来实现的,shiro首先会根据uri来获取对应的shiro-filter

跟进getRequestUri,发现uri是通过valueOrEmpty(request.getContextPath()) + “/” + valueOrEmpty(request.getServletPath()) + valueOrEmpty(request.getPathInfo())获得的,而其中

对于request.getServletPath()request.getContextPath() 以及 request.getPathInfo(),以 Tomcat 为例的中间件是会对其进行 URL 解码操作的

此时uri为//admin/Hello%2faaaa

然后再进入decodeAndCleanUriString函数进行一次解码,他这里会判断是否存在封号,如果存在就截取封号前面的,这样是为了避免http://www.xxxx.com/xxxx;jession=xxxxxx这种情况

所以总的来说在getRequestUri函数中,进行了两次url解码操作

返回到最开始的位置,可以看到requestUri为/admin/Hello/aaaa

继续往上层return,来到getChain方法,此时获取到了requestURI,下面就是匹配对应的shiro-filter了。首先获取所有shiro-filter

可以说是一个都匹配不上,最终返回null

return到上层,因为返回为null,所以进入了else,最终只返回了默认的 ApplicationFilterChain,在默认的 ApplicationFilterChain 中是没有任何权限校验

没有一个shiro-filter被匹配到,至此 Shiro 层面的权限就成功绕过了

Spring层面绕过

接下来就是要能让spring将我们的请求发送到对应的controller

熟悉 Spring 的师傅应该都知道在 Spring 中 DispatcherServlet 是负责请求派发的,即将对应的请求转发到对应的 Controller 来处理,其一个主要的操作是通过 HandlerMappings来将请求映射到处理器Handler。在处理过程中会调用 getHandler 方法来获取一个可以处理该请求的Handler(即与该请求匹配的handler,这个handler最终会调用相应controller)

HandlerMapping在这个SpringMVC体系结构中有着举足轻重的地位,充当着url和Controller之间映射关系配置的角色

http://www.51gjie.com/javaweb/921.html

继续往下debug,来到spring获取Handler的地方

在该方法中会获取所有的handlerMappings,通过调用HandlerMapping的getHandler方法来进行判断是否这个Handler可以处理当前请求

继续跟进

继续跟进来到getHandlerInternal,调用了父类getHandlerInternal,这里获取request的uri,这里也是导致绕过最重要的地方,跟进去看看

跟进resolveAndCacheLookupPath

到了spring真正获取uri的地方了

调用了getPathWithinApplication,调用了getRequestUri

注意看,这个getRequestUri与shiro中那个getRequestUri不一样,这个是调用了request.getRequestURI()

这个request.getRequestURI()是不会对uri进行解码的,以前的 shiro 使用 request.getRequestURI() 获取用户请求路径,并自行处理,此时 shiro 默认Servlet 容器(中间件)不会对路径进行 URL 解码操作,通过其注释可以看到;

但是呢后来在 1.5.2 版本的 shiro 更新中,为了修复 CVE-2020-1957 ,将 request.getRequestURI() 置换为了 valueOrEmpty(request.getContextPath()) + "/" + valueOrEmpty(request.getServletPath()) + valueOrEmpty(request.getPathInfo());而对于 request.getContextPath() 以及 request.getPathInfo(),以 Tomcat 为例的中间件是会对其进行 URL 解码操作的,此时 shiro 再进行 decodeAndCleanUriString,就相当于进行了两次的 URL 解码,而与之后的 Spring 的相关处理产生了差异。

下图也可以看到并没有对uri解码

此时再传进decodeAndCleanUriString,相当于是只进行了一次解码

回到上一层,可以看到只进行了一次解码

重新回到 getHandlerInternal 函数,可以看到 lookupPath 和 request 传入了 lookupHandlerMethod 函数中,这里的 lookupPath 其实就是获取到了我们请求对应的 uri的一次解码,接下来就可以根据lookupPath来匹配Controller的Handler了

跟进添加匹配的mapping

可以看到第一个mapping为/unauth这个,如果request能和这个mapping符合就匹配上这个mapping,显然是不符合的

跟进getMatchingMapping(判断是否符合)最终来到getMatchingCondition,进行了一系列的判断来到路由匹配

可以看一下路由/unauth,显然和request中的不匹配

所以返回null

然后一个个mapping和request匹配,最终来到/admin/{name}这个mapping

跟进getMatchingMapping

最终来到路由匹配

spring只对uri一次解码,所以说uri是/admin/Hello%2faaaa,可以和/admin/{name}匹配上

匹配成功就添加到 matches 中

上面的这些功能都是为了在所有匹配的Handler之后需要挑选一个最合适的Handler进行请求的处理,获取到合适的 Handler 之后就进行Handler的访问来处理请求

0x05 总结

总的来说就是shiro和spring对于url的处理方式不同导致的

shiro在获取uri时(为了下一步匹配shiro-filter)对其进行了两次解码

spring在获取uri时(为了下一步匹配controller)对其进行了一次解码

所以说/admin/Hello%252faaaa在shiro眼里就是/admin/Hello/aaaa,即并不会触发shiro的认证filter

而在后面的spring眼里是/admin/Hello%2faaaa,刚好匹配上了/admin/{name}这个controller,从而实现了认证绕过

0x06 参考文章

https://www.yuque.com/tianxiadamutou/zcfd4v/emcdeq

https://su18.org/post/shiro-3/#cve-2020-11989

https://cloud.tencent.com/developer/article/1643122

https://www.anquanke.com/post/id/218270#h3-7

http://www.51gjie.com/javaweb/921.html

Shiro安全(四):Shiro权限绕过之Shiro-782相关推荐

  1. shiro 方法级别细粒度权限控制_第四章:Shiro的身份认证(Authentication)——深入浅出学Shiro细粒度权限开发框架——私塾在线原创...

    nStep3:SubjectManager 接收token 以及简单地委托给内部的Authenticator 实例通过调用authenticator.authenticate(token).这通常是一 ...

  2. 将 Shiro 作为应用的权限基础

    Shiro 是 Java 世界中新近出现的权限框架,较之 JAAS 和 Spring Security,Shiro 在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势.本文介绍了 Shiro 的 ...

  3. 将 Shiro 作为应用的权限基础 三:基于注解实现的授权认证过程

    授权即访问控制,它将判断用户在应用程序中对资源是否拥有相应的访问权限. 如,判断一个用户有查看页面的权限,编辑数据的权限,拥有某一按钮的权限等等. 一.用户权限模型 为实现一个较为灵活的用户权限数据模 ...

  4. 权限验证框架Shiro

    权限验证框架Shiro: Shiro简介 什么是Shiro: shiro是一个强大易用的Java安全框架,提供了认证,授权,加密,回话管理等功能: 认证(Authentication):用户身份识别, ...

  5. shiro 方法级别细粒度权限控制_Shiro的认证和权限控制

    从类别上分,有两大类: - 认证:你是谁?–识别用户身份. - 授权:你能做什么?–限制用户使用的功能. 权限的控制级别 从控制级别(模型)上分: - URL级别-粗粒度 - 方法级别-细粒度 - 页 ...

  6. shiro 单点登录_Shiro权限管理框架(一):Shiro的基本使用

    其实关于Shiro的一些学习笔记很早就该写了,因为懒癌和拖延症晚期一直没有落实,直到今天公司的一个项目碰到了在集群环境的单点登录频繁掉线的问题,为了解决这个问题,Shiro相关的文档和教程没少翻.最后 ...

  7. 一篇搞定 SpringBoot+Mybatis+Shiro 实现多角色权限管理

    初衷:我在网上想找整合springboot+mybatis+shiro并且多角色认证的博客,发现找了好久也没有找到想到的,现在自己会了,就打算写个博客分享出去,希望能帮到你. 原创不易,请点赞支持! ...

  8. 一看就会!一篇全搞定!权限处理专家--Shiro保姆式教学,超详细!

    轻量级权限处理框架--Shiro 前言 Shiro三大对象 Subject SecurityManager Realm Authentication和Authorization Authenticat ...

  9. spring boot结合shiro实现用户-角色-权限的控制(包含用户名密码登陆和手机号验证码登陆)

    spring boot整合shiro实现权限校验 1.首先导入项目所需jar包 <parent><groupId>org.springframework.boot</gr ...

最新文章

  1. 黄金矿工-收益最大化
  2. 美国服务机器人技术路线图
  3. TF之DCGAN:基于TF利用DCGAN测试自己的数据集并进行生成过程全记录
  4. 为Eclipse plug-in(插件)创建语言包
  5. php excel 读取日期问题
  6. 软件开发需要重视对异常的处理
  7. Redis 的 8 大应用场景
  8. Java Lambda 表达式讲解
  9. GCP发布Kaniko:在非特权容器和Kubernetes中构建容器镜像的工具
  10. salt-api安装与配置
  11. 5月16日上午学习日志
  12. 计算机信息工程专业985,信息工程学院
  13. Asp.Net MVC学习总结(三)——过滤器你怎么看?
  14. 国际品牌拧紧工具的优缺点
  15. C语言 PTA 新年倒计时
  16. 基于h a d oop的海量图片存储模型 的分析和设计
  17. Mac没声音解决办法记录
  18. 阿里云大幅降低CDN价格网宿蓝汛跟不跟?
  19. [707]Apache NiFi安装及简单使用
  20. 永恒之蓝ms17_010漏洞复现

热门文章

  1. 关于移动端页面开发(微信内置浏览器)总结
  2. mac u盘只读怎么修改_如何解决Mac无法写入U盘的问题
  3. 485通讯与MODBUS的区别与联系
  4. 计算机局域网之组成结构
  5. Java设计模式之中介者模式(UML类图分析+代码详解)
  6. (死流氓)一招解决2345篡改主页问题
  7. 什么输入法对计算机英语,电脑输入法不见了,只能打英文怎么处理
  8. 为什么 Java/JDK 都快出 18 了,还有人用 1.8 呢?
  9. 2的1000次方等于多少
  10. java2的7次方怎么表示_2的十万次幂怎么求?用Java做