环境搭建

<!-- <https://mvnrepository.com/artifact/org.apache.shiro/shiro-core> -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.4.1</version>
        </dependency>

<!-- <https://mvnrepository.com/artifact/org.apache.shiro/shiro-web> -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-web</artifactId>
            <version>1.4.1</version>
        </dependency>

漏洞描述

RememberMe Cookie 默认通过 AES-128-CBC 模式加密,这种加密方式容易受到Padding Oracle Attack攻击,攻击者利用有效的RememberMe Cookie作为前缀,然后精心构造 RememberMe Cookie值来实现反序列化漏洞攻击。

利用条件

Shiro < 1.4.2

Shiro的改进

找到org.apache.shiro.mgt.AbstractRememberMeManager类,在Shiro 1.2.4下,存在一个默认key,其构造方法就是将这个默认key设置为Cookie加密解密的密钥

Untitled

但在Shiro 1.4.1下,不再定义默认key,唯一不同的是通过AesCipherService.generateNewKey().getEncoded()获取key

Untitled

会发现每次调试它的密钥都会发生变化

AesCipherService cipherService = new AesCipherService();
cipherService.generateNewKey().getEncoded()

我下面就对这两段代码进行了调试

首先是AesCipherService对象的实例化,那么其父类的构造方法都会被调用,类的继承关系:

org.apache.shiro.crypto.JcaCipherService
↓
org.apache.shiro.crypto.AbstractSymmetricCipherService
↓
org.apache.shiro.crypto.DefaultBlockCipherService
↓
org.apache.shiro.crypto.AesCipherService

org.apache.shiro.crypto.JcaCipherService

初始化了算法名称,密钥大小,初始向量大小等字段信息,默认生成初始化向量

Untitled

org.apache.shiro.crypto.AbstractSymmetricCipherService