Live2D
//

shiro反序列化漏洞解决方案

总结下来就是shiro的“记住我”的功能用到了AES加密,但是密钥是硬编码在代码里的,所以很容易拿到密钥,因为 AES 是对称加密,即加密密钥也同样是解密密钥,所以就可以通过恶意构建Cookie获取权限执行攻击命令,拿到root权限,官方解决的方案是简单的弃用了问题代码,所以建议是升级shiro版本,避免该问题,新版本到shiro 1.2.5及以上版本,但可能也不行,问题出在哪里呢,升级shiro版本后仍然存在反序列化漏洞,其原因是因为我们使用了别人的开源框架,他们在代码里会配置shiro的密钥,而关键代码可以在github上通过api search接口搜索到,从而得到一个所谓的key包,其实就是这些密钥的集合,然后用这些公开的密钥去轮流尝试,如果你用了开源的框架,而没有修改shiro的密钥,其实这就相当于你使用的shiro密钥已经泄露,这是非常危险的
明白了问题所在,解决就很简单了:
1.确定自己使用的shiro版本要高于1.2.4;
2.在代码中全局搜索 "setCipherKey(Base64.decode(" 关键字,或者"setCipherKey"方法,Base64.decode()中的字符串就是shiro的密钥,要确保该密钥的安全性,千万不要使用公开的密钥。
代码如下:
/**
     * 随机生成秘钥,参考org.apache.shiro.crypto.AbstractSymmetricCipherService#generateNewKey(int)
     *
     * @return 随机生成秘钥
     */
    @Bean
    public static byte[] generateNewKey() {

        KeyGenerator keyGenerator;

        try {
            keyGenerator = KeyGenerator.getInstance("AES");
        } catch (NoSuchAlgorithmException e) {
            String msg = "Unable to acquire AES algorithm. This is required to function.";
            throw new IllegalStateException(msg, e);
        }
        keyGenerator.init(128);
        SecretKey secretKey = keyGenerator.generateKey();
        byte[] encoded = secretKey.getEncoded();

        log.info("生成随机秘钥成功!");

        return encoded;
    }
/*
     * rememberMeManager
     * @return
     * 解决shiro反序列号漏洞
     * ranqw add
     */
    @Bean(name = " rememberMeManager")
    public CookieRememberMeManager getRememberMeManager() {
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        //生成新的密钥
        cookieRememberMeManager.setCipherKey(Base64.decode(GenerateCipherKey.generateNewKey()));
        cookieRememberMeManager.setCookie(getRememberMeCookie());
        return cookieRememberMeManager;
    }

    /**
     * cookie对象;
     *
     * @return ranqw add
     */
    public SimpleCookie getRememberMeCookie() {
        //这个参数是cookie的名称,对应前端的checkbox的name = rememberMe
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
        simpleCookie.setHttpOnly(true);
        //cookie生效时间30天,单位秒;
        simpleCookie.setMaxAge(2592000);
        return simpleCookie;
    }

@Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager() {
        DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
        // 设置realm
        dwsm.setRealm(getShiroRealm());
        // 注入缓存管理器
        dwsm.setCacheManager(getEhCacheManager());
        // 使用记住我
        dwsm.setRememberMeManager(getRememberMeManager());
        return dwsm;
    }

 

posted @ 2022-01-25 14:28  哦豁完蛋~  阅读(2043)  评论(0编辑  收藏  举报