一、分析定位
1. 漏洞描述

在这里插入图片描述
在这里插入图片描述

目前厂商已经发布了新版本修复这个安全问题,请到厂商的主页下载: 

https://issues.apache.org/jira/browse/SHIRO-550 
https://shiro.apache.org/download.html 
2. 项目引发漏洞简述

若依/Guns管理系统使用了Apache Shiro,Shiro 提供了记住我(RememberMe)的功能,下次访问时无需再登录即可访问。系统将密钥硬编码在代码里,且在官方文档中并没有强调修改该密钥,导致框架使用者大多数都使用了默认密钥。攻击者可以构造一个恶意的对象,并且对其序列化、AES加密、base64编码后,作为cookie的rememberMe字段发送。Shiro将rememberMe进行解密并且反序列化,最终造成反序列化漏洞,进而在目标机器上执行任意命令。

检测漏洞:ShiroConfig.java 是否包含 fCq+/xW488hMTCD+cmJ3aQ==,如果是使用的默认密钥则需要修改,防止被执行命令攻击。

二、 若依系统
2.1. 版本升级

升级版本到 >=v.4.3.1(其实就是升级Shiro版本到1.7),并且重新生成一个新的秘钥替换cipherKey,保证唯一且不要泄漏。

2.2. 配置文件

若依官网做法:

# Shiro
shiro:
  cookie:
    # 设置密钥,务必保持唯一性(生成方式,直接拷贝到main运行即可)KeyGenerator keygen = KeyGenerator.getInstance("AES"); SecretKey deskey = keygen.generateKey(); System.out.println(Base64.encodeToString(deskey.getEncoded()));
    cipherKey: zSyK5Kp6PZAAjlT+eeNMlg==
2.3. 推荐做法

调用的方法随机生成最好,不然安全扫描还会有漏洞

2.4. 栗子
package com.gblfy.util;

import org.apache.shiro.codec.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.NoSuchAlgorithmException;

/**
 * 生成一个Base64唯一字符串
 *
 * @author guobin
 * @date 2020-12-06
 */
public class ShiroAESEncryption {
    private final static Logger logger = LoggerFactory.getLogger(ShiroAESEncryption.class);

    public static void main(String[] args) throws NoSuchAlgorithmException{
        // 直接拷贝到main运行即可生成一个Base64唯一字符串
        KeyGenerator keygen = KeyGenerator.getInstance("AES");
        SecretKey deskey = keygen.generateKey();
        logger.info("生成新的Base64唯一字符串秘钥: {}", Base64.encodeToString(deskey.getEncoded()));
    }
}

在这里插入图片描述

2.5. 项目场景

在具体代码调用此方法生成唯一的base64码值

三、Gus系统
3.1. shiro版本升级

升级Shiro版本到 >=1.7,在调用的地方重新生成一个新的秘钥替换ConstDb.CIPHERKEY Base64.decode(ConstDb.CIPHERKEY),保证唯一且不要泄漏。

    <properties>
        <!--全局编码设置-->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <!--全局版本统一设置-->
        <shiro.version>1.7.0</shiro.version>
    </properties>
<!--shiro依赖和缓存-->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-core</artifactId>
                <version>${shiro.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>${shiro.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-ehcache</artifactId>
                <version>${shiro.version}</version>
            </dependency>
            <dependency>
                <groupId>net.sf.ehcache</groupId>
                <artifactId>ehcache</artifactId>
                <version>${ehcache2.version}</version>
            </dependency>

在这里插入图片描述

3.2. 调用重新生成
    /**
     * rememberMe管理器, cipherKey生成见{@code Base64Test.java}
     */
    @Bean
    public CookieRememberMeManager rememberMeManager(SimpleCookie rememberMeCookie) {
        CookieRememberMeManager manager = new CookieRememberMeManager();
        String aesEncryption = ShiroAESEncryption.ShiroAESEncryption();
        manager.setCipherKey(Base64.decode(aesEncryption));
        manager.setCookie(rememberMeCookie);
        return manager;
    }

在这里插入图片描述

3.3. 生成工具类

在这里插入图片描述

package com.gblfy.util;

import org.apache.shiro.codec.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.NoSuchAlgorithmException;

/**
 * 生成一个Base64唯一字符串
 *
 * @author guobin
 * @date 2020-12-06
 */
public class ShiroAESEncryption {
    private final static Logger logger = LoggerFactory.getLogger(ShiroAESEncryption.class);

    public static void ShiroAESEncryption() {
        KeyGenerator keygen = null;
        try {
            keygen = KeyGenerator.getInstance("AES");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        SecretKey deskey = keygen.generateKey();
        logger.info("生成新的Base64唯一字符串秘钥: {}", Base64.encodeToString(deskey.getEncoded()));
    }

    public static void main(String[] args) {
        ShiroAESEncryption();
    }
}
shiro漏洞补充:

1.4
1.4.2
1.6
都存在漏洞建议升级到shiro1.7版本

Logo

快速构建 Web 应用程序

更多推荐